├── backend ├── runtime.txt ├── src │ └── chatbot │ │ ├── __init__.py │ │ ├── utils │ │ ├── __init__.py │ │ ├── prompts.py │ │ └── chat_helpers.py │ │ ├── crews │ │ └── research_crew │ │ │ ├── __init__.py │ │ │ ├── config │ │ │ ├── agents.yaml │ │ │ └── tasks.yaml │ │ │ └── research_crew.py │ │ ├── tools │ │ ├── __init__.py │ │ ├── exa_answer_tool.py │ │ └── exa_search_tool.py │ │ ├── listeners │ │ ├── __init__.py │ │ └── real_time_listener.py │ │ ├── main.py │ │ ├── auth.py │ │ └── ag_ui_server.py ├── requirements.txt ├── .gitignore ├── Pipfile ├── example.env ├── generate_secret.py ├── pyproject.toml ├── Dockerfile ├── run_server.py ├── generate_example_credentials.py ├── debug_railway.py └── ARCHITECTURE.md ├── frontend ├── example.env.local ├── src │ ├── app │ │ ├── favicon.ico │ │ ├── page.tsx │ │ ├── api │ │ │ └── chat │ │ │ │ └── route.ts │ │ ├── layout.tsx │ │ └── globals.css │ ├── contexts │ │ └── TokenContext.tsx │ └── components │ │ ├── ExecutionTracker.tsx │ │ ├── FlowStateDisplay.tsx │ │ ├── ResearchResults.tsx │ │ └── ChatInterface.tsx ├── postcss.config.mjs ├── public │ ├── vercel.svg │ ├── window.svg │ ├── file.svg │ ├── globe.svg │ └── next.svg ├── next.config.ts ├── eslint.config.mjs ├── .gitignore ├── tsconfig.json ├── package.json └── tailwind.config.ts ├── package.json ├── LICENSE └── README.md /backend/runtime.txt: -------------------------------------------------------------------------------- 1 | 3.10 -------------------------------------------------------------------------------- /backend/src/chatbot/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/src/chatbot/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/src/chatbot/crews/research_crew/__init__.py: -------------------------------------------------------------------------------- 1 | """Research crew.""" 2 | -------------------------------------------------------------------------------- /frontend/example.env.local: -------------------------------------------------------------------------------- 1 | # Backend URL for API calls 2 | NEXT_PUBLIC_BACKEND_URL=http://localhost:8000 -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Folken2/ag-ui-crewai-research/HEAD/backend/requirements.txt -------------------------------------------------------------------------------- /frontend/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Folken2/ag-ui-crewai-research/HEAD/frontend/src/app/favicon.ico -------------------------------------------------------------------------------- /frontend/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | } 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | lib/ 4 | .DS_Store 5 | .venv/ 6 | venv/ 7 | generate_production_credentials.py 8 | debug_railway.py -------------------------------------------------------------------------------- /frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/src/chatbot/tools/__init__.py: -------------------------------------------------------------------------------- 1 | from .exa_search_tool import ExaSearchTool 2 | from .exa_answer_tool import ExaAnswerTool 3 | 4 | __all__ = ["ExaSearchTool", "ExaAnswerTool"] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@copilotkit/react-core": "^1.9.1", 4 | "@copilotkit/react-ui": "^1.9.1", 5 | "@copilotkit/runtime": "^1.9.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /backend/src/chatbot/listeners/__init__.py: -------------------------------------------------------------------------------- 1 | # Import all listeners to ensure they are registered 2 | from .real_time_listener import real_time_listener 3 | 4 | # Export listeners for external access if needed 5 | __all__ = ['real_time_listener'] -------------------------------------------------------------------------------- /frontend/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | async rewrites() { 5 | return [ 6 | { 7 | source: '/api/:path*', 8 | destination: process.env.BACKEND_URL 9 | ? `${process.env.BACKEND_URL}/api/:path*` 10 | : 'http://localhost:8000/api/:path*', 11 | }, 12 | ]; 13 | }, 14 | }; 15 | 16 | export default nextConfig; 17 | -------------------------------------------------------------------------------- /backend/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | crewai = {extras = ["tools"], version = ">=0.134.0,<1.0.0"} 8 | crewai-tools = ">=0.8.0" 9 | litellm = ">=1.0.0" 10 | fastapi = ">=0.104.0" 11 | uvicorn = ">=0.24.0" 12 | pydantic = ">=2.0.0" 13 | python-multipart = ">=0.0.6" 14 | ag-ui = ">=0.1.0" 15 | 16 | [dev-packages] 17 | 18 | [requires] 19 | python_version = "3.10" -------------------------------------------------------------------------------- /frontend/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /backend/example.env: -------------------------------------------------------------------------------- 1 | # Authentication Configuration 2 | SECRET_KEY=your-jwt-key 3 | ALGORITHM=HS256 4 | ACCESS_TOKEN_EXPIRE_MINUTES= # Leave empty for permanent tokens (recommended for Railway) 5 | 6 | 7 | # OpenRouter Configuration (for LiteLLM) 8 | OPENROUTER_API_KEY=your-openrouter-api-key-here 9 | OPENROUTER_MODEL=openai/gpt-4o-mini # Available models at: www.openrouter.ai/models 10 | OPENROUTER_BASE_URL=https://openrouter.ai/api/v1 11 | 12 | # EXA Search Configuration 13 | EXA_API_KEY=your-exa-api-key-here 14 | 15 | # Serper Configuration (for Google Search) 16 | SERPER_API_KEY=your-serper-api-key-here -------------------------------------------------------------------------------- /backend/generate_secret.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Generate a secure secret key for JWT authentication 4 | Run this script to generate a new secret key for your .env file 5 | """ 6 | 7 | import os 8 | import binascii 9 | 10 | def generate_secret_key(): 11 | """Generate a secure random secret key""" 12 | return binascii.hexlify(os.urandom(32)).decode() 13 | 14 | if __name__ == "__main__": 15 | secret_key = generate_secret_key() 16 | print("Generated Secret Key:") 17 | print(f"SECRET_KEY={secret_key}") 18 | print("\nAdd this to your .env file!") 19 | print("Make sure to keep this secret and never commit it to version control.") 20 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /frontend/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { ChatInterface } from "@/components/ChatInterface"; 4 | import { useToken } from "@/contexts/TokenContext"; 5 | 6 | export default function Home() { 7 | const { isLoading } = useToken(); 8 | 9 | if (isLoading) { 10 | return ( 11 |
82 | {state?.processing ? "AI is analyzing your request..." : 83 | state?.has_new_research ? "New insights are available" : 84 | "Ready for your next question"} 85 |
86 |169 | AI is working... 170 |
171 |172 | Analyzing your request and gathering insights 173 |
174 |193 | New research results are ready for you to explore 194 |
195 |{results.summary}
64 |{citation}
167 |185 | Start a conversation to see research results and insights here 186 |
187 |{conv.input}
230 |CrewAI + AG-UI Protocol Implementation
364 |398 | A cutting-edge implementation showcasing CrewAI for 399 | orchestrated AI agents and AG-UI Protocol for 400 | real-time streaming interactions. 401 |
402 | 403 | {/* Technical Badges */} 404 |{children}
, 587 | ul: ({children}) =>{children},
598 | pre: ({children}) => {children},
599 | blockquote: ({children}) => (
600 | 601 | {children} 602 |603 | ), 604 | a: ({href, children}) => ( 605 | 611 | {children} 612 | 613 | ), 614 | // Handle tables 615 | table: ({children}) => ( 616 |
716 | This will clear your current conversation with {messages.length} messages. 717 |
718 |719 | Are you sure you want to start fresh? 720 |
721 |