nananie143 commited on
Commit
a74a84f
·
1 Parent(s): 0805b52

Enhanced app creator with autonomous file creation, project building, and download capabilities

Browse files
Files changed (1) hide show
  1. app.py +892 -119
app.py CHANGED
@@ -7,6 +7,21 @@ from langchain.prompts import PromptTemplate
7
  import json
8
  import subprocess
9
  import logging
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  # Configure logging
12
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
@@ -14,173 +29,931 @@ logger = logging.getLogger(__name__)
14
 
15
  # Load the LLM and tokenizer
16
  MODEL_NAME = "unit-mesh/autodev-coder-deepseek-6.7b-finetunes"
17
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
18
- model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, torch_dtype=torch.float16, device_map="auto")
19
-
20
- # Create a Hugging Face pipeline
21
- hf_pipeline = pipeline(
22
- "text-generation",
23
- model=model,
24
- tokenizer=tokenizer,
25
- max_length=500,
26
- temperature=0.7,
27
- )
28
 
29
- # Wrap the pipeline in a LangChain LLM
30
- llm = HuggingFacePipeline(pipeline=hf_pipeline)
31
-
32
- # Define tools for the agents
33
- tools = [
34
- Tool(
35
- name="Code Formatter",
36
- func=lambda x: subprocess.run(["black", "-"], input=x.encode(), capture_output=True).stdout.decode(),
37
- description="Formats code using Black.",
38
- ),
39
- Tool(
40
- name="API Generator",
41
- func=lambda x: json.dumps({"endpoints": {"example": "POST - Example endpoint."}}),
42
- description="Generates API details from code.",
43
- ),
44
- Tool(
45
- name="Task Decomposer",
46
- func=lambda x: json.dumps({"tasks": ["Design UI", "Develop Backend", "Test App", "Deploy App"]}),
47
- description="Breaks down app requirements into smaller tasks.",
48
- ),
49
- ]
50
-
51
- # Define prompt templates
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  ui_designer_prompt = PromptTemplate(
53
  input_variables=["input"],
54
- template="You are a UI Designer. Your task is: {input}",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  )
56
 
57
  backend_developer_prompt = PromptTemplate(
58
  input_variables=["input"],
59
- template="You are a Backend Developer. Your task is: {input}",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  )
61
 
62
  qa_engineer_prompt = PromptTemplate(
63
  input_variables=["input"],
64
- template="You are a QA Engineer. Your task is: {input}",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  )
66
 
67
  devops_engineer_prompt = PromptTemplate(
68
  input_variables=["input"],
69
- template="You are a DevOps Engineer. Your task is: {input}",
70
- )
71
 
72
- # Initialize agents
73
- ui_designer_agent = initialize_agent(
74
- tools=tools,
75
- llm=llm,
76
- agent="zero-shot-react-description",
77
- verbose=True,
78
- )
79
 
80
- backend_developer_agent = initialize_agent(
81
- tools=tools,
82
- llm=llm,
83
- agent="zero-shot-react-description",
84
- verbose=True,
 
 
85
  )
86
 
87
- qa_engineer_agent = initialize_agent(
88
- tools=tools,
89
- llm=llm,
90
- agent="zero-shot-react-description",
91
- verbose=True,
92
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
- devops_engineer_agent = initialize_agent(
95
- tools=tools,
96
- llm=llm,
97
- agent="zero-shot-react-description",
98
- verbose=True,
99
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- # Multi-Agent Workflow
102
- def multi_agent_workflow(requirements: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  """
104
- Execute a multi-agent workflow to generate a complex app.
105
  Args:
106
  requirements (str): App requirements.
107
  Returns:
108
  str: Generated app code and API details.
109
  """
110
  try:
111
- # Step 1: Task Decomposition
112
- task_decomposition = ui_designer_agent.run(
113
- f"Break down the following app requirements into smaller tasks: {requirements}"
114
- )
115
- tasks = json.loads(task_decomposition)["tasks"]
116
- logger.info(f"Tasks: {tasks}")
117
-
118
- # Step 2: Code Generation
119
- ui_code = ui_designer_agent.run(f"Generate the UI code for: {tasks[0]}")
120
- backend_code = backend_developer_agent.run(f"Generate the backend code for: {tasks[1]}")
121
- logger.info(f"UI Code: {ui_code}")
122
- logger.info(f"Backend Code: {backend_code}")
123
-
124
- # Step 3: Code Formatting
125
- formatted_ui_code = ui_designer_agent.run(f"Format the following code: {ui_code}")
126
- formatted_backend_code = backend_developer_agent.run(f"Format the following code: {backend_code}")
127
- logger.info(f"Formatted UI Code: {formatted_ui_code}")
128
- logger.info(f"Formatted Backend Code: {formatted_backend_code}")
129
-
130
- # Step 4: Integration
131
- combined_code = f"{formatted_ui_code}\n\n{formatted_backend_code}"
132
- logger.info(f"Combined Code: {combined_code}")
133
-
134
- # Step 5: Testing
135
- test_results = qa_engineer_agent.run(f"Test the following app: {combined_code}")
136
- logger.info(f"Test Results: {test_results}")
137
-
138
- # Step 6: Deployment
139
- deployment_status = devops_engineer_agent.run(f"Deploy the following app: {combined_code}")
140
- logger.info(f"Deployment Status: {deployment_status}")
141
-
142
- # Step 7: API Documentation
143
- api_details = backend_developer_agent.run(f"Generate API details for: {combined_code}")
144
- logger.info(f"API Details: {api_details}")
145
-
146
- # Return the results
147
  return f"""
148
- Generated App Code:
149
- {combined_code}
150
 
151
- Test Results:
152
- {test_results}
 
 
153
 
154
- Deployment Status:
155
- {deployment_status}
156
 
157
- API Details:
158
- {api_details}
 
 
 
 
 
 
 
 
 
 
159
  """
160
  except Exception as e:
161
- logger.error(f"Workflow failed: {str(e)}")
162
- return f"Workflow failed: {str(e)}"
 
 
 
 
163
 
164
- # Gradio Interface
165
  def app_generator(requirements: str):
166
  """
167
- Generate an app based on the provided requirements.
168
  Args:
169
  requirements (str): App requirements.
170
  Returns:
171
  str: Generated app code and API details.
172
  """
173
- return multi_agent_workflow(requirements)
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  # Gradio UI
176
  with gr.Blocks() as ui:
177
  gr.Markdown("# Autonomous App Generator with LangChain Agents")
 
 
 
 
 
 
 
 
178
  with gr.Row():
179
- requirements_input = gr.Textbox(label="App Requirements", placeholder="Describe the app you want to build...")
 
 
 
 
180
  generate_button = gr.Button("Generate App")
181
- output = gr.Textbox(label="Generated App Code and API Details", lines=20)
182
- generate_button.click(app_generator, inputs=requirements_input, outputs=output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
  # Run the Gradio app
185
  if __name__ == "__main__":
186
- ui.launch()
 
 
 
 
7
  import json
8
  import subprocess
9
  import logging
10
+ import asyncio
11
+ from typing import Dict, List, Optional
12
+ from dataclasses import dataclass
13
+ from enum import Enum
14
+ import networkx as nx
15
+ from pathlib import Path
16
+ from datetime import datetime
17
+ from typing import Set, Union, Any
18
+ import hashlib
19
+ import os
20
+ import json
21
+ from dataclasses import asdict, field
22
+ import shutil
23
+ import tempfile
24
+ from zipfile import ZipFile
25
 
26
  # Configure logging
27
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
 
29
 
30
  # Load the LLM and tokenizer
31
  MODEL_NAME = "unit-mesh/autodev-coder-deepseek-6.7b-finetunes"
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ def load_model():
34
+ try:
35
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
36
+ # Check available device and memory
37
+ if torch.cuda.is_available():
38
+ device = "cuda"
39
+ # Get available GPU memory
40
+ gpu_memory = torch.cuda.get_device_properties(0).total_memory / 1024**3 # Convert to GB
41
+ if gpu_memory < 8: # If less than 8GB available
42
+ logger.warning("Limited GPU memory available. Using CPU instead.")
43
+ device = "cpu"
44
+ else:
45
+ device = "cpu"
46
+ logger.info("No GPU detected. Using CPU.")
47
+
48
+ model = AutoModelForCausalLM.from_pretrained(
49
+ MODEL_NAME,
50
+ torch_dtype=torch.float16 if device == "cuda" else torch.float32,
51
+ device_map="auto" if device == "cuda" else None,
52
+ low_cpu_mem_usage=True
53
+ )
54
+ return tokenizer, model
55
+ except Exception as e:
56
+ logger.error(f"Failed to load model: {str(e)}")
57
+ raise RuntimeError(f"Model initialization failed: {str(e)}")
58
+
59
+ # Initialize models lazily
60
+ tokenizer = None
61
+ model = None
62
+ hf_pipeline = None
63
+ llm = None
64
+
65
+ def get_llm():
66
+ global tokenizer, model, hf_pipeline, llm
67
+ if llm is None:
68
+ tokenizer, model = load_model()
69
+ hf_pipeline = pipeline(
70
+ "text-generation",
71
+ model=model,
72
+ tokenizer=tokenizer,
73
+ max_length=500,
74
+ temperature=0.7,
75
+ )
76
+ llm = HuggingFacePipeline(pipeline=hf_pipeline)
77
+ return llm
78
+
79
+ # Lazy initialization of agents
80
+ def get_agent(agent_type):
81
+ llm = get_llm()
82
+ return initialize_agent(
83
+ tools=[
84
+ Tool(
85
+ name="Code Formatter",
86
+ func=lambda x: subprocess.run(["black", "-"], input=x.encode(), capture_output=True).stdout.decode(),
87
+ description="Formats code using Black.",
88
+ ),
89
+ Tool(
90
+ name="API Generator",
91
+ func=lambda x: json.dumps({"endpoints": {"example": "POST - Example endpoint."}}),
92
+ description="Generates API details from code.",
93
+ ),
94
+ Tool(
95
+ name="Task Decomposer",
96
+ func=lambda x: json.dumps({"tasks": ["Design UI", "Develop Backend", "Test App", "Deploy App"]}),
97
+ description="Breaks down app requirements into smaller tasks.",
98
+ ),
99
+ ],
100
+ llm=llm,
101
+ agent="zero-shot-react-description",
102
+ verbose=True,
103
+ )
104
+
105
+ # Enhanced prompt templates with more specific instructions
106
  ui_designer_prompt = PromptTemplate(
107
  input_variables=["input"],
108
+ template="""You are an expert UI Designer specializing in modern, responsive web applications.
109
+ Task: {input}
110
+
111
+ Focus on:
112
+ 1. Clean, intuitive user interface
113
+ 2. Responsive design principles
114
+ 3. Modern UI components
115
+ 4. Accessibility standards
116
+ 5. Cross-browser compatibility
117
+
118
+ Generate code using:
119
+ - HTML5 semantic elements
120
+ - Modern CSS (Flexbox/Grid)
121
+ - React/Vue.js best practices
122
+ - Material UI or Tailwind CSS
123
+
124
+ Provide detailed component structure and styling."""
125
  )
126
 
127
  backend_developer_prompt = PromptTemplate(
128
  input_variables=["input"],
129
+ template="""You are an expert Backend Developer specializing in scalable applications.
130
+ Task: {input}
131
+
132
+ Focus on:
133
+ 1. RESTful API design
134
+ 2. Database schema optimization
135
+ 3. Security best practices
136
+ 4. Error handling
137
+ 5. Performance optimization
138
+
139
+ Include:
140
+ - API endpoint definitions
141
+ - Database models
142
+ - Authentication/Authorization
143
+ - Input validation
144
+ - Error handling middleware
145
+ - Rate limiting
146
+ - Logging
147
+
148
+ Use modern backend frameworks (FastAPI/Django/Express)."""
149
  )
150
 
151
  qa_engineer_prompt = PromptTemplate(
152
  input_variables=["input"],
153
+ template="""You are an expert QA Engineer focusing on comprehensive testing.
154
+ Task: {input}
155
+
156
+ Implement:
157
+ 1. Unit tests
158
+ 2. Integration tests
159
+ 3. API endpoint tests
160
+ 4. UI component tests
161
+ 5. Performance tests
162
+
163
+ Include:
164
+ - Test cases for edge cases
165
+ - Input validation tests
166
+ - Error handling tests
167
+ - Load testing scenarios
168
+ - Security testing checks"""
169
  )
170
 
171
  devops_engineer_prompt = PromptTemplate(
172
  input_variables=["input"],
173
+ template="""You are an expert DevOps Engineer specializing in modern deployment practices.
174
+ Task: {input}
175
 
176
+ Provide:
177
+ 1. Dockerfile configuration
178
+ 2. Docker Compose setup
179
+ 3. CI/CD pipeline configuration
180
+ 4. Environment configuration
181
+ 5. Monitoring setup
 
182
 
183
+ Include:
184
+ - Development/Production configs
185
+ - Environment variables
186
+ - Health checks
187
+ - Logging setup
188
+ - Monitoring integration
189
+ - Backup strategies"""
190
  )
191
 
192
+ def generate_project_structure(app_name, features):
193
+ """Generate a complete project structure based on features."""
194
+ return f"""
195
+ {app_name}/
196
+ ├── frontend/
197
+ │ ├── src/
198
+ │ │ ├── components/
199
+ │ │ ├── pages/
200
+ │ │ ├── hooks/
201
+ │ │ ├── utils/
202
+ │ │ └── styles/
203
+ │ ├── package.json
204
+ │ └── README.md
205
+ ├── backend/
206
+ │ ├── src/
207
+ │ │ ├── routes/
208
+ │ │ ├── controllers/
209
+ │ │ ├── models/
210
+ │ │ ├── middleware/
211
+ │ │ └── utils/
212
+ │ ├── requirements.txt
213
+ │ └── README.md
214
+ ├── tests/
215
+ │ ├── unit/
216
+ │ ├── integration/
217
+ │ └── e2e/
218
+ ├── docs/
219
+ │ ├── API.md
220
+ │ ├── SETUP.md
221
+ │ └── DEPLOYMENT.md
222
+ ├── docker-compose.yml
223
+ ├── .env.example
224
+ └── README.md
225
+ """
226
 
227
+ def generate_documentation(app_name, features, api_details):
228
+ """Generate comprehensive documentation."""
229
+ return f"""
230
+ # {app_name}
231
+
232
+ ## Overview
233
+ A modern web application with the following features:
234
+ {features}
235
+
236
+ ## Quick Start
237
+ ```bash
238
+ # Clone the repository
239
+ git clone <repository-url>
240
+
241
+ # Install dependencies
242
+ cd {app_name}
243
+ # Frontend
244
+ cd frontend && npm install
245
+ # Backend
246
+ cd ../backend && pip install -r requirements.txt
247
+
248
+ # Run the application
249
+ docker-compose up
250
+ ```
251
+
252
+ ## API Documentation
253
+ {api_details}
254
+
255
+ ## Development
256
+ - Frontend: React.js with TypeScript
257
+ - Backend: Python with FastAPI
258
+ - Database: PostgreSQL
259
+ - Cache: Redis
260
+ - Testing: Jest, Pytest
261
+
262
+ ## Deployment
263
+ Includes Docker configuration for easy deployment:
264
+ - Frontend container
265
+ - Backend container
266
+ - Database container
267
+ - Redis container
268
+
269
+ ## Testing
270
+ ```bash
271
+ # Run frontend tests
272
+ cd frontend && npm test
273
+
274
+ # Run backend tests
275
+ cd backend && pytest
276
+ ```
277
+
278
+ ## Contributing
279
+ Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
280
+
281
+ ## License
282
+ This project is licensed under the MIT License - see the LICENSE.md file for details
283
+ """
284
+
285
+ # AI Flow States and Types
286
+ class FlowState(Enum):
287
+ PENDING = "pending"
288
+ RUNNING = "running"
289
+ COMPLETED = "completed"
290
+ FAILED = "failed"
291
+
292
+ class AgentRole(Enum):
293
+ ARCHITECT = "architect"
294
+ UI_DESIGNER = "ui_designer"
295
+ BACKEND_DEVELOPER = "backend_developer"
296
+ DATABASE_ENGINEER = "database_engineer"
297
+ SECURITY_EXPERT = "security_expert"
298
+ QA_ENGINEER = "qa_engineer"
299
+ DEVOPS_ENGINEER = "devops_engineer"
300
+ DOCUMENTATION_WRITER = "documentation_writer"
301
+
302
+ @dataclass
303
+ class AgentContext:
304
+ """Context information for each agent in the flow."""
305
+ role: AgentRole
306
+ state: FlowState
307
+ artifacts: Dict[str, str]
308
+ dependencies: List[AgentRole]
309
+ feedback: List[str]
310
 
311
+ class AIFlow:
312
+ """Manages the flow of work between different AI agents."""
313
+
314
+ def __init__(self):
315
+ self.flow_graph = nx.DiGraph()
316
+ self.contexts: Dict[AgentRole, AgentContext] = {}
317
+ self.global_context = {}
318
+
319
+ def initialize_flow(self):
320
+ """Initialize the AI Flow with agent relationships and dependencies."""
321
+ # Define agent relationships
322
+ flow_structure = {
323
+ AgentRole.ARCHITECT: [AgentRole.UI_DESIGNER, AgentRole.BACKEND_DEVELOPER, AgentRole.DATABASE_ENGINEER],
324
+ AgentRole.UI_DESIGNER: [AgentRole.QA_ENGINEER],
325
+ AgentRole.BACKEND_DEVELOPER: [AgentRole.SECURITY_EXPERT, AgentRole.QA_ENGINEER],
326
+ AgentRole.DATABASE_ENGINEER: [AgentRole.SECURITY_EXPERT],
327
+ AgentRole.SECURITY_EXPERT: [AgentRole.QA_ENGINEER],
328
+ AgentRole.QA_ENGINEER: [AgentRole.DEVOPS_ENGINEER],
329
+ AgentRole.DEVOPS_ENGINEER: [AgentRole.DOCUMENTATION_WRITER],
330
+ AgentRole.DOCUMENTATION_WRITER: []
331
+ }
332
+
333
+ # Build the flow graph
334
+ for role, dependencies in flow_structure.items():
335
+ self.flow_graph.add_node(role)
336
+ for dep in dependencies:
337
+ self.flow_graph.add_edge(role, dep)
338
+
339
+ # Initialize context for each agent
340
+ self.contexts[role] = AgentContext(
341
+ role=role,
342
+ state=FlowState.PENDING,
343
+ artifacts={},
344
+ dependencies=dependencies,
345
+ feedback=[]
346
+ )
347
+
348
+ async def execute_flow(self, requirements: str):
349
+ """Execute the AI Flow with parallel processing where possible."""
350
+ try:
351
+ self.initialize_flow()
352
+ self.global_context["requirements"] = requirements
353
+
354
+ # Get all paths through the flow graph
355
+ paths = list(nx.all_simple_paths(
356
+ self.flow_graph,
357
+ AgentRole.ARCHITECT,
358
+ AgentRole.DOCUMENTATION_WRITER
359
+ ))
360
+
361
+ # Execute paths in parallel
362
+ await self._execute_paths(paths)
363
+
364
+ return self._compile_results()
365
+
366
+ except Exception as e:
367
+ logger.error(f"Flow execution failed: {str(e)}")
368
+ raise
369
+
370
+ async def _execute_paths(self, paths: List[List[AgentRole]]):
371
+ """Execute multiple paths through the flow in parallel."""
372
+ path_tasks = [self._execute_path(path) for path in paths]
373
+ await asyncio.gather(*path_tasks)
374
+
375
+ async def _execute_path(self, path: List[AgentRole]):
376
+ """Execute a single path through the flow."""
377
+ for role in path:
378
+ context = self.contexts[role]
379
+ if context.state != FlowState.COMPLETED:
380
+ await self._execute_agent(role)
381
+
382
+ async def _execute_agent(self, role: AgentRole):
383
+ """Execute a single agent's tasks."""
384
+ context = self.contexts[role]
385
+ context.state = FlowState.RUNNING
386
+
387
+ try:
388
+ # Get agent-specific prompt
389
+ prompt = self._get_agent_prompt(role)
390
+
391
+ # Execute agent's task
392
+ if role == AgentRole.ARCHITECT:
393
+ result = await self._execute_architect(prompt)
394
+ elif role == AgentRole.UI_DESIGNER:
395
+ result = await self._execute_ui_designer(prompt)
396
+ elif role == AgentRole.BACKEND_DEVELOPER:
397
+ result = await self._execute_backend_developer(prompt)
398
+ # ... (similar for other roles)
399
+
400
+ # Store results in context
401
+ context.artifacts["output"] = result
402
+ context.state = FlowState.COMPLETED
403
+
404
+ except Exception as e:
405
+ context.state = FlowState.FAILED
406
+ context.feedback.append(str(e))
407
+ raise
408
+
409
+ def _get_agent_prompt(self, role: AgentRole) -> str:
410
+ """Get the appropriate prompt template for each agent role."""
411
+ prompts = {
412
+ AgentRole.ARCHITECT: """You are a Software Architect designing a scalable application.
413
+ Requirements: {requirements}
414
+
415
+ Focus on:
416
+ 1. System architecture
417
+ 2. Component interactions
418
+ 3. Technology stack selection
419
+ 4. Scalability considerations
420
+ 5. Integration patterns
421
+
422
+ Provide:
423
+ - High-level architecture diagram
424
+ - Component breakdown
425
+ - Technology recommendations
426
+ - Integration patterns
427
+ - Performance considerations""",
428
+ # ... (other role-specific prompts)
429
+ }
430
+
431
+ base_prompt = prompts.get(role, "")
432
+ return base_prompt.format(**self.global_context)
433
+
434
+ async def _execute_architect(self, prompt: str) -> str:
435
+ """Execute the Architect agent's tasks."""
436
+ agent = get_agent("architect")
437
+ return agent.run(prompt)
438
+
439
+ async def _execute_ui_designer(self, prompt: str) -> str:
440
+ """Execute the UI Designer agent's tasks."""
441
+ agent = get_agent("ui_designer")
442
+ return agent.run(prompt)
443
+
444
+ # ... (similar methods for other roles)
445
+
446
+ def _compile_results(self) -> str:
447
+ """Compile the results from all agents into a final output."""
448
+ results = []
449
+ for role, context in self.contexts.items():
450
+ if context.state == FlowState.COMPLETED:
451
+ results.append(f"## {role.value.replace('_', ' ').title()} Output")
452
+ results.append(context.artifacts.get("output", "No output available"))
453
+ results.append("")
454
+
455
+ return "\n".join(results)
456
+
457
+ @dataclass
458
+ class FileContext:
459
+ """Context for file operations and tracking."""
460
+ path: Path
461
+ content: str
462
+ last_modified: datetime
463
+ dependencies: Set[Path]
464
+ checksum: str
465
+
466
+ @classmethod
467
+ def from_path(cls, path: Path):
468
+ content = path.read_text()
469
+ return cls(
470
+ path=path,
471
+ content=content,
472
+ last_modified=datetime.fromtimestamp(path.stat().st_mtime),
473
+ dependencies=set(),
474
+ checksum=hashlib.md5(content.encode()).hexdigest()
475
+ )
476
+
477
+ @dataclass
478
+ class MemoryItem:
479
+ """Represents a single memory item in the system."""
480
+ key: str
481
+ value: Any
482
+ context: dict
483
+ timestamp: datetime
484
+ importance: float = 1.0
485
+ references: Set[str] = field(default_factory=set)
486
+
487
+ class ContextManager:
488
+ """Manages real-time context awareness across the system."""
489
+
490
+ def __init__(self):
491
+ self.file_contexts: Dict[Path, FileContext] = {}
492
+ self.global_context: Dict[str, Any] = {}
493
+ self.command_history: List[Dict] = []
494
+ self.memory_store: Dict[str, MemoryItem] = {}
495
+
496
+ def update_file_context(self, path: Path) -> FileContext:
497
+ """Update context for a specific file."""
498
+ context = FileContext.from_path(path)
499
+ self.file_contexts[path] = context
500
+ return context
501
+
502
+ def get_related_files(self, path: Path) -> Set[Path]:
503
+ """Find files related to the given file."""
504
+ if path not in self.file_contexts:
505
+ self.update_file_context(path)
506
+
507
+ context = self.file_contexts[path]
508
+ return context.dependencies
509
+
510
+ def track_command(self, command: str, args: List[str], result: Any):
511
+ """Track command execution and results."""
512
+ self.command_history.append({
513
+ 'command': command,
514
+ 'args': args,
515
+ 'result': result,
516
+ 'timestamp': datetime.now(),
517
+ })
518
+
519
+ def add_memory(self, key: str, value: Any, context: dict = None):
520
+ """Add an item to the memory store."""
521
+ self.memory_store[key] = MemoryItem(
522
+ key=key,
523
+ value=value,
524
+ context=context or {},
525
+ timestamp=datetime.now()
526
+ )
527
+
528
+ def get_memory(self, key: str) -> Any:
529
+ """Retrieve an item from memory."""
530
+ item = self.memory_store.get(key)
531
+ return item.value if item else None
532
+
533
+ class FileOperationManager:
534
+ """Manages multi-file operations and tracking."""
535
+
536
+ def __init__(self, context_manager: ContextManager):
537
+ self.context_manager = context_manager
538
+ self.pending_changes: Dict[Path, str] = {}
539
+
540
+ async def edit_files(self, changes: Dict[Path, str]):
541
+ """Apply changes to multiple files atomically."""
542
+ try:
543
+ # Validate all changes first
544
+ for path, content in changes.items():
545
+ if not self._validate_change(path, content):
546
+ raise ValueError(f"Invalid change for {path}")
547
+
548
+ # Apply changes
549
+ for path, content in changes.items():
550
+ await self._apply_change(path, content)
551
+
552
+ # Update contexts
553
+ for path in changes:
554
+ self.context_manager.update_file_context(path)
555
+
556
+ except Exception as e:
557
+ logger.error(f"Failed to apply multi-file changes: {str(e)}")
558
+ raise
559
+
560
+ def _validate_change(self, path: Path, content: str) -> bool:
561
+ """Validate a proposed file change."""
562
+ try:
563
+ # Check file exists or can be created
564
+ if not path.parent.exists():
565
+ path.parent.mkdir(parents=True)
566
+
567
+ # Validate syntax if it's a Python file
568
+ if path.suffix == '.py':
569
+ compile(content, str(path), 'exec')
570
+
571
+ return True
572
+ except Exception as e:
573
+ logger.error(f"Validation failed for {path}: {str(e)}")
574
+ return False
575
+
576
+ async def _apply_change(self, path: Path, content: str):
577
+ """Apply a single file change."""
578
+ path.write_text(content)
579
+
580
+ class CommandManager:
581
+ """Manages command suggestions and execution."""
582
+
583
+ def __init__(self, context_manager: ContextManager):
584
+ self.context_manager = context_manager
585
+ self.command_templates: Dict[str, str] = {}
586
+
587
+ def suggest_commands(self, context: dict) -> List[Dict]:
588
+ """Suggest relevant commands based on context."""
589
+ suggestions = []
590
+ for cmd_name, template in self.command_templates.items():
591
+ if self._is_relevant(cmd_name, context):
592
+ suggestions.append({
593
+ 'command': cmd_name,
594
+ 'template': template,
595
+ 'confidence': self._calculate_confidence(cmd_name, context)
596
+ })
597
+ return sorted(suggestions, key=lambda x: x['confidence'], reverse=True)
598
+
599
+ async def execute_command(self, command: str, args: List[str]) -> Any:
600
+ """Execute a command and track its result."""
601
+ try:
602
+ # Execute the command
603
+ result = await self._run_command(command, args)
604
+
605
+ # Track the execution
606
+ self.context_manager.track_command(command, args, result)
607
+
608
+ return result
609
+ except Exception as e:
610
+ logger.error(f"Command execution failed: {str(e)}")
611
+ raise
612
+
613
+ def _is_relevant(self, cmd_name: str, context: dict) -> bool:
614
+ """Determine if a command is relevant to the current context."""
615
+ # Implementation depends on specific rules
616
+ return True
617
+
618
+ def _calculate_confidence(self, cmd_name: str, context: dict) -> float:
619
+ """Calculate confidence score for a command suggestion."""
620
+ # Implementation depends on specific metrics
621
+ return 1.0
622
+
623
+ class RuleSystem:
624
+ """Manages system rules and constraints."""
625
+
626
+ def __init__(self):
627
+ self.rules: Dict[str, callable] = {}
628
+ self.constraints: Dict[str, callable] = {}
629
+
630
+ def add_rule(self, name: str, rule_func: callable):
631
+ """Add a new rule to the system."""
632
+ self.rules[name] = rule_func
633
+
634
+ def add_constraint(self, name: str, constraint_func: callable):
635
+ """Add a new constraint to the system."""
636
+ self.constraints[name] = constraint_func
637
+
638
+ def evaluate_rules(self, context: dict) -> Dict[str, bool]:
639
+ """Evaluate all rules against the current context."""
640
+ return {name: rule(context) for name, rule in self.rules.items()}
641
+
642
+ def check_constraints(self, context: dict) -> Dict[str, bool]:
643
+ """Check all constraints against the current context."""
644
+ return {name: constraint(context) for name, constraint in self.constraints.items()}
645
+
646
+ class ProjectBuilder:
647
+ """Handles autonomous creation of project files and folders."""
648
+
649
+ def __init__(self, base_path: Path):
650
+ self.base_path = Path(base_path)
651
+ self.current_build = None
652
+ self.file_manifest = []
653
+
654
+ async def create_project(self, app_name: str, structure: dict) -> Path:
655
+ """Create a new project with the specified structure."""
656
+ try:
657
+ # Create temporary build directory
658
+ build_dir = Path(tempfile.mkdtemp())
659
+ self.current_build = build_dir / app_name
660
+ self.current_build.mkdir(parents=True)
661
+
662
+ # Create project structure
663
+ await self._create_structure(self.current_build, structure)
664
+
665
+ return self.current_build
666
+ except Exception as e:
667
+ logger.error(f"Project creation failed: {str(e)}")
668
+ if self.current_build and self.current_build.exists():
669
+ shutil.rmtree(self.current_build)
670
+ raise
671
+
672
+ async def _create_structure(self, parent: Path, structure: dict):
673
+ """Recursively create project structure."""
674
+ for name, content in structure.items():
675
+ path = parent / name
676
+ if isinstance(content, dict):
677
+ path.mkdir(exist_ok=True)
678
+ await self._create_structure(path, content)
679
+ else:
680
+ path.write_text(str(content))
681
+ self.file_manifest.append(path)
682
+
683
+ class OutputManager:
684
+ """Manages project outputs and creates downloadable artifacts."""
685
+
686
+ def __init__(self, project_builder: ProjectBuilder):
687
+ self.project_builder = project_builder
688
+ self.output_dir = Path(tempfile.mkdtemp())
689
+ self.downloads = {}
690
+
691
+ def create_download(self, app_name: str) -> str:
692
+ """Create a downloadable zip file of the project."""
693
+ try:
694
+ if not self.project_builder.current_build:
695
+ raise ValueError("No project has been built yet")
696
+
697
+ # Create zip file
698
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
699
+ zip_name = f"{app_name}_{timestamp}.zip"
700
+ zip_path = self.output_dir / zip_name
701
+
702
+ with ZipFile(zip_path, 'w') as zipf:
703
+ for file_path in self.project_builder.file_manifest:
704
+ rel_path = file_path.relative_to(self.project_builder.current_build)
705
+ zipf.write(file_path, rel_path)
706
+
707
+ # Store download info
708
+ self.downloads[zip_name] = {
709
+ 'path': zip_path,
710
+ 'created_at': datetime.now(),
711
+ 'size': zip_path.stat().st_size
712
+ }
713
+
714
+ return str(zip_path)
715
+ except Exception as e:
716
+ logger.error(f"Failed to create download: {str(e)}")
717
+ raise
718
+
719
+ class EnhancedAIFlow(AIFlow):
720
+ """Enhanced AI Flow with project building and output management."""
721
+
722
+ def __init__(self):
723
+ super().__init__()
724
+ self.project_builder = ProjectBuilder(Path(tempfile.mkdtemp()))
725
+ self.output_manager = OutputManager(self.project_builder)
726
+ self.context_manager = ContextManager()
727
+ self.file_manager = FileOperationManager(self.context_manager)
728
+ self.command_manager = CommandManager(self.context_manager)
729
+ self.rule_system = RuleSystem()
730
+
731
+ async def execute_flow(self, requirements: str):
732
+ """Execute the AI Flow and build the project."""
733
+ try:
734
+ # Execute normal flow
735
+ results = await super().execute_flow(requirements)
736
+
737
+ # Extract app name and generate documentation
738
+ app_name = requirements.split()[0].lower().replace(" ", "_")
739
+
740
+ # Create basic project structure
741
+ structure = {
742
+ "frontend": {
743
+ "src": {
744
+ "components": {},
745
+ "pages": {},
746
+ "styles": {},
747
+ },
748
+ "package.json": "{\n \"name\": \"frontend\",\n \"version\": \"1.0.0\"\n}",
749
+ "README.md": "# Frontend\n"
750
+ },
751
+ "backend": {
752
+ "src": {
753
+ "routes": {},
754
+ "models": {},
755
+ "controllers": {},
756
+ },
757
+ "requirements.txt": "fastapi\nuvicorn\n",
758
+ "README.md": "# Backend\n"
759
+ },
760
+ "README.md": f"# {app_name}\nGenerated by AI Flow\n"
761
+ }
762
+
763
+ # Build the project
764
+ await self.project_builder.create_project(app_name, structure)
765
+
766
+ # Create download
767
+ download_path = self.output_manager.create_download(app_name)
768
+
769
+ # Add download information to results
770
+ results += f"""
771
+ ## Download
772
+ Your project has been created and is ready for download:
773
+ - File: {Path(download_path).name}
774
+ - Size: {self.output_manager.downloads[Path(download_path).name]['size'] / 1024:.1f} KB
775
+ - Created: {self.output_manager.downloads[Path(download_path).name]['created_at'].strftime('%Y-%m-%d %H:%M:%S')}
776
+
777
+ To download your project, use this path: {download_path}
778
+
779
+ ## Project Structure
780
+ The following files have been created:
781
+ """
782
+ for file_path in self.project_builder.file_manifest:
783
+ rel_path = file_path.relative_to(self.project_builder.current_build)
784
+ results += f"- {rel_path}\n"
785
+
786
+ return results
787
+ except Exception as e:
788
+ logger.error(f"Enhanced flow execution failed: {str(e)}")
789
+ raise
790
+
791
+ async def _execute_agent(self, role: AgentRole):
792
+ """Execute a single agent's tasks with enhanced context."""
793
+ context = self.contexts[role]
794
+ context.state = FlowState.RUNNING
795
+
796
+ try:
797
+ # Get agent-specific prompt with context
798
+ prompt = self._get_agent_prompt(role)
799
+
800
+ # Add current context to prompt
801
+ prompt += f"\n\nContext:\n{json.dumps(self.context_manager.global_context, indent=2)}"
802
+
803
+ # Execute agent's task
804
+ result = await self._execute_agent_task(role, prompt)
805
+
806
+ # Store results with context
807
+ context.artifacts["output"] = result
808
+ context.state = FlowState.COMPLETED
809
+
810
+ # Update memory
811
+ self.context_manager.add_memory(
812
+ f"agent_result_{role.value}",
813
+ result,
814
+ {"role": role.value, "timestamp": datetime.now()}
815
+ )
816
+
817
+ except Exception as e:
818
+ context.state = FlowState.FAILED
819
+ context.feedback.append(str(e))
820
+ raise
821
+
822
+ # Update the multi_agent_workflow function to use AI Flows
823
+ async def multi_agent_workflow(requirements: str) -> str:
824
  """
825
+ Execute a multi-agent workflow using AI Flows to generate a complex app.
826
  Args:
827
  requirements (str): App requirements.
828
  Returns:
829
  str: Generated app code and API details.
830
  """
831
  try:
832
+ # Initialize and execute AI Flow
833
+ flow = EnhancedAIFlow()
834
+ results = await flow.execute_flow(requirements)
835
+
836
+ # Extract app name and generate documentation
837
+ app_name = requirements.split()[0].lower().replace(" ", "_")
838
+
839
+ # Generate project structure and documentation
840
+ project_structure = generate_project_structure(app_name, flow.contexts[AgentRole.ARCHITECT].artifacts)
841
+ documentation = generate_documentation(app_name, requirements, flow.contexts[AgentRole.DOCUMENTATION_WRITER].artifacts)
842
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  return f"""
844
+ # {app_name.title()} - Generated Application
 
845
 
846
+ ## Project Structure
847
+ ```
848
+ {project_structure}
849
+ ```
850
 
851
+ {results}
 
852
 
853
+ ## Documentation
854
+ {documentation}
855
+
856
+ ## Next Steps
857
+ 1. Review the generated architecture and components
858
+ 2. Set up the development environment
859
+ 3. Implement the components following the provided structure
860
+ 4. Run the test suite
861
+ 5. Deploy using the provided configurations
862
+
863
+ ## Support
864
+ For any issues or questions, please refer to the documentation or create an issue in the repository.
865
  """
866
  except Exception as e:
867
+ error_msg = f"Workflow failed: {str(e)}"
868
+ logger.error(error_msg)
869
+ return error_msg
870
+ finally:
871
+ if torch.cuda.is_available():
872
+ torch.cuda.empty_cache()
873
 
874
+ # Update the app_generator function to handle async execution
875
  def app_generator(requirements: str):
876
  """
877
+ Generate an app based on the provided requirements using AI Flows.
878
  Args:
879
  requirements (str): App requirements.
880
  Returns:
881
  str: Generated app code and API details.
882
  """
883
+ if not requirements or len(requirements.strip()) == 0:
884
+ return "Please provide app requirements."
885
+
886
+ try:
887
+ # Run the async workflow in a new event loop
888
+ loop = asyncio.new_event_loop()
889
+ asyncio.set_event_loop(loop)
890
+ return loop.run_until_complete(multi_agent_workflow(requirements))
891
+ except Exception as e:
892
+ error_msg = f"App generation failed: {str(e)}"
893
+ logger.error(error_msg)
894
+ return error_msg
895
+ finally:
896
+ loop.close()
897
 
898
  # Gradio UI
899
  with gr.Blocks() as ui:
900
  gr.Markdown("# Autonomous App Generator with LangChain Agents")
901
+ gr.Markdown("""
902
+ ## Instructions
903
+ 1. Describe the app you want to build in detail
904
+ 2. Include any specific requirements or features
905
+ 3. Click 'Generate App' to start the process
906
+ 4. Download your generated app from the provided link
907
+ """)
908
+
909
  with gr.Row():
910
+ requirements_input = gr.Textbox(
911
+ label="App Requirements",
912
+ placeholder="Describe the app you want to build...",
913
+ lines=5
914
+ )
915
  generate_button = gr.Button("Generate App")
916
+
917
+ with gr.Row():
918
+ output = gr.Textbox(
919
+ label="Generated App Details",
920
+ lines=20
921
+ )
922
+ file_output = gr.File(
923
+ label="Download Generated App",
924
+ interactive=False
925
+ )
926
+
927
+ def process_output(requirements):
928
+ try:
929
+ # Generate the app
930
+ result = app_generator(requirements)
931
+
932
+ # Extract download path from the result
933
+ download_path = None
934
+ for line in result.split('\n'):
935
+ if line.startswith("To download your project, use this path:"):
936
+ download_path = line.split(": ")[1].strip()
937
+ break
938
+
939
+ if download_path and Path(download_path).exists():
940
+ return result, download_path
941
+ else:
942
+ return result, None
943
+ except Exception as e:
944
+ error_msg = f"Failed to generate app: {str(e)}"
945
+ logger.error(error_msg)
946
+ return error_msg, None
947
+
948
+ generate_button.click(
949
+ process_output,
950
+ inputs=[requirements_input],
951
+ outputs=[output, file_output]
952
+ )
953
 
954
  # Run the Gradio app
955
  if __name__ == "__main__":
956
+ try:
957
+ ui.launch()
958
+ except Exception as e:
959
+ logger.error(f"Failed to launch Gradio interface: {str(e)}")