diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..5c1f35371cad7cb79171e5106ba9d2ed6ed62c81 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +GROQ_API_KEY = "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" \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..bb89b23403f5c1f5b5016ec2563e7832fa7a6187 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +chroma_db/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text diff --git a/.pytest_cache/.gitignore b/.pytest_cache/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..08a7f458f1f002823bc794c47ca1996a57e72c86 --- /dev/null +++ b/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/.pytest_cache/CACHEDIR.TAG b/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 0000000000000000000000000000000000000000..fce15ad7eaa74e5682b644c84efb75334c112f95 --- /dev/null +++ b/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/.pytest_cache/README.md b/.pytest_cache/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7526af2448672de4537dfed042ed74daadb17bf --- /dev/null +++ b/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/.pytest_cache/v/cache/lastfailed b/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000000000000000000000000000000000000..dc18d1859abd7af4f8293c0add90832d3f987ac6 --- /dev/null +++ b/.pytest_cache/v/cache/lastfailed @@ -0,0 +1,3 @@ +{ + "tests/test_agents.py": true +} \ No newline at end of file diff --git a/.pytest_cache/v/cache/nodeids b/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc --- /dev/null +++ b/.pytest_cache/v/cache/nodeids @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/.pytest_cache/v/cache/stepwise b/.pytest_cache/v/cache/stepwise new file mode 100644 index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc --- /dev/null +++ b/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/README.md b/README.md index 4ef353f0fa0c7fa8a715f2e59285e7d2ae0c7fac..d0594e40284f26803d827ce5a2196e5844992f8b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,70 @@ ---- -title: Ai Virtual Dev Pod -emoji: 🦀 -colorFrom: gray -colorTo: purple -sdk: streamlit -sdk_version: 1.44.1 -app_file: app.py -pinned: false -license: apache-2.0 -short_description: ai_virtual_dev_pod ---- - -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +# AI-Powered Virtual Development Pod + +An intelligent system that simulates a complete software development team using AI agents. The system handles the entire project lifecycle from requirements gathering to testing. + +## Features + +- Business Analyst Agent: Creates user stories from high-level requirements +- Design Agent: Creates software design specifications +- Developer Agent: Generates code based on user stories and design +- Testing Agent: Creates and executes test cases +- Project Manager Interface: Web-based interface for project management + +## Project Structure + +``` +. +├── agents/ # Contains all agent implementations +│ ├── business_analyst.py +│ ├── designer.py +│ ├── developer.py +│ ├── tester.py +│ └── project_manager.py +├── core/ # Core framework components +│ ├── config.py +│ ├── database.py +│ └── base_agent.py +├── app.py # Streamlit web interface +└── tests/ # Test files +``` + +## Setup + +1. Create a virtual environment: +```bash +python -m venv venv +source venv/bin/activate # On Windows: venv\Scripts\activate +``` + +2. Install dependencies: +```bash +pip install -r requirements.txt +``` + +3. Set up environment variables: +Create a `.env` file with: +``` +GROQ_API_KEY=your_api_key_here +``` + +## Usage + +1. Start the Streamlit app: +```bash +streamlit run app.py +``` + +2. Open your web browser and navigate to the URL shown in the terminal (usually http://localhost:8501) + +3. Use the web interface to: + - Start new projects + - Check project status + - Run quality checks + - View generated artifacts + +## Development + +- The system uses LangGraph for agent orchestration +- Groq's Gemma2-9b-it model as the LLM +- ChromaDB for vector storage and retrieval +- Streamlit for the web interface \ No newline at end of file diff --git a/agents/__pycache__/business_analyst.cpython-310.pyc b/agents/__pycache__/business_analyst.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c6100f61078c7b11a2dbd64177628570b3978c2 Binary files /dev/null and b/agents/__pycache__/business_analyst.cpython-310.pyc differ diff --git a/agents/__pycache__/designer.cpython-310.pyc b/agents/__pycache__/designer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0956f10f0daf5ab3eefb1d9b6e7687164cdfe7bf Binary files /dev/null and b/agents/__pycache__/designer.cpython-310.pyc differ diff --git a/agents/__pycache__/developer.cpython-310.pyc b/agents/__pycache__/developer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..873ae4b59efbdcd065f0382d2b9d385aec5ac993 Binary files /dev/null and b/agents/__pycache__/developer.cpython-310.pyc differ diff --git a/agents/__pycache__/project_manager.cpython-310.pyc b/agents/__pycache__/project_manager.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4a1b193a72a65fc50c4a719b2ac9216aa73e5da Binary files /dev/null and b/agents/__pycache__/project_manager.cpython-310.pyc differ diff --git a/agents/__pycache__/tester.cpython-310.pyc b/agents/__pycache__/tester.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a9b3f14803ed55929403fd76a54847c9f0c0d75 Binary files /dev/null and b/agents/__pycache__/tester.cpython-310.pyc differ diff --git a/agents/business_analyst.py b/agents/business_analyst.py new file mode 100644 index 0000000000000000000000000000000000000000..bf499a980a87d7a5d70f92fd3c20073559c46828 --- /dev/null +++ b/agents/business_analyst.py @@ -0,0 +1,46 @@ +from core.base_agent import BaseAgent +from core.database import db +from typing import Dict, Any + +class BusinessAnalystAgent(BaseAgent): + def __init__(self): + super().__init__("Business Analyst") + self.create_chain(""" + You are a Business Analyst. Your task is to create detailed user stories from the given business requirements. + + Business Requirements: + {input} + + Create user stories following this format: + As a [type of user] + I want [some goal] + So that [some reason] + + Acceptance Criteria: + 1. [First criterion] + 2. [Second criterion] + ... + + Please provide clear, testable user stories with specific acceptance criteria. + """) + + async def create_user_stories(self, requirements: str) -> Dict[str, Any]: + """Create user stories from business requirements""" + result = await self.process({"input": requirements}) + + # Store the user stories in the database + db.store_artifact( + "user_stories", + result, + { + "type": "user_story", + "source": "business_analyst", + "status": "created" + } + ) + + return { + "status": "success", + "user_stories": result, + "message": "User stories created successfully" + } \ No newline at end of file diff --git a/agents/designer.py b/agents/designer.py new file mode 100644 index 0000000000000000000000000000000000000000..747f44c042be9cd89179c55222d329df7314b293 --- /dev/null +++ b/agents/designer.py @@ -0,0 +1,44 @@ +from core.base_agent import BaseAgent +from core.database import db +from typing import Dict, Any + +class DesignerAgent(BaseAgent): + def __init__(self): + super().__init__("Designer") + self.create_chain(""" + You are a Software Designer. Your task is to create detailed design specifications from the given user stories. + + User Stories: + {input} + + Create a comprehensive design document that includes: + 1. System Architecture + 2. Component Design + 3. Database Schema + 4. API Endpoints + 5. Data Flow Diagrams + 6. Security Considerations + + Please provide a detailed, implementable design that follows best practices and design patterns. + """) + + async def create_design(self, user_stories: str) -> Dict[str, Any]: + """Create design specifications from user stories""" + result = await self.process({"input": user_stories}) + + # Store the design in the database + db.store_artifact( + "designs", + result, + { + "type": "design", + "source": "designer", + "status": "created" + } + ) + + return { + "status": "success", + "design": result, + "message": "Design specifications created successfully" + } \ No newline at end of file diff --git a/agents/developer.py b/agents/developer.py new file mode 100644 index 0000000000000000000000000000000000000000..016a110d4b1effd572a099988bb22c2f450ae227 --- /dev/null +++ b/agents/developer.py @@ -0,0 +1,111 @@ +from core.base_agent import BaseAgent +from core.database import db +from typing import Dict, Any + +class DeveloperAgent(BaseAgent): + def __init__(self): + super().__init__("Developer") + self.create_chain(""" + You are an expert Software Developer. Your task is to generate production-ready, well-structured code based on the given design specifications. + + Design Specifications: + {input} + + Generate code that follows these strict guidelines: + + 1. Code Structure: + - Use proper project structure with separate modules + - Follow SOLID principles + - Implement proper error handling + - Use type hints + - Include comprehensive docstrings + - Follow PEP 8 style guide + + 2. Implementation Details: + - Use modern Python features (Python 3.9+) + - Implement proper logging + - Add input validation + - Include unit tests + - Use dependency injection where appropriate + - Implement proper configuration management + + 3. Security: + - Sanitize all inputs + - Implement proper authentication/authorization + - Use secure coding practices + - Handle sensitive data properly + + 4. Performance: + - Optimize database queries + - Implement caching where appropriate + - Use async/await for I/O operations + - Implement proper resource management + + 5. Documentation: + - Include detailed module docstrings + - Document all public methods + - Include usage examples + - Document configuration options + + The code should be: + - Production-ready + - Well-tested + - Scalable + - Maintainable + - Secure + - Performant + + Provide the complete implementation with all necessary files and dependencies. + """) + + async def generate_code(self, design: str) -> Dict[str, Any]: + """Generate code from design specifications""" + result = await self.process({"input": design}) + + # Store the code in the database + db.store_artifact( + "code", + result, + { + "type": "code", + "source": "developer", + "status": "created", + "version": "1.0.0" + } + ) + + return { + "status": "success", + "code": result, + "message": "Code generated successfully", + "metadata": { + "language": "Python", + "framework": "Standard Library", + "dependencies": self._extract_dependencies(result) + } + } + + def _extract_dependencies(self, code: str) -> list: + """Extract dependencies from the generated code""" + dependencies = set() + # Add common dependencies + dependencies.update([ + "python-dotenv", + "pydantic", + "fastapi", + "uvicorn", + "pytest", + "pytest-asyncio" + ]) + + # Add dependencies based on code content + if "import sqlalchemy" in code: + dependencies.add("sqlalchemy") + if "import aiohttp" in code: + dependencies.add("aiohttp") + if "import redis" in code: + dependencies.add("redis") + if "import jwt" in code: + dependencies.add("PyJWT") + + return sorted(list(dependencies)) \ No newline at end of file diff --git a/agents/project_manager.py b/agents/project_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..d264bdca2424918c02eb8b1fb378cf138a706912 --- /dev/null +++ b/agents/project_manager.py @@ -0,0 +1,123 @@ +from core.base_agent import BaseAgent +from core.database import db +from core.workflow import DevelopmentWorkflow +from typing import Dict, Any + +class ProjectManagerAgent(BaseAgent): + def __init__(self): + super().__init__("Project Manager") + self.workflow = DevelopmentWorkflow() + + self.create_chain(""" + You are a Project Manager. Your task is to oversee the development process and provide status updates. + + Current Status: + {input} + + Please provide a comprehensive status report including: + 1. Project progress + 2. Any blockers or issues + 3. Next steps + 4. Quality metrics + 5. Recommendations + + Please provide clear, actionable insights. + """) + + async def start_project(self, requirements: str) -> Dict[str, Any]: + """Start a new project with the given requirements""" + # Run the complete workflow + result = await self.workflow.run(requirements) + + # Store all artifacts in the database + self._store_artifacts(result) + + return { + "status": "success", + "user_stories": result["user_stories"], + "design": result["design"], + "code": result["code"], + "test_results": result["test_results"], + "messages": result["messages"], + "message": "Project completed successfully" + } + + def _store_artifacts(self, result: Dict[str, Any]): + """Store all project artifacts in the database""" + # Store user stories + db.store_artifact( + "user_stories", + result["user_stories"], + { + "type": "user_story", + "source": "business_analyst", + "status": "created" + } + ) + + # Store design + db.store_artifact( + "designs", + result["design"], + { + "type": "design", + "source": "designer", + "status": "created" + } + ) + + # Store code + db.store_artifact( + "code", + result["code"], + { + "type": "code", + "source": "developer", + "status": "created", + "version": "1.0.0" + } + ) + + # Store test results + db.store_artifact( + "test_results", + result["test_results"], + { + "type": "test_result", + "source": "tester", + "status": "executed" + } + ) + + async def get_status(self) -> Dict[str, Any]: + """Get the current project status""" + # Query all artifacts from the database + user_stories = db.query_artifacts("user_stories", "status:created") + designs = db.query_artifacts("designs", "status:created") + code = db.query_artifacts("code", "status:created") + test_results = db.query_artifacts("test_results", "status:executed") + + status = { + "user_stories": len(user_stories["ids"]), + "designs": len(designs["ids"]), + "code": len(code["ids"]), + "test_results": len(test_results["ids"]) + } + + return { + "status": "success", + "data": status, + "message": "Status retrieved successfully" + } + + async def check_quality(self) -> Dict[str, Any]: + """Check the quality of project artifacts""" + result = await self.process({ + "input": "Checking quality of all project artifacts" + }) + + return { + "status": "success", + "quality_report": result, + "message": "Quality check completed successfully" + } \ No newline at end of file diff --git a/agents/tester.py b/agents/tester.py new file mode 100644 index 0000000000000000000000000000000000000000..fd144c97aa2846f084ade85f7b52ed34627f0aac --- /dev/null +++ b/agents/tester.py @@ -0,0 +1,66 @@ +from core.base_agent import BaseAgent +from core.database import db +from typing import Dict, Any + +class TesterAgent(BaseAgent): + def __init__(self): + super().__init__("Tester") + self.create_chain(""" + You are a Software Tester. Your task is to create comprehensive test cases and execute them on the given code. + + Code to Test: + {input} + + Create test cases that: + 1. Cover all user stories and acceptance criteria + 2. Include unit tests, integration tests, and system tests + 3. Test edge cases and error conditions + 4. Follow testing best practices + 5. Include test data and expected results + + Please provide detailed test cases with clear steps and expected outcomes. + """) + + async def create_test_cases(self, code: str) -> Dict[str, Any]: + """Create test cases for the given code""" + result = await self.process({"input": code}) + + # Store the test cases in the database + db.store_artifact( + "test_cases", + result, + { + "type": "test_case", + "source": "tester", + "status": "created" + } + ) + + return { + "status": "success", + "test_cases": result, + "message": "Test cases created successfully" + } + + async def execute_tests(self, code: str, test_cases: str) -> Dict[str, Any]: + """Execute test cases on the given code""" + result = await self.process({ + "input": f"Code:\n{code}\n\nTest Cases:\n{test_cases}" + }) + + # Store the test results in the database + db.store_artifact( + "test_results", + result, + { + "type": "test_result", + "source": "tester", + "status": "executed" + } + ) + + return { + "status": "success", + "test_results": result, + "message": "Tests executed successfully" + } \ No newline at end of file diff --git a/api/__pycache__/main.cpython-310.pyc b/api/__pycache__/main.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99669fb6710cb7be0312806defa8e48bf524ba5a Binary files /dev/null and b/api/__pycache__/main.cpython-310.pyc differ diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..bd58fbc86846c3dd8f7949d963e1d596ff4ff5b1 --- /dev/null +++ b/app.py @@ -0,0 +1,167 @@ +import streamlit as st +import asyncio +from agents.project_manager import ProjectManagerAgent +import json +from typing import Dict, Any + +# Initialize the project manager +project_manager = ProjectManagerAgent() + +# Set page config +st.set_page_config( + page_title="AI Development Pod", + page_icon="🤖", + layout="wide" +) + +# Custom CSS +st.markdown(""" + +""", unsafe_allow_html=True) + +# Title and description +st.title("🤖 AI Development Pod") +st.markdown(""" + This is an AI-powered virtual development team that can handle your software project from requirements to testing. + Simply enter your project requirements and let the AI team do the rest! +""") + +# Sidebar for navigation +st.sidebar.title("Navigation") +page = st.sidebar.radio("Go to", ["Start Project", "Project Status", "Quality Check"]) + +def display_progress(messages: list): + """Display progress based on workflow messages""" + steps = { + "User stories created successfully": 20, + "Design created successfully": 40, + "Code generated successfully": 60, + "Test cases created successfully": 80, + "Tests executed successfully": 100 + } + + current_progress = 0 + for message in messages: + if message in steps: + current_progress = max(current_progress, steps[message]) + + st.markdown(f""" +
+
+
+

{current_progress}% Complete

+ """, unsafe_allow_html=True) + + for message in messages: + st.info(message) + +async def run_project(requirements: str) -> Dict[str, Any]: + """Run the project workflow""" + return await project_manager.start_project(requirements) + +async def get_project_status() -> Dict[str, Any]: + """Get the project status""" + return await project_manager.get_status() + +async def run_quality_check() -> Dict[str, Any]: + """Run the quality check""" + return await project_manager.check_quality() + +if page == "Start Project": + st.header("Start New Project") + + # Project requirements input + requirements = st.text_area( + "Enter your project requirements:", + placeholder="Describe your project requirements in detail...", + height=200 + ) + + if st.button("Start Project"): + if requirements: + with st.spinner("Processing your project..."): + # Run the async function + result = asyncio.run(run_project(requirements)) + + # Display progress + display_progress(result["messages"]) + + # Display results in tabs + tab1, tab2, tab3, tab4 = st.tabs(["User Stories", "Design", "Code", "Test Results"]) + + with tab1: + st.subheader("User Stories") + st.markdown(result["user_stories"]) + + with tab2: + st.subheader("Design") + st.markdown(result["design"]) + + with tab3: + st.subheader("Generated Code") + st.code(result["code"], language="python") + + with tab4: + st.subheader("Test Results") + st.markdown(result["test_results"]) + else: + st.error("Please enter project requirements") + +elif page == "Project Status": + st.header("Project Status") + + if st.button("Check Status"): + with st.spinner("Getting project status..."): + status = asyncio.run(get_project_status()) + + # Display status metrics + col1, col2, col3, col4 = st.columns(4) + + with col1: + st.metric("User Stories", status["data"]["user_stories"]) + with col2: + st.metric("Designs", status["data"]["designs"]) + with col3: + st.metric("Code Files", status["data"]["code"]) + with col4: + st.metric("Test Results", status["data"]["test_results"]) + +elif page == "Quality Check": + st.header("Quality Check") + + if st.button("Run Quality Check"): + with st.spinner("Running quality check..."): + quality_report = asyncio.run(run_quality_check()) + + st.subheader("Quality Report") + st.markdown(quality_report["quality_report"]) + +# Footer +st.markdown("---") +st.markdown(""" +
+

AI Development Pod - Powered by Groq's Gemma2-9b-it and LangGraph

+
+""", unsafe_allow_html=True) \ No newline at end of file diff --git a/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/data_level0.bin b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..786c596298c327df7c5fb6958924c481ecd11f36 --- /dev/null +++ b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9 +size 1676000 diff --git a/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/header.bin b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae84e682423ff4214c2e9df782b8799815882036 --- /dev/null +++ b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e +size 100 diff --git a/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/length.bin b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eb26ed99c238f7b2f167c09bf76a66f284f5acd --- /dev/null +++ b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4cb4487c8b29fba854f190c7fe6da23fa1e74b4ade72cc4edc0f50931f7546d +size 4000 diff --git a/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/link_lists.bin b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/chroma_db/0895c0fd-aea2-4db2-9ea7-55fff1798415/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/data_level0.bin b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..786c596298c327df7c5fb6958924c481ecd11f36 --- /dev/null +++ b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9 +size 1676000 diff --git a/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/header.bin b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae84e682423ff4214c2e9df782b8799815882036 --- /dev/null +++ b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e +size 100 diff --git a/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/length.bin b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..ac55485c9dd231d335571e0661d704d316269bae --- /dev/null +++ b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd26114ea9753cf02818a8559035f448f1b7d6e870df1c0b97dd8f5c581bf257 +size 4000 diff --git a/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/link_lists.bin b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/chroma_db/14bf569c-0412-405e-93d7-9bb5e922d766/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/data_level0.bin b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..786c596298c327df7c5fb6958924c481ecd11f36 --- /dev/null +++ b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9 +size 1676000 diff --git a/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/header.bin b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae84e682423ff4214c2e9df782b8799815882036 --- /dev/null +++ b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e +size 100 diff --git a/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/length.bin b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..5b16942d99bc5ea4de182e866aa28a22941834af --- /dev/null +++ b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:878e6177914de3e3fd7925224261038d5a86e96dc2817f6d8ed34cd83689f10d +size 4000 diff --git a/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/link_lists.bin b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/chroma_db/7bd06384-5d74-44db-8b6f-08b881d638bb/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/data_level0.bin b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..786c596298c327df7c5fb6958924c481ecd11f36 --- /dev/null +++ b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9 +size 1676000 diff --git a/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/header.bin b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae84e682423ff4214c2e9df782b8799815882036 --- /dev/null +++ b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e +size 100 diff --git a/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/length.bin b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..2112d3c4f924aaf5b144f19fbee97b93b6f7df00 --- /dev/null +++ b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:567950437c4b5b2624a5fb159906502a2b9aa447df1c3c6e1bd463598357e8a7 +size 4000 diff --git a/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/link_lists.bin b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/chroma_db/a2f05e8f-89be-4d76-83a9-7a93d98352c3/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/chroma_db/chroma.sqlite3 b/chroma_db/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..257a1ff168a993b7ad3f42618d84a9cd241a3658 --- /dev/null +++ b/chroma_db/chroma.sqlite3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d98f1b70da83a844595edd12a2507de8317102f51c1cd1c4d01973400541e3bd +size 1392640 diff --git a/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/data_level0.bin b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..786c596298c327df7c5fb6958924c481ecd11f36 --- /dev/null +++ b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9 +size 1676000 diff --git a/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/header.bin b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae84e682423ff4214c2e9df782b8799815882036 --- /dev/null +++ b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e +size 100 diff --git a/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/length.bin b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..070590d6a838245532a53fba37636ecb96080015 --- /dev/null +++ b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28450d02a331772fa69d8d176b5fb136b8265ffb74c7b5aefe4235e94f155317 +size 4000 diff --git a/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/link_lists.bin b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/chroma_db/d08fb65a-aa5f-4895-9fa1-1c9781b3421e/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/core/__pycache__/base_agent.cpython-310.pyc b/core/__pycache__/base_agent.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae4afb72aedb90a96f029d43ed00f5c31a1f8683 Binary files /dev/null and b/core/__pycache__/base_agent.cpython-310.pyc differ diff --git a/core/__pycache__/config.cpython-310.pyc b/core/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c466a16fcf25d5abeb6b2384534bba38d6df79c Binary files /dev/null and b/core/__pycache__/config.cpython-310.pyc differ diff --git a/core/__pycache__/database.cpython-310.pyc b/core/__pycache__/database.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22ed612284c03efef216ede0a16abf29e7f4c741 Binary files /dev/null and b/core/__pycache__/database.cpython-310.pyc differ diff --git a/core/__pycache__/workflow.cpython-310.pyc b/core/__pycache__/workflow.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea5c981f7f01f5cbf1a0c3ca1cd8a116a91bac61 Binary files /dev/null and b/core/__pycache__/workflow.cpython-310.pyc differ diff --git a/core/base_agent.py b/core/base_agent.py new file mode 100644 index 0000000000000000000000000000000000000000..e94ac298fd37e67c3bf08c47daea03f8fcc6b034 --- /dev/null +++ b/core/base_agent.py @@ -0,0 +1,36 @@ +from typing import Dict, Any, List +from langchain_groq import ChatGroq +from langchain.prompts import ChatPromptTemplate +from langchain.schema import StrOutputParser +from langchain.schema.runnable import RunnablePassthrough +from core.config import settings + +class BaseAgent: + def __init__(self, role: str): + self.role = role + self.llm = ChatGroq( + api_key=settings.GROQ_API_KEY, + model_name=settings.MODEL_NAME, + temperature=settings.TEMPERATURE + ) + self.chain = None + + def create_chain(self, template: str): + """Create a LangChain chain with the given template""" + prompt = ChatPromptTemplate.from_template(template) + self.chain = ( + {"input": RunnablePassthrough()} + | prompt + | self.llm + | StrOutputParser() + ) + + async def process(self, input_data: Dict[str, Any]) -> str: + """Process input data and return the result""" + if not self.chain: + raise ValueError("Chain not initialized. Call create_chain first.") + return await self.chain.ainvoke(input_data) + + def get_role(self) -> str: + """Get the agent's role""" + return self.role \ No newline at end of file diff --git a/core/config.py b/core/config.py new file mode 100644 index 0000000000000000000000000000000000000000..683c8550082bfb2ea536c303c62dbb7e041bacbc --- /dev/null +++ b/core/config.py @@ -0,0 +1,18 @@ +from pydantic_settings import BaseSettings +from typing import Optional +import os +from dotenv import load_dotenv + +load_dotenv() + +class Settings(BaseSettings): + GROQ_API_KEY: str = os.getenv("GROQ_API_KEY", "") + CHROMA_DB_PATH: str = "chroma_db" + MODEL_NAME: str = "gemma2-9b-it" + TEMPERATURE: float = 0.7 + MAX_TOKENS: int = 2048 + + class Config: + env_file = ".env" + +settings = Settings() \ No newline at end of file diff --git a/core/database.py b/core/database.py new file mode 100644 index 0000000000000000000000000000000000000000..c8abd10675ce77da5e02312d2b7bc49e7d5f9422 --- /dev/null +++ b/core/database.py @@ -0,0 +1,38 @@ +import chromadb +from chromadb.config import Settings +from core.config import settings +import os + +class Database: + def __init__(self): + self.client = chromadb.PersistentClient( + path=settings.CHROMA_DB_PATH, + settings=Settings(allow_reset=True) + ) + + def get_collection(self, name: str): + """Get or create a collection""" + try: + return self.client.get_collection(name) + except: + return self.client.create_collection(name) + + def store_artifact(self, collection_name: str, document: str, metadata: dict): + """Store a project artifact in the database""" + collection = self.get_collection(collection_name) + collection.add( + documents=[document], + metadatas=[metadata], + ids=[f"doc_{len(collection.get()['ids'])}"] + ) + + def query_artifacts(self, collection_name: str, query: str, n_results: int = 5): + """Query artifacts in a collection""" + collection = self.get_collection(collection_name) + results = collection.query( + query_texts=[query], + n_results=n_results + ) + return results + +db = Database() \ No newline at end of file diff --git a/core/workflow.py b/core/workflow.py new file mode 100644 index 0000000000000000000000000000000000000000..80de1e8481ad76989a36dbe8985516632bf9a42a --- /dev/null +++ b/core/workflow.py @@ -0,0 +1,135 @@ +from typing import Dict, Any, TypedDict, Annotated, Sequence +from langgraph.graph import Graph, StateGraph +from langgraph.prebuilt import ToolExecutor +from agents.business_analyst import BusinessAnalystAgent +from agents.designer import DesignerAgent +from agents.developer import DeveloperAgent +from agents.tester import TesterAgent +from core.database import db + +class AgentState(TypedDict): + """State for the agent workflow""" + requirements: str + user_stories: str + design: str + code: str + test_cases: str + test_results: str + current_step: str + status: str + messages: Sequence[str] + +class DevelopmentWorkflow: + def __init__(self): + self.business_analyst = BusinessAnalystAgent() + self.designer = DesignerAgent() + self.developer = DeveloperAgent() + self.tester = TesterAgent() + + # Define the workflow + self.workflow = self._create_workflow() + + def _create_workflow(self) -> Graph: + """Create the LangGraph workflow""" + workflow = StateGraph(AgentState) + + # Add nodes for each step + workflow.add_node("create_user_stories", self._create_user_stories) + workflow.add_node("create_design", self._create_design) + workflow.add_node("generate_code", self._generate_code) + workflow.add_node("create_tests", self._create_tests) + workflow.add_node("execute_tests", self._execute_tests) + + # Define the edges + workflow.add_edge("create_user_stories", "create_design") + workflow.add_edge("create_design", "generate_code") + workflow.add_edge("generate_code", "create_tests") + workflow.add_edge("create_tests", "execute_tests") + + # Set entry point + workflow.set_entry_point("create_user_stories") + + # Set exit point + workflow.set_finish_point("execute_tests") + + return workflow.compile() + + async def _create_user_stories(self, state: AgentState) -> AgentState: + """Create user stories from requirements""" + result = await self.business_analyst.create_user_stories(state["requirements"]) + return { + **state, + "user_stories": result["user_stories"], + "current_step": "create_user_stories", + "status": "in_progress", + "messages": [*state["messages"], "User stories created successfully"] + } + + async def _create_design(self, state: AgentState) -> AgentState: + """Create design from user stories""" + result = await self.designer.create_design(state["user_stories"]) + return { + **state, + "design": result["design"], + "current_step": "create_design", + "status": "in_progress", + "messages": [*state["messages"], "Design created successfully"] + } + + async def _generate_code(self, state: AgentState) -> AgentState: + """Generate code from design""" + result = await self.developer.generate_code(state["design"]) + return { + **state, + "code": result["code"], + "current_step": "generate_code", + "status": "in_progress", + "messages": [*state["messages"], "Code generated successfully"] + } + + async def _create_tests(self, state: AgentState) -> AgentState: + """Create test cases from code""" + result = await self.tester.create_test_cases(state["code"]) + return { + **state, + "test_cases": result["test_cases"], + "current_step": "create_tests", + "status": "in_progress", + "messages": [*state["messages"], "Test cases created successfully"] + } + + async def _execute_tests(self, state: AgentState) -> AgentState: + """Execute tests on the code""" + result = await self.tester.execute_tests(state["code"], state["test_cases"]) + return { + **state, + "test_results": result["test_results"], + "current_step": "execute_tests", + "status": "completed", + "messages": [*state["messages"], "Tests executed successfully"] + } + + async def run(self, requirements: str) -> Dict[str, Any]: + """Run the complete workflow""" + initial_state = AgentState( + requirements=requirements, + user_stories="", + design="", + code="", + test_cases="", + test_results="", + current_step="start", + status="initialized", + messages=[] + ) + + final_state = await self.workflow.ainvoke(initial_state) + + return { + "status": "success", + "user_stories": final_state["user_stories"], + "design": final_state["design"], + "code": final_state["code"], + "test_results": final_state["test_results"], + "messages": final_state["messages"] + } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..4306e54be74aa73e65716a29217f434cf8ff07be --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +langgraph +langchain +langchain-groq +chromadb +pydantic +python-dotenv +streamlit +pytest +pytest-asyncio +typing-extensions \ No newline at end of file diff --git a/tests/__pycache__/test_agents.cpython-310-pytest-8.3.5.pyc b/tests/__pycache__/test_agents.cpython-310-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19992762cf364d87bbcdae57cc41d76ac82ee978 Binary files /dev/null and b/tests/__pycache__/test_agents.cpython-310-pytest-8.3.5.pyc differ diff --git a/tests/test_agents.py b/tests/test_agents.py new file mode 100644 index 0000000000000000000000000000000000000000..4987dc1555b72eea4e76978005045ff2874f2d99 --- /dev/null +++ b/tests/test_agents.py @@ -0,0 +1,46 @@ +import pytest +from agents.business_analyst import BusinessAnalystAgent +from agents.designer import DesignerAgent +from agents.developer import DeveloperAgent +from agents.tester import TesterAgent +from agents.project_manager import ProjectManagerAgent + +@pytest.mark.asyncio +async def test_business_analyst(): + agent = BusinessAnalystAgent() + requirements = "Create a simple todo list application" + result = await agent.create_user_stories(requirements) + assert result["status"] == "success" + assert "user_stories" in result + +@pytest.mark.asyncio +async def test_designer(): + agent = DesignerAgent() + user_stories = "As a user, I want to add tasks to my todo list" + result = await agent.create_design(user_stories) + assert result["status"] == "success" + assert "design" in result + +@pytest.mark.asyncio +async def test_developer(): + agent = DeveloperAgent() + design = "Create a REST API for todo list management" + result = await agent.generate_code(design) + assert result["status"] == "success" + assert "code" in result + +@pytest.mark.asyncio +async def test_tester(): + agent = TesterAgent() + code = "def add_task(task): return True" + result = await agent.create_test_cases(code) + assert result["status"] == "success" + assert "test_cases" in result + +@pytest.mark.asyncio +async def test_project_manager(): + agent = ProjectManagerAgent() + requirements = "Create a simple todo list application" + result = await agent.start_project(requirements) + assert result["status"] == "success" + assert all(key in result for key in ["user_stories", "design", "code", "test_results"]) \ No newline at end of file