acecalisto3 commited on
Commit
d681a00
·
verified ·
1 Parent(s): d740f3a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1613 -522
app.py CHANGED
@@ -1,588 +1,1679 @@
1
- import streamlit as st
2
- from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
3
- import inspect
4
- import datetime
5
- import traceback
6
- from abc import ABC, abstractmethod
 
 
 
 
 
 
 
 
 
 
7
  import os
8
- from transformers import pipeline
9
- import subprocess
10
- import requests
11
- import json
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- # --- Error Handling and Logging ---
 
 
 
 
 
 
 
 
 
14
 
15
- class AgentException(Exception):
16
- """Custom exception for agent-related errors."""
17
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- def handle_agent_errors(func):
20
- """Decorator to catch and display agent errors gracefully."""
21
- def wrapper(*args, **kwargs):
22
  try:
23
- return func(*args, **kwargs)
24
- except AgentException as e:
25
- st.error(f"Agent Error: {e}")
26
- st.code(traceback.format_exc(), language="text")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  except Exception as e:
28
- st.error(f"An unexpected error occurred: {e}")
29
- st.code(traceback.format_exc(), language="text")
30
- return wrapper
31
-
32
- # --- Abstract Base Classes ---
33
- class BaseTool(ABC):
34
- @abstractmethod
35
- def use(self, input_str: str) -> str:
36
- """How the tool is used."""
37
- pass
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- class BaseModel(ABC):
41
- @abstractmethod
42
- def generate(self, prompt: str) -> str:
43
- """How the model generates output."""
44
- pass
45
 
46
- # --- Concrete Tool Implementations ---
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- class WorkspaceEmulatorTool(BaseTool):
49
- """Simulates a development workspace."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- def __init__(self):
52
- self.name = "WorkspaceEmulatorTool"
 
 
 
 
 
 
 
53
 
54
- def use(self, input_str: str) -> str:
 
55
  try:
56
- # Parse the input to create directories and files
57
- commands = input_str.split(';')
58
- for cmd in commands:
59
- cmd = cmd.strip()
60
- if cmd.startswith('mkdir '):
61
- dir_name = cmd[len('mkdir '):]
62
- os.makedirs(dir_name, exist_ok=True)
63
- print(f"Directory '{dir_name}' created.")
64
- elif cmd.startswith('touch '):
65
- file_name = cmd[len('touch '):]
66
- open(file_name, 'a').close()
67
- print(f"File '{file_name}' created.")
68
- else:
69
- print(f"Unknown command: {cmd}")
70
- return "Workspace emulated successfully."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  except Exception as e:
72
- return f"Error emulating workspace: {str(e)}"
 
 
 
 
 
 
 
73
 
74
- class DeploymentSimulatorTool(BaseTool):
75
- """Simulates deployment processes."""
76
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def __init__(self):
78
- self.name = "DeploymentSimulatorTool"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- def use(self, input_str: str) -> str:
 
81
  try:
82
- # Simulate deployment steps
83
- steps = input_str.split(';')
84
- for step in steps:
85
- step = step.strip()
86
- if step == 'build':
87
- print("Building the application...")
88
- elif step == 'test':
89
- print("Running tests...")
90
- elif step == 'deploy':
91
- print("Deploying to the server...")
92
- else:
93
- print(f"Unknown step: {step}")
94
- return "Deployment simulated successfully."
 
 
 
 
95
  except Exception as e:
96
- return f"Error simulating deployment: {str(e)}"
 
97
 
98
- class ErrorSpottingTool(BaseTool):
99
- """Spots and corrects errors in code."""
100
-
101
- def __init__(self):
102
- self.name = "ErrorSpottingTool"
103
 
104
- def use(self, input_str: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  try:
106
- # Write the code to a temporary file
107
- with open('temp_code.py', 'w') as f:
108
- f.write(input_str)
 
 
 
 
 
 
109
 
110
- # Run pylint to check for errors
111
- pylint_output = subprocess.check_output(['pylint', 'temp_code.py'], text=True)
112
- os.remove('temp_code.py')
 
 
 
 
 
 
 
 
 
 
 
113
 
114
- # Return the pylint output
115
- return pylint_output
116
  except Exception as e:
117
- return f"Error spotting and correcting code: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- class GitHubRepoSpongeTool(BaseTool):
120
- """Fetches and analyzes GitHub repositories."""
121
-
122
- def __init__(self):
123
- self.name = "GitHubRepoSpongeTool"
124
-
125
- def use(self, input_str: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
126
  try:
127
- # Assume input_str is the GitHub repository in the form 'owner/repo'
128
- owner, repo = input_str.split('/')
129
- url = f'https://api.github.com/repos/{owner}/{repo}'
130
- response = requests.get(url)
131
- if response.status_code == 200:
132
- repo_data = response.json()
133
- return f"Repository data fetched: {repo_data}"
134
- else:
135
- return f"Failed to fetch repository: {response.status_code}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  except Exception as e:
137
- return f"Error fetching GitHub repository: {str(e)}"
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- class MyDuckDuckGoSearchTool(BaseTool, DuckDuckGoSearchTool):
141
- """Performs a DuckDuckGo search and returns the results."""
142
-
143
- def __init__(self):
144
- self.name = "MyDuckDuckGoSearchTool"
145
-
146
- def use(self, input_str: str) -> str:
147
- results = self.search(input_str, max_results=5)
148
- result_str = ""
149
- for idx, result in enumerate(results, 1):
150
- result_str += f"\n{idx}. {result.title} - {result.url}\n{result.text}\n"
151
- return result_str
152
-
153
- class MyHfApiModel(BaseModel, HfApiModel):
154
- """Generates text using the Hugging Face API."""
155
-
156
- def __init__(self, api_token=None):
157
- if api_token is None:
158
- api_token = os.getenv("HUGGINGFACE_API_TOKEN")
159
- super().__init__()
160
- self.api_token = api_token
161
- self.generator = pipeline("text-generation", model="gpt2", tokenizer="gpt2")
162
-
163
- def generate(self, prompt: str) -> str:
164
- response = self.generator(
165
- prompt,
166
- max_new_tokens=100,
167
- num_return_sequences=1
 
 
 
 
168
  )
169
- return response[0]["generated_text"]
170
 
171
- # --- New Tools ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
- class CodeInterpreterTool(BaseTool):
174
- """Interprets and executes Python code."""
175
 
176
- def __init__(self):
177
- self.name = "CodeInterpreterTool"
178
-
179
- def use(self, input_str: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  try:
181
- result = subprocess.run(
182
- ["python", "-c", input_str],
183
- capture_output=True,
184
- text=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  )
186
- if result.returncode == 0:
187
- return result.stdout
188
- else:
189
- return f"Error: {result.stderr}"
 
 
 
 
 
 
190
  except Exception as e:
191
- return f"Execution failed: {str(e)}"
 
192
 
193
- class WorkspaceEmulatorTool(BaseTool):
194
- """Simulates a development workspace."""
195
-
196
- def __init__(self):
197
- self.name = "WorkspaceEmulatorTool"
198
-
199
- def use(self, input_str: str) -> str:
200
- return f"Workspace emulated for: {input_str}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- class DeploymentSimulatorTool(BaseTool):
203
- """Simulates deployment processes."""
204
-
205
- def __init__(self):
206
- self.name = "DeploymentSimulatorTool"
207
-
208
- def use(self, input_str: str) -> str:
209
- return f"Deployment simulated for: {input_str}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
- class ErrorSpottingTool(BaseTool):
212
- """Spots and corrects errors in code."""
213
-
214
- def __init__(self):
215
- self.name = "ErrorSpottingTool"
216
-
217
- def use(self, input_str: str) -> str:
218
- return f"Errors spotted and corrected in: {input_str}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
- class GitHubRepoSpongeTool(BaseTool):
221
- """Fetches and analyzes GitHub repositories."""
222
-
223
- def __init__(self):
224
- self.name = "GitHubRepoSpongeTool"
225
-
226
- def use(self, input_str: str) -> str:
227
- repo_url = input_str.strip()
228
- repo_name = repo_url.split("/")[-1]
229
- api_url = f"https://api.github.com/repos/{repo_name}"
230
- response = requests.get(api_url)
231
- if response.status_code == 200:
232
- repo_data = response.json()
233
- return f"Repository data: {json.dumps(repo_data, indent=2)}"
234
- else:
235
- return f"Failed to fetch repository: {response.status_code}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- class IssueSnifferTool(BaseTool):
238
- """Fetches and analyzes GitHub issues."""
239
-
240
- def __init__(self):
241
- self.name = "IssueSnifferTool"
242
-
243
- def use(self, input_str: str) -> str:
244
- repo_url = input_str.strip()
245
- repo_name = repo_url.split("/")[-1]
246
- api_url = f"https://api.github.com/repos/{repo_name}/issues"
247
- response = requests.get(api_url)
248
- if response.status_code == 200:
249
- issues = response.json()
250
- return f"Issues found: {json.dumps(issues, indent=2)}"
251
- else:
252
- return f"Failed to fetch issues: {response.status_code}"
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
- # --- Agent Definitions ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
 
256
- class CodeInterpreterAgent(CodeAgent):
257
- def __init__(self):
258
- tools = [CodeInterpreterTool()]
259
- model = MyHfApiModel()
260
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
 
262
- class WorkspaceEmulatorAgent(CodeAgent):
263
- def __init__(self):
264
- tools = [WorkspaceEmulatorTool()]
265
- model = MyHfApiModel()
266
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
- class DeploymentSimulatorAgent(CodeAgent):
269
- def __init__(self):
270
- tools = [DeploymentSimulatorTool()]
271
- model = MyHfApiModel()
272
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
 
274
- class ErrorSpottingAgent(CodeAgent):
275
- def __init__(self):
276
- tools = [ErrorSpottingTool()]
277
- model = MyHfApiModel()
278
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
 
280
- class GitHubRepoSpongeAgent(CodeAgent):
281
- def __init__(self):
282
- tools = [GitHubRepoSpongeTool()]
283
- model = MyHfApiModel()
284
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
 
286
- class IssueSnifferAgent(CodeAgent):
287
- def __init__(self):
288
- tools = [IssueSnifferTool()]
289
- model = MyHfApiModel()
290
- super().__init__(tools, model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
- # --- Refinement Loop Integration ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
 
294
- class AutonomousAgent(CodeAgent):
295
- """An agent capable of creating other agents to complete tasks."""
296
-
297
- def __init__(self, tools, model):
298
- super().__init__(tools, model)
299
- self.sub_agents = []
300
- self.refinement_loop = RefinementLoop(DevelopmentPipeline(
301
- workspace_manager=st.session_state.workspace_manager,
302
- tool_manager=st.session_state.tool_manager
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  ))
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
- def analyze_task(self, task: str) -> str:
306
- """Analyzes the task and determines necessary actions."""
307
- prompt = f"Analyze this task and suggest actions: {task}"
308
- analysis = self.model.generate(prompt)
309
- return analysis
310
-
311
- def create_tool(self, tool_name: str):
312
- """Dynamically creates a new tool based on the name."""
313
- if tool_name == "CodeInterpreterTool":
314
- return CodeInterpreterTool()
315
- # Add more tools as needed
316
- return None
317
-
318
- def create_sub_agent(self, task: str):
319
- """Creates a new agent to handle a specific subtask."""
320
- tools = [self.create_tool("CodeInterpreterTool")]
321
- model = MyHfApiModel()
322
- sub_agent = AutonomousAgent(tools, model)
323
- self.sub_agents.append(sub_agent)
324
- return sub_agent
325
-
326
- def delegate_task(self, task: str):
327
- """Delegates a task to a sub-agent."""
328
- sub_agent = self.create_sub_agent(task)
329
- result = sub_agent.run(task)
330
- return result
331
-
332
- def collaborate(self, task: str):
333
- """Collaborates with sub-agents to complete a task."""
334
- analysis = self.analyze_task(task)
335
- if "subtask" in analysis.lower():
336
- subtasks = analysis.split("\n") # Example: Split analysis into subtasks
337
- results = []
338
- for subtask in subtasks:
339
- result = self.delegate_task(subtask)
340
- results.append(result)
341
- return results
342
- else:
343
- return [self.run(task)]
344
-
345
- def run_quality_assurance(self, project_name: str):
346
- """Runs the quality assurance pipeline and refinement loop."""
347
- results = self.refinement_loop.run_refinement_cycle(project_name)
348
- return results
349
-
350
- # --- Tool Menu ---
351
-
352
- def get_available_tools():
353
- """Returns a dictionary of available tools."""
354
- return {
355
- "MyDuckDuckGoSearchTool": MyDuckDuckGoSearchTool(),
356
- "CodeInterpreterTool": CodeInterpreterTool(),
357
- "WorkspaceEmulatorTool": WorkspaceEmulatorTool(),
358
- "DeploymentSimulatorTool": DeploymentSimulatorTool(),
359
- "ErrorSpottingTool": ErrorSpottingTool(),
360
- "GitHubRepoSpongeTool": GitHubRepoSpongeTool(),
361
- "IssueSnifferTool": IssueSnifferTool(),
362
- }
363
-
364
- # --- Tool and Model Discovery ---
365
-
366
- def discover_tools_and_models():
367
- """Automatically discovers and returns dictionaries of available tools and models."""
368
- tools = {}
369
- models = {}
370
-
371
- for name, obj in inspect.getmembers(inspect.getmodule(inspect.currentframe())):
372
- if inspect.isclass(obj):
373
- if issubclass(obj, BaseTool) and obj is not BaseTool:
374
- tools[name] = obj
375
- if issubclass(obj, BaseModel) and obj is not BaseModel:
376
- models[name] = obj
377
-
378
- return tools, models
379
-
380
- # --- Agent Registry ---
381
-
382
- class AgentRegistry:
383
  def __init__(self):
384
- self.agents = {}
385
-
386
- @handle_agent_errors
387
- def add_agent(self, name, agent):
388
- if not isinstance(agent, CodeAgent):
389
- raise TypeError("Agent must be an instance of CodeAgent.")
390
- if name in self.agents:
391
- raise ValueError(f"Agent with name '{name}' already exists.")
392
- self.agents[name] = agent
393
-
394
- def get_agent(self, name):
395
- if name not in self.agents:
396
- raise AgentException(f"Agent '{name}' not found.")
397
- return self.agents.get(name)
398
-
399
- def list_agents(self):
400
- return list(self.agents.keys())
401
-
402
- # --- State Management ---
403
-
404
- def initialize_state():
405
- """Initializes the Streamlit session state."""
406
- if "agent_registry" not in st.session_state:
407
- st.session_state.agent_registry = AgentRegistry()
408
- available_tools, available_models = discover_tools_and_models()
409
- st.session_state.available_tools = available_tools
410
- st.session_state.available_models = available_models
411
-
412
- # Add pre-generated supplemental agents
413
- st.session_state.agent_registry.add_agent("CodeInterpreterAgent", CodeInterpreterAgent())
414
- st.session_state.agent_registry.add_agent("WorkspaceEmulatorAgent", WorkspaceEmulatorAgent())
415
- st.session_state.agent_registry.add_agent("DeploymentSimulatorAgent", DeploymentSimulatorAgent())
416
- st.session_state.agent_registry.add_agent("ErrorSpottingAgent", ErrorSpottingAgent())
417
- st.session_state.agent_registry.add_agent("GitHubRepoSpongeAgent", GitHubRepoSpongeAgent())
418
- st.session_state.agent_registry.add_agent("IssueSnifferAgent", IssueSnifferAgent())
419
-
420
- # Add a default autonomous agent
421
- st.session_state.agent_registry.add_agent(
422
- "AutonomousDevAgent",
423
- AutonomousAgent(
424
- tools=[MyDuckDuckGoSearchTool()],
425
- model=MyHfApiModel()
426
  )
427
- )
428
- if "logs" not in st.session_state:
429
- st.session_state.logs = []
430
- if "autonomous_output" not in st.session_state:
431
- st.session_state.autonomous_output = []
432
- if "chat_output" not in st.session_state:
433
- st.session_state.chat_output = []
434
-
435
- # --- Logging ---
436
-
437
- def log_agent_action(prompt, result, agent_name):
438
- timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
439
- log_entry = {
440
- "timestamp": timestamp,
441
- "agent": agent_name,
442
- "prompt": prompt,
443
- "result": result
444
- }
445
- st.session_state.logs.append(log_entry)
446
-
447
- # --- Chat Output ---
448
-
449
- def add_to_chat_output(agent_name: str, message: str):
450
- """Adds a message to the chat output."""
451
- timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
452
- chat_entry = {
453
- "timestamp": timestamp,
454
- "agent": agent_name,
455
- "message": message
456
- }
457
- st.session_state.chat_output.append(chat_entry)
458
-
459
- # --- Streamlit UI ---
460
 
461
- def main():
462
- st.title("AI Agent Sandbox - Autonomous Mode")
463
- st.write("Create, test, and manage autonomous AI agents that can create other agents to complete tasks.")
 
 
 
 
 
 
 
464
 
465
- initialize_state()
 
 
 
 
 
 
 
466
 
467
- # --- Sidebar: Agent Management ---
468
- with st.sidebar:
469
- st.subheader("Agent Management")
470
- selected_agent_name = st.selectbox(
471
- "Select an Agent:",
472
- st.session_state.agent_registry.list_agents() + ["Create New Agent"]
 
 
473
  )
474
 
475
- # --- Create New Agent ---
476
- if selected_agent_name == "Create New Agent":
477
- st.subheader("Create a New Agent")
478
- new_agent_name = st.text_input("Agent Name:")
 
 
479
 
480
- tool_options = {
481
- name: f"{name} - {cls.__doc__ or 'No description available.'}"
482
- for name, cls in st.session_state.available_tools.items()
483
- }
484
- selected_tool_names = st.multiselect(
485
- "Agent Tools:",
486
- options=list(tool_options.keys()),
487
- format_func=lambda x: tool_options[x],
488
- default=["MyDuckDuckGoSearchTool"] if "MyDuckDuckGoSearchTool" in tool_options else []
489
- )
490
 
491
- model_options = {
492
- name: f"{name} - {cls.__doc__ or 'No description available.'}"
493
- for name, cls in st.session_state.available_models.items()
494
- }
495
- selected_model_name = st.selectbox(
496
- "Model:",
497
- options=list(model_options.keys())
498
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
 
500
- if st.button("Create Agent"):
501
- create_agent(new_agent_name, selected_tool_names, selected_model_name)
502
-
503
- # --- Tool Menu for Autonomous Agent ---
504
- st.header("Tool Menu for Autonomous Agent")
505
- available_tools = get_available_tools()
506
- selected_tools = st.multiselect(
507
- "Select tools for the autonomous agent:",
508
- options=list(available_tools.keys()),
509
- default=["MyDuckDuckGoSearchTool"]
510
- )
511
-
512
- # --- Autonomous Mode ---
513
- st.header("Autonomous Mode")
514
- task = st.text_area("Enter a task for the autonomous agent:", "Develop a tool to automate software development tasks.")
515
-
516
- # --- Quality Assurance Pipeline ---
517
- if st.button("Run Quality Assurance Pipeline"):
518
- if "AutonomousDevAgent" in st.session_state.agent_registry.list_agents():
519
- agent = st.session_state.agent_registry.get_agent("AutonomousDevAgent")
520
- if isinstance(agent, AutonomousAgent):
521
- project_name = "SampleProject" # Replace with actual project name
522
- qa_results = agent.run_quality_assurance(project_name)
523
- st.session_state.autonomous_output.append(f"Quality Assurance Results: {qa_results}")
524
- add_to_chat_output("AutonomousDevAgent", "Quality Assurance completed.")
525
- else:
526
- st.error("Selected agent is not an AutonomousAgent.")
527
- else:
528
- st.error("AutonomousDevAgent not available.")
529
-
530
- # Initialize a flag for continuous refinement
531
- if "refining" not in st.session_state:
532
- st.session_state.refining = False
533
-
534
- if st.button("Start Continuous Refinement"):
535
- st.session_state.refining = True
536
- # Initialize the autonomous agent with selected tools
537
- tools = [available_tools[tool] for tool in selected_tools]
538
- autonomous_agent = AutonomousAgent(tools=tools, model=MyHfApiModel())
539
-
540
- # Add initial task to chat output
541
- add_to_chat_output("AutonomousDevAgent", f"Starting task: {task}")
542
-
543
- while st.session_state.refining:
544
- # Run the autonomous agent
545
- results = autonomous_agent.collaborate(task)
546
-
547
- # Display results in-app
548
- st.session_state.autonomous_output = []
549
- for result in results:
550
- st.session_state.autonomous_output.append(result)
551
- add_to_chat_output("AutonomousDevAgent", f"Task result: {result}")
552
-
553
- # Log the results
554
- log_agent_action(task, results, "AutonomousDevAgent")
555
-
556
- # Allow for user interjection
557
- user_message = st.text_input("Enter a message to steer/redirect/modify the developmental course:", key="user_interjection")
558
- if st.button("Submit Message"):
559
- if user_message:
560
- add_to_chat_output("User", f"Interjection: {user_message}")
561
- st.session_state.autonomous_output.append(f"User Interjection: {user_message}")
562
- st.write(f"**User Interjection:**\n{user_message}")
563
-
564
- # Check if the user wants to stop the refinement
565
- if st.button("Stop Continuous Refinement"):
566
- st.session_state.refining = False
567
- st.write("Continuous refinement stopped.")
568
-
569
- # --- Chat Output ---
570
- st.header("Chat Output")
571
- for entry in st.session_state.chat_output:
572
- st.write(f"{entry['timestamp']} - {entry['agent']}: {entry['message']}")
573
-
574
- # --- Display Autonomous Output ---
575
- st.header("Autonomous Output")
576
- for output in st.session_state.autonomous_output:
577
- st.write(f"**Output:**\n{output}")
578
-
579
- # --- Display Logs ---
580
- st.header("Logs")
581
- if st.session_state.logs:
582
- for log in st.session_state.logs:
583
- st.write(f"{log['timestamp']} - {log['agent']}: {log['prompt']} -> {log['result']}")
584
- else:
585
- st.write("No logs available.")
586
 
587
  if __name__ == "__main__":
588
  main()
 
1
+ # Add these imports at the top of your file
2
+ from typing import List, Dict, Optional, Any, Tuple
3
+ from dataclasses import dataclass
4
+ from enum import Enum
5
+ import logging
6
+ import time
7
+ import ast
8
+ import pylint.lint
9
+ import radon.complexity
10
+ import radon.metrics
11
+ from pylint.lint import Run
12
+ from pylint.reporters import JSONReporter
13
+ from coverage import Coverage
14
+ import bandit
15
+ from bandit.core import manager
16
+ from datetime import datetime
17
  import os
18
+ import sys
19
+ import streamlit as st
20
+ import asyncio
21
+ from typing import Dict, Any
22
+ from datetime import datetime
23
+ from pathlib import Path
24
+
25
+ # Configure logging
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
29
+ handlers=[
30
+ logging.FileHandler('app.log'),
31
+ logging.StreamHandler(sys.stdout)
32
+ ]
33
+ )
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+ class CodeMetricsAnalyzer:
38
+ """Analyzes code metrics using various tools"""
39
+
40
+ def __init__(self):
41
+ self.metrics_history = []
42
+
43
+ def analyze_code_quality(self, file_path: str) -> Dict[str, Any]:
44
+ """Analyzes code quality using multiple metrics"""
45
+ try:
46
+ # Pylint analysis
47
+ pylint_score = self._run_pylint(file_path)
48
+
49
+ # Complexity analysis
50
+ complexity_score = self._analyze_complexity(file_path)
51
+
52
+ # Test coverage analysis
53
+ coverage_score = self._analyze_test_coverage(file_path)
54
+
55
+ # Security analysis
56
+ security_score = self._analyze_security(file_path)
57
+
58
+ # Calculate overall quality score
59
+ quality_score = self._calculate_overall_score(
60
+ pylint_score,
61
+ complexity_score,
62
+ coverage_score,
63
+ security_score
64
+ )
65
+
66
+ metrics = {
67
+ "quality_score": quality_score,
68
+ "pylint_score": pylint_score,
69
+ "complexity_score": complexity_score,
70
+ "coverage_score": coverage_score,
71
+ "security_score": security_score,
72
+ "timestamp": datetime.now()
73
+ }
74
+
75
+ self.metrics_history.append(metrics)
76
+ return metrics
77
+
78
+ except Exception as e:
79
+ logging.error(f"Error analyzing code metrics: {str(e)}")
80
+ return {
81
+ "error": str(e),
82
+ "quality_score": 0.0,
83
+ "timestamp": datetime.now()
84
+ }
85
 
86
+ def _run_pylint(self, file_path: str) -> float:
87
+ """Runs pylint analysis"""
88
+ try:
89
+ reporter = JSONReporter()
90
+ Run([file_path], reporter=reporter, do_exit=False)
91
+ score = reporter.data.get('score', 0.0)
92
+ return float(score) / 10.0 # Normalize to 0-1 scale
93
+ except Exception as e:
94
+ logging.error(f"Pylint analysis error: {str(e)}")
95
+ return 0.0
96
 
97
+ def _analyze_complexity(self, file_path: str) -> float:
98
+ """Analyzes code complexity"""
99
+ try:
100
+ with open(file_path, 'r') as file:
101
+ code = file.read()
102
+
103
+ # Calculate cyclomatic complexity
104
+ complexity = radon.complexity.cc_visit(code)
105
+ avg_complexity = sum(item.complexity for item in complexity) / len(complexity) if complexity else 0
106
+
107
+ # Normalize complexity score (0-1 scale, lower is better)
108
+ normalized_score = 1.0 - min(avg_complexity / 10.0, 1.0)
109
+ return normalized_score
110
+
111
+ except Exception as e:
112
+ logging.error(f"Complexity analysis error: {str(e)}")
113
+ return 0.0
114
 
115
+ def _analyze_test_coverage(self, file_path: str) -> float:
116
+ """Analyzes test coverage"""
 
117
  try:
118
+ cov = Coverage()
119
+ cov.start()
120
+
121
+ # Execute the file to measure coverage
122
+ with open(file_path) as f:
123
+ exec(compile(f.read(), file_path, 'exec'))
124
+
125
+ cov.stop()
126
+ cov.save()
127
+
128
+ # Get coverage data
129
+ total_lines = 0
130
+ covered_lines = 0
131
+
132
+ for filename in cov.data.measured_files():
133
+ _, executable, _, missing, _ = cov.analysis(filename)
134
+ total_lines += len(executable)
135
+ covered_lines += len(executable) - len(missing)
136
+
137
+ coverage_ratio = covered_lines / total_lines if total_lines > 0 else 0
138
+ return coverage_ratio
139
+
140
  except Exception as e:
141
+ logging.error(f"Coverage analysis error: {str(e)}")
142
+ return 0.0
 
 
 
 
 
 
 
 
143
 
144
+ def _analyze_security(self, file_path: str) -> float:
145
+ """Analyzes code security using bandit"""
146
+ try:
147
+ conf = manager.BanditManager()
148
+ conf.discover_files([file_path])
149
+ conf.run_tests()
150
+
151
+ # Calculate security score based on findings
152
+ total_issues = len(conf.get_issue_list())
153
+ max_severity = max((issue.severity for issue in conf.get_issue_list()), default=0)
154
+
155
+ # Normalize security score (0-1 scale, higher is better)
156
+ security_score = 1.0 - (total_issues * max_severity) / 10.0
157
+ return max(0.0, min(1.0, security_score))
158
+
159
+ except Exception as e:
160
+ logging.error(f"Security analysis error: {str(e)}")
161
+ return 0.0
162
+
163
+ def _calculate_overall_score(self, pylint_score: float, complexity_score: float,
164
+ coverage_score: float, security_score: float) -> float:
165
+ """Calculates overall code quality score"""
166
+ weights = {
167
+ 'pylint': 0.3,
168
+ 'complexity': 0.2,
169
+ 'coverage': 0.25,
170
+ 'security': 0.25
171
+ }
172
+
173
+ overall_score = (
174
+ weights['pylint'] * pylint_score +
175
+ weights['complexity'] * complexity_score +
176
+ weights['coverage'] * coverage_score +
177
+ weights['security'] * security_score
178
+ )
179
+
180
+ return max(0.0, min(1.0, overall_score))
181
 
182
+ def get_metrics_history(self) -> List[Dict[str, Any]]:
183
+ """Returns the history of metrics measurements"""
184
+ return self.metrics_history
 
 
185
 
186
+ def get_trend_analysis(self) -> Dict[str, Any]:
187
+ """Analyzes trends in metrics over time"""
188
+ if not self.metrics_history:
189
+ return {"status": "No metrics history available"}
190
+
191
+ trends = {
192
+ "quality_score": self._calculate_trend([m["quality_score"] for m in self.metrics_history]),
193
+ "coverage_score": self._calculate_trend([m["coverage_score"] for m in self.metrics_history]),
194
+ "security_score": self._calculate_trend([m["security_score"] for m in self.metrics_history])
195
+ }
196
+
197
+ return trends
198
 
199
+ def _calculate_trend(self, values: List[float]) -> Dict[str, Any]:
200
+ """Calculates trend statistics for a metric"""
201
+ if not values:
202
+ return {"trend": "unknown", "change": 0.0}
203
+
204
+ recent_values = values[-3:] # Look at last 3 measurements
205
+ if len(recent_values) < 2:
206
+ return {"trend": "insufficient data", "change": 0.0}
207
+
208
+ change = recent_values[-1] - recent_values[0]
209
+ trend = "improving" if change > 0 else "declining" if change < 0 else "stable"
210
+
211
+ return {
212
+ "trend": trend,
213
+ "change": change,
214
+ "current": recent_values[-1],
215
+ "previous": recent_values[0]
216
+ }
217
+
218
+ @dataclass
219
+ class QualityMetrics:
220
+ """Advanced quality metrics tracking and analysis"""
221
+ code_quality_score: float = 0.0
222
+ test_coverage: float = 0.0
223
+ security_score: str = "unknown"
224
+ performance_score: float = 0.0
225
+ metrics_analyzer: CodeMetricsAnalyzer = None
226
 
227
+ def __post_init__(self):
228
+ self.metrics_analyzer = CodeMetricsAnalyzer()
229
+ self.history = []
230
+ self.thresholds = {
231
+ "code_quality": 0.85,
232
+ "test_coverage": 0.90,
233
+ "security": 0.85,
234
+ "performance": 0.80
235
+ }
236
 
237
+ def analyze_code(self, project_name: str) -> Dict[str, Any]:
238
+ """Comprehensive code analysis"""
239
  try:
240
+ # Get all Python files in the project
241
+ project_files = self._get_project_files(project_name)
242
+
243
+ aggregated_metrics = {
244
+ "code_quality": 0.0,
245
+ "test_coverage": 0.0,
246
+ "security": 0.0,
247
+ "performance": 0.0,
248
+ "files_analyzed": len(project_files),
249
+ "detailed_metrics": []
250
+ }
251
+
252
+ for file_path in project_files:
253
+ metrics = self.metrics_analyzer.analyze_code_quality(file_path)
254
+ aggregated_metrics["detailed_metrics"].append({
255
+ "file": file_path,
256
+ "metrics": metrics
257
+ })
258
+
259
+ # Update aggregated scores
260
+ aggregated_metrics["code_quality"] += metrics["quality_score"]
261
+ aggregated_metrics["test_coverage"] += metrics["coverage_score"]
262
+ aggregated_metrics["security"] += metrics["security_score"]
263
+
264
+ # Calculate averages
265
+ if project_files:
266
+ for key in ["code_quality", "test_coverage", "security"]:
267
+ aggregated_metrics[key] /= len(project_files)
268
+
269
+ # Update instance variables
270
+ self.code_quality_score = aggregated_metrics["code_quality"]
271
+ self.test_coverage = aggregated_metrics["test_coverage"]
272
+ self.security_score = str(aggregated_metrics["security"])
273
+
274
+ # Add to history
275
+ self.history.append({
276
+ "timestamp": datetime.now(),
277
+ "metrics": aggregated_metrics
278
+ })
279
+
280
+ return aggregated_metrics
281
+
282
  except Exception as e:
283
+ logging.error(f"Error in code analysis: {str(e)}")
284
+ return {
285
+ "error": str(e),
286
+ "code_quality": 0.0,
287
+ "test_coverage": 0.0,
288
+ "security": "error",
289
+ "performance": 0.0
290
+ }
291
 
292
+ def _get_project_files(self, project_name: str) -> List[str]:
293
+ """Get all Python files in the project"""
294
+ project_dir = os.path.join(os.getcwd(), project_name)
295
+ python_files = []
296
+
297
+ for root, _, files in os.walk(project_dir):
298
+ for file in files:
299
+ if file.endswith('.py'):
300
+ python_files.append(os.path.join(root, file))
301
+
302
+ return python_files
303
+
304
+ def get_improvement_suggestions(self) -> List[str]:
305
+ """Generate improvement suggestions based on metrics"""
306
+ suggestions = []
307
+ latest_metrics = self.history[-1]["metrics"] if self.history else None
308
+
309
+ if not latest_metrics:
310
+ return ["No metrics available for analysis"]
311
+
312
+ if latest_metrics["code_quality"] < self.thresholds["code_quality"]:
313
+ suggestions.append(
314
+ f"Code quality score ({latest_metrics['code_quality']:.2f}) is below threshold "
315
+ f"({self.thresholds['code_quality']}). Consider refactoring complex methods."
316
+ )
317
+
318
+ if latest_metrics["test_coverage"] < self.thresholds["test_coverage"]:
319
+ suggestions.append(
320
+ f"Test coverage ({latest_metrics['test_coverage']:.2f}) is below threshold "
321
+ f"({self.thresholds['test_coverage']}). Add more unit tests."
322
+ )
323
+
324
+ if float(latest_metrics["security"]) < self.thresholds["security"]:
325
+ suggestions.append(
326
+ f"Security score ({latest_metrics['security']}) is below threshold "
327
+ f"({self.thresholds['security']}). Address security vulnerabilities."
328
+ )
329
+
330
+ return suggestions
331
+
332
+ class ErrorTracker:
333
+ """Enhanced error tracking and analysis"""
334
  def __init__(self):
335
+ self.errors: List[Dict[str, Any]] = []
336
+ self.error_patterns: Dict[str, int] = {}
337
+ self.critical_errors: List[Dict[str, Any]] = []
338
+
339
+ def add_error(self, error_type: str, message: str, severity: str = "normal"):
340
+ """Add an error with enhanced tracking"""
341
+ error_entry = {
342
+ "type": error_type,
343
+ "message": message,
344
+ "severity": severity,
345
+ "timestamp": datetime.now(),
346
+ "stack_trace": traceback.format_exc()
347
+ }
348
+
349
+ self.errors.append(error_entry)
350
+
351
+ # Track error patterns
352
+ if error_type in self.error_patterns:
353
+ self.error_patterns[error_type] += 1
354
+ else:
355
+ self.error_patterns[error_type] = 1
356
+
357
+ # Track critical errors
358
+ if severity == "critical":
359
+ self.critical_errors.append(error_entry)
360
+ self._notify_critical_error(error_entry)
361
+
362
+ def _notify_critical_error(self, error: Dict[str, Any]):
363
+ """Handle critical error notification"""
364
+ logging.critical(f"Critical error detected: {error['message']}")
365
+ # Implement notification system here (e.g., email, Slack)
366
+
367
+ def get_error_analysis(self) -> Dict[str, Any]:
368
+ """Generate comprehensive error analysis"""
369
+ return {
370
+ "total_errors": len(self.errors),
371
+ "error_patterns": self.error_patterns,
372
+ "critical_errors": len(self.critical_errors),
373
+ "most_common_error": max(self.error_patterns.items(), key=lambda x: x[1]) if self.error_patterns else None,
374
+ "error_trend": self._analyze_error_trend()
375
+ }
376
+
377
+ def _analyze_error_trend(self) -> Dict[str, Any]:
378
+ """Analyze error trends over time"""
379
+ if not self.errors:
380
+ return {"trend": "no errors"}
381
+
382
+ # Group errors by hour
383
+ error_timeline = {}
384
+ for error in self.errors:
385
+ hour = error["timestamp"].replace(minute=0, second=0, microsecond=0)
386
+ if hour in error_timeline:
387
+ error_timeline[hour] += 1
388
+ else:
389
+ error_timeline[hour] = 1
390
+
391
+ # Calculate trend
392
+ timeline_values = list(error_timeline.values())
393
+ if len(timeline_values) < 2:
394
+ return {"trend": "insufficient data"}
395
+
396
+ trend = "increasing" if timeline_values[-1] > timeline_values[0] else "decreasing"
397
+ return {
398
+ "trend": trend,
399
+ "current_rate": timeline_values[-1],
400
+ "initial_rate": timeline_values[0]
401
+ }
402
+
403
+ class ProjectAnalytics:
404
+ """Enhanced project analytics and reporting"""
405
+ def __init__(self, workspace_manager):
406
+ self.workspace_manager = workspace_manager
407
+ self.metrics_analyzer = CodeMetricsAnalyzer()
408
+ self.analysis_history = []
409
 
410
+ def generate_project_report(self, project_name: str) -> Dict[str, Any]:
411
+ """Generate comprehensive project report"""
412
  try:
413
+ current_analysis = {
414
+ "timestamp": datetime.now(),
415
+ "basic_metrics": self._get_basic_metrics(project_name),
416
+ "code_quality": self._get_code_quality_metrics(project_name),
417
+ "performance": self._get_performance_metrics(project_name),
418
+ "security": self._get_security_metrics(project_name),
419
+ "dependencies": self._analyze_dependencies(project_name)
420
+ }
421
+
422
+ self.analysis_history.append(current_analysis)
423
+
424
+ return {
425
+ "current_analysis": current_analysis,
426
+ "historical_trends": self._analyze_trends(),
427
+ "recommendations": self._generate_recommendations(current_analysis)
428
+ }
429
+
430
  except Exception as e:
431
+ logging.error(f"Error generating project report: {str(e)}")
432
+ return {"error": str(e)}
433
 
434
+ class DevelopmentPipeline:
435
+ """Advanced development pipeline with stage management and monitoring"""
 
 
 
436
 
437
+ class PipelineStage(Enum):
438
+ PLANNING = "planning"
439
+ DEVELOPMENT = "development"
440
+ TESTING = "testing"
441
+ DEPLOYMENT = "deployment"
442
+ MAINTENANCE = "maintenance"
443
+ ROLLBACK = "rollback"
444
+
445
+ def __init__(self, workspace_manager, tool_manager):
446
+ self.workspace_manager = workspace_manager
447
+ self.tool_manager = tool_manager
448
+ self.current_stage = None
449
+ self.stage_history = []
450
+ self.active_processes = {}
451
+ self.stage_metrics = {}
452
+ self.logger = self._setup_logger()
453
+
454
+ def _setup_logger(self) -> logging.Logger:
455
+ logger = logging.getLogger("DevelopmentPipeline")
456
+ logger.setLevel(logging.DEBUG)
457
+ handler = logging.StreamHandler()
458
+ formatter = logging.Formatter(
459
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
460
+ )
461
+ handler.setFormatter(formatter)
462
+ logger.addHandler(handler)
463
+ return logger
464
+
465
+ async def execute_stage(self, stage: PipelineStage, context: Dict[str, Any]) -> Dict[str, Any]:
466
+ """Execute a pipeline stage with monitoring and error handling"""
467
+ self.logger.info(f"Starting stage: {stage.value}")
468
+ start_time = time.time()
469
+
470
  try:
471
+ # Record stage start
472
+ self.current_stage = stage
473
+ self._record_stage_start(stage, context)
474
+
475
+ # Execute stage-specific logic
476
+ result = await self._execute_stage_logic(stage, context)
477
+
478
+ # Validate stage output
479
+ self._validate_stage_output(stage, result)
480
 
481
+ # Update metrics
482
+ execution_time = time.time() - start_time
483
+ self._update_stage_metrics(stage, execution_time, result)
484
+
485
+ # Record stage completion
486
+ self._record_stage_completion(stage, result)
487
+
488
+ return {
489
+ "status": "success",
490
+ "stage": stage.value,
491
+ "result": result,
492
+ "execution_time": execution_time,
493
+ "metrics": self.stage_metrics.get(stage, {})
494
+ }
495
 
 
 
496
  except Exception as e:
497
+ error_msg = f"Error in stage {stage.value}: {str(e)}"
498
+ self.logger.error(error_msg)
499
+
500
+ # Handle stage failure
501
+ await self._handle_stage_failure(stage, context, e)
502
+
503
+ return {
504
+ "status": "error",
505
+ "stage": stage.value,
506
+ "error": error_msg,
507
+ "execution_time": time.time() - start_time
508
+ }
509
 
510
+ async def _execute_stage_logic(self, stage: PipelineStage, context: Dict[str, Any]) -> Dict[str, Any]:
511
+ """Execute stage-specific logic with appropriate tools"""
512
+ if stage == self.PipelineStage.PLANNING:
513
+ return await self._execute_planning_stage(context)
514
+ elif stage == self.PipelineStage.DEVELOPMENT:
515
+ return await self._execute_development_stage(context)
516
+ elif stage == self.PipelineStage.TESTING:
517
+ return await self._execute_testing_stage(context)
518
+ elif stage == self.PipelineStage.DEPLOYMENT:
519
+ return await self._execute_deployment_stage(context)
520
+ elif stage == self.PipelineStage.MAINTENANCE:
521
+ return await self._execute_maintenance_stage(context)
522
+ elif stage == self.PipelineStage.ROLLBACK:
523
+ return await self._execute_rollback_stage(context)
524
+ else:
525
+ raise ValueError(f"Unknown pipeline stage: {stage}")
526
+
527
+ async def _execute_planning_stage(self, context: Dict[str, Any]) -> Dict[str, Any]:
528
+ """Execute planning stage with requirement analysis and task breakdown"""
529
  try:
530
+ # Analyze requirements
531
+ requirements = await self.tool_manager.execute_tool(
532
+ "requirements_analyzer",
533
+ context.get("requirements", "")
534
+ )
535
+
536
+ # Generate task breakdown
537
+ tasks = await self.tool_manager.execute_tool(
538
+ "task_breakdown",
539
+ requirements["result"]
540
+ )
541
+
542
+ # Create project structure
543
+ project_structure = await self.workspace_manager.create_project_structure(
544
+ context["project_name"],
545
+ tasks["result"]
546
+ )
547
+
548
+ return {
549
+ "requirements": requirements["result"],
550
+ "tasks": tasks["result"],
551
+ "project_structure": project_structure
552
+ }
553
  except Exception as e:
554
+ raise Exception(f"Planning stage failed: {str(e)}")
555
 
556
+ async def _execute_development_stage(self, context: Dict[str, Any]) -> Dict[str, Any]:
557
+ """Execute development stage with code generation and quality checks"""
558
+ try:
559
+ # Generate code
560
+ code_generation = await self.tool_manager.execute_tool(
561
+ "code_generator",
562
+ context.get("tasks", [])
563
+ )
564
+
565
+ # Run initial quality checks
566
+ quality_check = await self.tool_manager.execute_tool(
567
+ "code_quality_checker",
568
+ code_generation["result"]
569
+ )
570
+
571
+ # Save generated code
572
+ saved_files = await self.workspace_manager.save_generated_code(
573
+ context["project_name"],
574
+ code_generation["result"]
575
+ )
576
+
577
+ return {
578
+ "generated_code": code_generation["result"],
579
+ "quality_check": quality_check["result"],
580
+ "saved_files": saved_files
581
+ }
582
+ except Exception as e:
583
+ raise Exception(f"Development stage failed: {str(e)}")
584
+
585
+ async def _execute_testing_stage(self, context: Dict[str, Any]) -> Dict[str, Any]:
586
+ """Execute testing stage with comprehensive test suite"""
587
+ try:
588
+ # Generate tests
589
+ test_generation = await self.tool_manager.execute_tool(
590
+ "test_generator",
591
+ context.get("generated_code", "")
592
+ )
593
+
594
+ # Run tests
595
+ test_results = await self.tool_manager.execute_tool(
596
+ "test_runner",
597
+ test_generation["result"]
598
+ )
599
+
600
+ # Generate coverage report
601
+ coverage_report = await self.tool_manager.execute_tool(
602
+ "coverage_analyzer",
603
+ test_results["result"]
604
+ )
605
+
606
+ return {
607
+ "test_cases": test_generation["result"],
608
+ "test_results": test_results["result"],
609
+ "coverage_report": coverage_report["result"]
610
+ }
611
+ except Exception as e:
612
+ raise Exception(f"Testing stage failed: {str(e)}")
613
+
614
+ def _validate_stage_output(self, stage: PipelineStage, result: Dict[str, Any]):
615
+ """Validate stage output against defined criteria"""
616
+ validation_rules = self._get_validation_rules(stage)
617
+ validation_errors = []
618
 
619
+ for rule in validation_rules:
620
+ if not rule.validate(result):
621
+ validation_errors.append(rule.get_error_message())
622
+
623
+ if validation_errors:
624
+ raise ValueError(f"Stage validation failed: {'; '.join(validation_errors)}")
625
+
626
+ def _update_stage_metrics(self, stage: PipelineStage, execution_time: float, result: Dict[str, Any]):
627
+ """Update metrics for the stage"""
628
+ if stage not in self.stage_metrics:
629
+ self.stage_metrics[stage] = {
630
+ "total_executions": 0,
631
+ "successful_executions": 0,
632
+ "failed_executions": 0,
633
+ "average_execution_time": 0,
634
+ "last_execution_time": None,
635
+ "error_rate": 0
636
+ }
637
+
638
+ metrics = self.stage_metrics[stage]
639
+ metrics["total_executions"] += 1
640
+ metrics["last_execution_time"] = execution_time
641
+
642
+ if result.get("status") == "success":
643
+ metrics["successful_executions"] += 1
644
+ else:
645
+ metrics["failed_executions"] += 1
646
+
647
+ metrics["error_rate"] = metrics["failed_executions"] / metrics["total_executions"]
648
+ metrics["average_execution_time"] = (
649
+ (metrics["average_execution_time"] * (metrics["total_executions"] - 1) + execution_time)
650
+ / metrics["total_executions"]
651
  )
 
652
 
653
+ async def _handle_stage_failure(self, stage: PipelineStage, context: Dict[str, Any], error: Exception):
654
+ """Handle stage failure with rollback and recovery options"""
655
+ self.logger.error(f"Handling failure in stage {stage.value}: {str(error)}")
656
+
657
+ # Record failure
658
+ self._record_stage_failure(stage, error)
659
+
660
+ # Determine if rollback is needed
661
+ if self._should_rollback(stage, error):
662
+ await self._execute_rollback(stage, context)
663
+
664
+ # Attempt recovery
665
+ await self._attempt_recovery(stage, context, error)
666
+
667
+ def _should_rollback(self, stage: PipelineStage, error: Exception) -> bool:
668
+ """Determine if a rollback is needed based on error severity"""
669
+ critical_errors = [
670
+ "DatabaseError",
671
+ "DeploymentError",
672
+ "SecurityViolation"
673
+ ]
674
+ return any(err in str(error) for err in critical_errors)
675
+
676
+ async def _execute_rollback(self, stage: PipelineStage, context: Dict[str, Any]):
677
+ """Execute rollback procedure for a failed stage"""
678
+ self.logger.info(f"Executing rollback for stage {stage.value}")
679
+
680
+ try:
681
+ # Get rollback point
682
+ rollback_point = self._get_rollback_point(stage)
683
+
684
+ # Execute rollback
685
+ await self.execute_stage(
686
+ self.PipelineStage.ROLLBACK,
687
+ {
688
+ **context,
689
+ "rollback_point": rollback_point,
690
+ "failed_stage": stage
691
+ }
692
+ )
693
+
694
+ except Exception as e:
695
+ self.logger.error(f"Rollback failed: {str(e)}")
696
+ # Implement emergency shutdown if rollback fails
697
+ self._emergency_shutdown(stage, e)
698
+
699
+ def _emergency_shutdown(self, stage: PipelineStage, error: Exception):
700
+ """Handle emergency shutdown when rollback fails"""
701
+ self.logger.critical(f"Emergency shutdown initiated for stage {stage.value}")
702
+ # Implement emergency shutdown procedures
703
+ pass
704
 
705
+ class RefinementLoop:
706
+ """Enhanced refinement loop for code quality assurance and continuous improvement"""
707
 
708
+ class RefinementState(Enum):
709
+ INITIALIZING = "initializing"
710
+ ANALYZING = "analyzing"
711
+ REFINING = "refining"
712
+ VALIDATING = "validating"
713
+ COMPLETED = "completed"
714
+ FAILED = "failed"
715
+
716
+ def __init__(self, pipeline: DevelopmentPipeline, max_iterations: int = 5):
717
+ self.pipeline = pipeline
718
+ self.max_iterations = max_iterations
719
+ self.current_iteration = 0
720
+ self.refinement_history: List[Dict[str, Any]] = []
721
+ self.quality_metrics = QualityMetrics()
722
+ self.error_tracker = ErrorTracker()
723
+ self.improvement_suggestions: List[str] = []
724
+ self.state = self.RefinementState.INITIALIZING
725
+ self.logger = self._setup_logger()
726
+ self.performance_monitor = self._setup_performance_monitor()
727
+ self.refinement_strategies = self._initialize_refinement_strategies()
728
+
729
+ def _setup_logger(self) -> logging.Logger:
730
+ """Set up enhanced logging with detailed formatting"""
731
+ logger = logging.getLogger("RefinementLoop")
732
+ logger.setLevel(logging.DEBUG)
733
+
734
+ # File handler for persistent logging
735
+ file_handler = logging.FileHandler("refinement_loop.log")
736
+ file_handler.setLevel(logging.DEBUG)
737
+
738
+ # Console handler for immediate feedback
739
+ console_handler = logging.StreamHandler()
740
+ console_handler.setLevel(logging.INFO)
741
+
742
+ # Create formatters and add them to the handlers
743
+ detailed_formatter = logging.Formatter(
744
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
745
+ )
746
+ simple_formatter = logging.Formatter(
747
+ '%(levelname)s: %(message)s'
748
+ )
749
+
750
+ file_handler.setFormatter(detailed_formatter)
751
+ console_handler.setFormatter(simple_formatter)
752
+
753
+ # Add handlers to logger
754
+ logger.addHandler(file_handler)
755
+ logger.addHandler(console_handler)
756
+
757
+ return logger
758
+
759
+ def _setup_performance_monitor(self):
760
+ """Initialize performance monitoring"""
761
+ return {
762
+ "start_time": None,
763
+ "end_time": None,
764
+ "iterations": [],
765
+ "memory_usage": [],
766
+ "cpu_usage": []
767
+ }
768
+
769
+ def _initialize_refinement_strategies(self) -> Dict[str, Any]:
770
+ """Initialize available refinement strategies"""
771
+ return {
772
+ "code_optimization": self._optimize_code,
773
+ "test_enhancement": self._enhance_tests,
774
+ "security_hardening": self._harden_security,
775
+ "performance_tuning": self._tune_performance,
776
+ "documentation_improvement": self._improve_documentation
777
+ }
778
+
779
+ async def run_refinement_cycle(self, project_name: str) -> Dict[str, Any]:
780
+ """Execute refinement cycle with enhanced error handling and monitoring"""
781
+ self.logger.info(f"Starting refinement cycle for project: {project_name}")
782
+ self.state = self.RefinementState.INITIALIZING
783
+ self.performance_monitor["start_time"] = time.time()
784
+
785
+ try:
786
+ while self.current_iteration < self.max_iterations:
787
+ self.logger.debug(f"Starting iteration {self.current_iteration + 1}")
788
+ iteration_start_time = time.time()
789
+
790
+ # Update state and analyze current state
791
+ self.state = self.RefinementState.ANALYZING
792
+ analysis = await self._analyze_current_state(project_name)
793
+
794
+ if analysis["meets_requirements"]:
795
+ self.logger.info("Quality requirements met")
796
+ break
797
+
798
+ # Apply refinements
799
+ self.state = self.RefinementState.REFINING
800
+ refinement_result = await self._apply_refinements(project_name, analysis)
801
+ self.refinement_history.append(refinement_result)
802
+
803
+ # Validate changes
804
+ self.state = self.RefinementState.VALIDATING
805
+ validation_result = await self._validate_changes(project_name)
806
+
807
+ if not validation_result["success"]:
808
+ self.logger.warning("Validation failed, initiating rollback")
809
+ await self._rollback_changes(project_name)
810
+ continue
811
+
812
+ # Update metrics and record performance
813
+ await self._update_metrics(validation_result)
814
+ self._record_iteration_performance(iteration_start_time)
815
+
816
+ self.current_iteration += 1
817
+
818
+ if await self._check_optimal_state():
819
+ self.logger.info("Optimal state reached")
820
+ break
821
+
822
+ # Prevent resource exhaustion
823
+ await asyncio.sleep(1)
824
+
825
+ self.state = self.RefinementState.COMPLETED
826
+ return await self._generate_final_report()
827
+
828
+ except Exception as e:
829
+ self.state = self.RefinementState.FAILED
830
+ self.logger.error(f"Error in refinement cycle: {str(e)}")
831
+ self.error_tracker.add_error("refinement_cycle", str(e))
832
+ return {
833
+ "success": False,
834
+ "error": str(e),
835
+ "error_details": traceback.format_exc()
836
+ }
837
+ finally:
838
+ self.performance_monitor["end_time"] = time.time()
839
+
840
+ async def _analyze_current_state(self, project_name: str) -> Dict[str, Any]:
841
+ """Analyze current project state with detailed metrics"""
842
  try:
843
+ # Collect code metrics
844
+ code_metrics = await self._collect_code_metrics(project_name)
845
+
846
+ # Analyze test coverage
847
+ test_coverage = await self._analyze_test_coverage(project_name)
848
+
849
+ # Check security vulnerabilities
850
+ security_analysis = await self._analyze_security(project_name)
851
+
852
+ # Measure performance metrics
853
+ performance_metrics = await self._measure_performance(project_name)
854
+
855
+ # Determine if requirements are met
856
+ meets_requirements = await self._check_requirements(
857
+ code_metrics,
858
+ test_coverage,
859
+ security_analysis,
860
+ performance_metrics
861
  )
862
+
863
+ return {
864
+ "code_metrics": code_metrics,
865
+ "test_coverage": test_coverage,
866
+ "security_analysis": security_analysis,
867
+ "performance_metrics": performance_metrics,
868
+ "meets_requirements": meets_requirements,
869
+ "timestamp": datetime.now()
870
+ }
871
+
872
  except Exception as e:
873
+ self.logger.error(f"Error analyzing current state: {str(e)}")
874
+ raise
875
 
876
+ async def _apply_refinements(self, project_name: str, analysis: Dict[str, Any]) -> Dict[str, Any]:
877
+ """Apply necessary refinements based on analysis"""
878
+ try:
879
+ refinements_applied = []
880
+
881
+ # Determine needed refinements
882
+ needed_refinements = await self._determine_needed_refinements(analysis)
883
+
884
+ # Apply each refinement strategy
885
+ for refinement_type, refinement_data in needed_refinements.items():
886
+ if refinement_type in self.refinement_strategies:
887
+ refinement_result = await self.refinement_strategies[refinement_type](
888
+ project_name,
889
+ refinement_data
890
+ )
891
+ refinements_applied.append(refinement_result)
892
+
893
+ return {
894
+ "refinements_applied": refinements_applied,
895
+ "timestamp": datetime.now()
896
+ }
897
+
898
+ except Exception as e:
899
+ self.logger.error(f"Error applying refinements: {str(e)}")
900
+ raise
901
 
902
+ async def _validate_changes(self, project_name: str) -> Dict[str, Any]:
903
+ """Validate applied changes with comprehensive testing"""
904
+ try:
905
+ # Run test suite
906
+ test_results = await self._run_test_suite(project_name)
907
+
908
+ # Validate code quality
909
+ quality_validation = await self._validate_code_quality(project_name)
910
+
911
+ # Check for regressions
912
+ regression_check = await self._check_for_regressions(project_name)
913
+
914
+ # Verify performance impact
915
+ performance_impact = await self._verify_performance_impact(project_name)
916
+
917
+ validation_success = all([
918
+ test_results["success"],
919
+ quality_validation["success"],
920
+ not regression_check["regressions_found"],
921
+ performance_impact["acceptable"]
922
+ ])
923
+
924
+ return {
925
+ "success": validation_success,
926
+ "test_results": test_results,
927
+ "quality_validation": quality_validation,
928
+ "regression_check": regression_check,
929
+ "performance_impact": performance_impact,
930
+ "timestamp": datetime.now()
931
+ }
932
+
933
+ except Exception as e:
934
+ self.logger.error(f"Error validating changes: {str(e)}")
935
+ raise
936
 
937
+ async def _optimize_code(self, project_name: str, optimization_data: Dict[str, Any]) -> Dict[str, Any]:
938
+ """Optimize code based on analysis results"""
939
+ try:
940
+ self.logger.info(f"Starting code optimization for {project_name}")
941
+ optimizations_applied = []
942
+
943
+ # Apply code optimizations
944
+ for file_path, file_data in optimization_data.items():
945
+ # Complexity reduction
946
+ if file_data.get("complexity_score", 0) > 0.7:
947
+ complexity_result = await self._reduce_complexity(file_path)
948
+ optimizations_applied.append({"type": "complexity", "result": complexity_result})
949
+
950
+ # Performance optimization
951
+ if file_data.get("performance_score", 0) < 0.8:
952
+ performance_result = await self._optimize_performance(file_path)
953
+ optimizations_applied.append({"type": "performance", "result": performance_result})
954
+
955
+ # Memory optimization
956
+ if file_data.get("memory_score", 0) < 0.8:
957
+ memory_result = await self._optimize_memory(file_path)
958
+ optimizations_applied.append({"type": "memory", "result": memory_result})
959
+
960
+ return {
961
+ "status": "success",
962
+ "optimizations_applied": optimizations_applied,
963
+ "timestamp": datetime.now()
964
+ }
965
+
966
+ except Exception as e:
967
+ self.logger.error(f"Error in code optimization: {str(e)}")
968
+ raise
969
 
970
+ async def _enhance_tests(self, project_name: str, test_data: Dict[str, Any]) -> Dict[str, Any]:
971
+ """Enhance test coverage and quality"""
972
+ try:
973
+ self.logger.info(f"Starting test enhancement for {project_name}")
974
+ enhancements_applied = []
975
+
976
+ # Generate missing tests
977
+ missing_tests = await self._identify_missing_tests(project_name)
978
+ if missing_tests:
979
+ generated_tests = await self._generate_tests(missing_tests)
980
+ enhancements_applied.append({"type": "new_tests", "tests": generated_tests})
981
+
982
+ # Improve existing tests
983
+ weak_tests = await self._identify_weak_tests(project_name)
984
+ if weak_tests:
985
+ improved_tests = await self._improve_test_quality(weak_tests)
986
+ enhancements_applied.append({"type": "improved_tests", "tests": improved_tests})
987
+
988
+ # Add property-based tests
989
+ property_tests = await self._generate_property_tests(project_name)
990
+ if property_tests:
991
+ enhancements_applied.append({"type": "property_tests", "tests": property_tests})
992
+
993
+ return {
994
+ "status": "success",
995
+ "enhancements_applied": enhancements_applied,
996
+ "timestamp": datetime.now()
997
+ }
998
+
999
+ except Exception as e:
1000
+ self.logger.error(f"Error in test enhancement: {str(e)}")
1001
+ raise
1002
 
1003
+ async def _harden_security(self, project_name: str, security_data: Dict[str, Any]) -> Dict[str, Any]:
1004
+ """Implement security improvements"""
1005
+ try:
1006
+ self.logger.info(f"Starting security hardening for {project_name}")
1007
+ security_improvements = []
1008
+
1009
+ # Fix security vulnerabilities
1010
+ vulnerabilities = await self._identify_vulnerabilities(project_name)
1011
+ if vulnerabilities:
1012
+ fixed_vulnerabilities = await self._fix_vulnerabilities(vulnerabilities)
1013
+ security_improvements.append({"type": "vulnerability_fixes", "fixes": fixed_vulnerabilities})
1014
+
1015
+ # Implement security best practices
1016
+ security_best_practices = await self._implement_security_practices(project_name)
1017
+ security_improvements.append({"type": "best_practices", "implementations": security_best_practices})
1018
+
1019
+ # Add security tests
1020
+ security_tests = await self._add_security_tests(project_name)
1021
+ security_improvements.append({"type": "security_tests", "tests": security_tests})
1022
+
1023
+ return {
1024
+ "status": "success",
1025
+ "security_improvements": security_improvements,
1026
+ "timestamp": datetime.now()
1027
+ }
1028
+
1029
+ except Exception as e:
1030
+ self.logger.error(f"Error in security hardening: {str(e)}")
1031
+ raise
1032
 
1033
+ async def _tune_performance(self, project_name: str, performance_data: Dict[str, Any]) -> Dict[str, Any]:
1034
+ """Tune application performance"""
1035
+ try:
1036
+ self.logger.info(f"Starting performance tuning for {project_name}")
1037
+ performance_improvements = []
1038
+
1039
+ # Optimize database queries
1040
+ if performance_data.get("database_issues"):
1041
+ query_optimizations = await self._optimize_database_queries(project_name)
1042
+ performance_improvements.append({"type": "database_optimization", "optimizations": query_optimizations})
1043
+
1044
+ # Optimize algorithms
1045
+ if performance_data.get("algorithm_issues"):
1046
+ algorithm_optimizations = await self._optimize_algorithms(project_name)
1047
+ performance_improvements.append({"type": "algorithm_optimization", "optimizations": algorithm_optimizations})
1048
+
1049
+ # Implement caching
1050
+ if performance_data.get("caching_recommended"):
1051
+ caching_implementations = await self._implement_caching(project_name)
1052
+ performance_improvements.append({"type": "caching", "implementations": caching_implementations})
1053
+
1054
+ return {
1055
+ "status": "success",
1056
+ "performance_improvements": performance_improvements,
1057
+ "timestamp": datetime.now()
1058
+ }
1059
+
1060
+ except Exception as e:
1061
+ self.logger.error(f"Error in performance tuning: {str(e)}")
1062
+ raise
1063
 
1064
+ async def _improve_documentation(self, project_name: str, doc_data: Dict[str, Any]) -> Dict[str, Any]:
1065
+ """Improve code documentation"""
1066
+ try:
1067
+ self.logger.info(f"Starting documentation improvement for {project_name}")
1068
+ documentation_improvements = []
1069
+
1070
+ # Generate missing docstrings
1071
+ missing_docs = await self._identify_missing_docs(project_name)
1072
+ if missing_docs:
1073
+ generated_docs = await self._generate_docstrings(missing_docs)
1074
+ documentation_improvements.append({"type": "docstrings", "docs": generated_docs})
1075
+
1076
+ # Update README
1077
+ readme_updates = await self._update_readme(project_name)
1078
+ documentation_improvements.append({"type": "readme", "updates": readme_updates})
1079
+
1080
+ # Generate API documentation
1081
+ api_docs = await self._generate_api_docs(project_name)
1082
+ documentation_improvements.append({"type": "api_docs", "docs": api_docs})
1083
+
1084
+ return {
1085
+ "status": "success",
1086
+ "documentation_improvements": documentation_improvements,
1087
+ "timestamp": datetime.now()
1088
+ }
1089
+
1090
+ except Exception as e:
1091
+ self.logger.error(f"Error in documentation improvement: {str(e)}")
1092
+ raise
1093
 
1094
+ async def _generate_final_report(self) -> Dict[str, Any]:
1095
+ """Generate comprehensive final report"""
1096
+ total_duration = self.performance_monitor["end_time"] - self.performance_monitor["start_time"]
1097
+
1098
+ return {
1099
+ "status": "success",
1100
+ "iterations_completed": self.current_iteration,
1101
+ "total_duration": total_duration,
1102
+ "refinement_history": self.refinement_history,
1103
+ "final_metrics": await self._get_final_metrics(),
1104
+ "performance_summary": self._get_performance_summary(),
1105
+ "improvement_suggestions": self.improvement_suggestions,
1106
+ "error_summary": self.error_tracker.get_error_analysis()
1107
+ }
1108
+
1109
+ def _get_performance_summary(self) -> Dict[str, Any]:
1110
+ """Generate performance summary"""
1111
+ return {
1112
+ "total_iterations": len(self.performance_monitor["iterations"]),
1113
+ "average_iteration_time": statistics.mean(self.performance_monitor["iterations"]),
1114
+ "memory_usage": {
1115
+ "average": statistics.mean(self.performance_monitor["memory_usage"]),
1116
+ "peak": max(self.performance_monitor["memory_usage"])
1117
+ },
1118
+ "cpu_usage": {
1119
+ "average": statistics.mean(self.performance_monitor["cpu_usage"]),
1120
+ "peak": max(self.performance_monitor["cpu_usage"])
1121
+ }
1122
+ }
1123
+
1124
+ async def _get_final_metrics(self) -> Dict[str, Any]:
1125
+ """Get final quality metrics"""
1126
+ return {
1127
+ "code_quality": self.quality_metrics.code_quality_score,
1128
+ "test_coverage": self.quality_metrics.test_coverage,
1129
+ "security_score": self.quality_metrics.security_score,
1130
+ "performance_score": self.quality_metrics.performance_score,
1131
+ "improvement_percentage": await self._calculate_improvement_percentage()
1132
+ }
1133
+
1134
+ async def _calculate_improvement_percentage(self) -> float:
1135
+ """Calculate overall improvement percentage"""
1136
+ if not self.refinement_history:
1137
+ return 0.0
1138
+
1139
+ initial_metrics = self.refinement_history[0].get("metrics", {})
1140
+ final_metrics = self.refinement_history[-1].get("metrics", {})
1141
+
1142
+ improvements = []
1143
+ for metric in ["code_quality", "test_coverage", "security_score", "performance_score"]:
1144
+ if metric in initial_metrics and metric in final_metrics:
1145
+ improvement = (final_metrics[metric] - initial_metrics[metric]) / initial_metrics[metric] * 100
1146
+ improvements.append(improvement)
1147
+
1148
+ return statistics.mean(improvements) if improvements else 0.0
1149
 
1150
+ class StreamlitInterface:
1151
+ """Streamlit UI integration for the RefinementLoop system"""
1152
+
1153
+ def __init__(self, refinement_loop: RefinementLoop):
1154
+ self.refinement_loop = refinement_loop
1155
+ self.session_state = self._initialize_session_state()
1156
+ self.theme = self._setup_theme()
1157
+ self.metrics_cache = {}
1158
+
1159
+ def _initialize_session_state(self) -> Dict[str, Any]:
1160
+ """Initialize Streamlit session state"""
1161
+ if 'project_history' not in st.session_state:
1162
+ st.session_state.project_history = []
1163
+ if 'current_project' not in st.session_state:
1164
+ st.session_state.current_project = None
1165
+ if 'refinement_status' not in st.session_state:
1166
+ st.session_state.refinement_status = None
1167
+ return st.session_state
1168
+
1169
+ def _setup_theme(self) -> Dict[str, Any]:
1170
+ """Setup custom theme for the interface"""
1171
+ return {
1172
+ 'primary_color': '#1f77b4',
1173
+ 'background_color': '#ffffff',
1174
+ 'secondary_background_color': '#f0f2f6',
1175
+ 'text_color': '#262730',
1176
+ 'font': 'sans serif'
1177
+ }
1178
+
1179
+ def render_main_interface(self):
1180
+ """Render the main Streamlit interface"""
1181
+ st.set_page_config(
1182
+ page_title="Code Refinement System",
1183
+ page_icon="🔄",
1184
+ layout="wide"
1185
+ )
1186
 
1187
+ st.title("Advanced Code Refinement System")
1188
+
1189
+ # Sidebar navigation
1190
+ self._render_sidebar()
1191
+
1192
+ # Main content area
1193
+ selected_tab = st.tabs(["Dashboard", "Project Analysis", "Refinement History", "Settings"])
1194
+
1195
+ with selected_tab[0]:
1196
+ self._render_dashboard()
1197
+
1198
+ with selected_tab[1]:
1199
+ self._render_project_analysis()
1200
+
1201
+ with selected_tab[2]:
1202
+ self._render_refinement_history()
1203
+
1204
+ with selected_tab[3]:
1205
+ self._render_settings()
1206
 
1207
+ def _render_sidebar(self):
1208
+ """Render sidebar with project controls"""
1209
+ with st.sidebar:
1210
+ st.header("Project Controls")
1211
+
1212
+ # Project selection/creation
1213
+ project_name = st.text_input("Project Name")
1214
+
1215
+ if st.button("Start New Refinement"):
1216
+ if project_name:
1217
+ self._start_new_refinement(project_name)
1218
+
1219
+ # Current project status
1220
+ if st.session_state.current_project:
1221
+ st.subheader("Current Project")
1222
+ st.info(f"Active: {st.session_state.current_project}")
1223
+
1224
+ if st.session_state.refinement_status:
1225
+ st.progress(self._calculate_progress())
1226
+
1227
+ # Quick actions
1228
+ st.subheader("Quick Actions")
1229
+ if st.button("Stop Refinement"):
1230
+ self._stop_refinement()
1231
+ if st.button("Export Report"):
1232
+ self._export_report()
1233
+
1234
+ def _render_dashboard(self):
1235
+ """Render main dashboard with key metrics"""
1236
+ col1, col2, col3 = st.columns(3)
1237
+
1238
+ with col1:
1239
+ self._render_quality_metrics()
1240
+
1241
+ with col2:
1242
+ self._render_performance_metrics()
1243
+
1244
+ with col3:
1245
+ self._render_security_metrics()
1246
+
1247
+ # Detailed charts
1248
+ self._render_trend_charts()
1249
+
1250
+ # Recent activity
1251
+ self._render_recent_activity()
1252
 
1253
+ def _render_quality_metrics(self):
1254
+ """Render code quality metrics"""
1255
+ st.subheader("Code Quality")
1256
+
1257
+ if self.metrics_cache.get('quality_metrics'):
1258
+ metrics = self.metrics_cache['quality_metrics']
1259
+
1260
+ # Display metrics with gauges
1261
+ col1, col2 = st.columns(2)
1262
+ with col1:
1263
+ self._render_gauge(
1264
+ "Code Quality Score",
1265
+ metrics['code_quality_score'],
1266
+ 0,
1267
+ 100,
1268
+ "Higher is better"
1269
+ )
1270
+ with col2:
1271
+ self._render_gauge(
1272
+ "Test Coverage",
1273
+ metrics['test_coverage'],
1274
+ 0,
1275
+ 100,
1276
+ "Target: 80%"
1277
+ )
1278
+
1279
+ # Show improvement suggestions
1280
+ if metrics.get('suggestions'):
1281
+ st.write("Improvement Suggestions:")
1282
+ for suggestion in metrics['suggestions']:
1283
+ st.info(suggestion)
1284
+
1285
+ def _render_performance_metrics(self):
1286
+ """Render performance metrics"""
1287
+ st.subheader("Performance Metrics")
1288
+
1289
+ if self.metrics_cache.get('performance_metrics'):
1290
+ metrics = self.metrics_cache['performance_metrics']
1291
+
1292
+ # Display key performance indicators
1293
+ cols = st.columns(3)
1294
+ with cols[0]:
1295
+ st.metric(
1296
+ "Response Time",
1297
+ f"{metrics['response_time']}ms",
1298
+ delta=metrics['response_time_change']
1299
+ )
1300
+ with cols[1]:
1301
+ st.metric(
1302
+ "Memory Usage",
1303
+ f"{metrics['memory_usage']}MB",
1304
+ delta=metrics['memory_usage_change']
1305
+ )
1306
+ with cols[2]:
1307
+ st.metric(
1308
+ "CPU Usage",
1309
+ f"{metrics['cpu_usage']}%",
1310
+ delta=metrics['cpu_usage_change']
1311
+ )
1312
+
1313
+ # Performance trend chart
1314
+ if metrics.get('history'):
1315
+ self._render_line_chart(
1316
+ "Performance Trend",
1317
+ metrics['history'],
1318
+ 'timestamp',
1319
+ 'response_time'
1320
+ )
1321
+
1322
+ def _render_security_metrics(self):
1323
+ """Render security metrics and vulnerabilities"""
1324
+ st.subheader("Security Analysis")
1325
+
1326
+ if self.metrics_cache.get('security_metrics'):
1327
+ metrics = self.metrics_cache['security_metrics']
1328
+
1329
+ # Security score
1330
+ st.metric(
1331
+ "Security Score",
1332
+ f"{metrics['security_score']}/100",
1333
+ delta=metrics['security_score_change']
1334
+ )
1335
+
1336
+ # Vulnerabilities
1337
+ if metrics.get('vulnerabilities'):
1338
+ st.write("Detected Vulnerabilities:")
1339
+ for vuln in metrics['vulnerabilities']:
1340
+ severity_color = {
1341
+ 'HIGH': 'red',
1342
+ 'MEDIUM': 'orange',
1343
+ 'LOW': 'yellow'
1344
+ }.get(vuln['severity'], 'grey')
1345
+
1346
+ st.markdown(
1347
+ f"<span style='color: {severity_color}'>"
1348
+ f"[{vuln['severity']}] {vuln['description']}"
1349
+ f"</span>",
1350
+ unsafe_allow_html=True
1351
+ )
1352
+
1353
+ async def _start_new_refinement(self, project_name: str):
1354
+ """Start a new refinement cycle"""
1355
+ try:
1356
+ st.session_state.current_project = project_name
1357
+ st.session_state.refinement_status = "running"
1358
+
1359
+ # Create progress placeholder
1360
+ progress_bar = st.progress(0)
1361
+ status_text = st.empty()
1362
+
1363
+ # Run refinement cycle
1364
+ result = await self.refinement_loop.run_refinement_cycle(project_name)
1365
+
1366
+ # Update session state with results
1367
+ st.session_state.project_history.append({
1368
+ "project_name": project_name,
1369
+ "timestamp": datetime.now(),
1370
+ "result": result
1371
+ })
1372
+
1373
+ # Update metrics cache
1374
+ self.metrics_cache = await self._fetch_latest_metrics(project_name)
1375
+
1376
+ st.session_state.refinement_status = "completed"
1377
+ status_text.success("Refinement completed successfully!")
1378
+
1379
+ except Exception as e:
1380
+ st.session_state.refinement_status = "failed"
1381
+ st.error(f"Refinement failed: {str(e)}")
1382
 
1383
+ def _render_trend_charts(self):
1384
+ """Render trend charts for various metrics"""
1385
+ st.subheader("Trend Analysis")
1386
+
1387
+ # Create tabs for different trend views
1388
+ trend_tabs = st.tabs(["Quality Trends", "Performance Trends", "Security Trends"])
1389
+
1390
+ with trend_tabs[0]:
1391
+ if self.metrics_cache.get('quality_history'):
1392
+ self._render_line_chart(
1393
+ "Code Quality Trend",
1394
+ self.metrics_cache['quality_history'],
1395
+ 'timestamp',
1396
+ 'quality_score'
1397
+ )
1398
+
1399
+ with trend_tabs[1]:
1400
+ if self.metrics_cache.get('performance_history'):
1401
+ self._render_line_chart(
1402
+ "Performance Trend",
1403
+ self.metrics_cache['performance_history'],
1404
+ 'timestamp',
1405
+ 'response_time'
1406
+ )
1407
+
1408
+ with trend_tabs[2]:
1409
+ if self.metrics_cache.get('security_history'):
1410
+ self._render_line_chart(
1411
+ "Security Score Trend",
1412
+ self.metrics_cache['security_history'],
1413
+ 'timestamp',
1414
+ 'security_score'
1415
+ )
1416
+
1417
+ def _render_recent_activity(self):
1418
+ """Render recent activity log"""
1419
+ st.subheader("Recent Activity")
1420
+
1421
+ if st.session_state.project_history:
1422
+ for activity in reversed(st.session_state.project_history[-5:]):
1423
+ with st.expander(
1424
+ f"{activity['project_name']} - {activity['timestamp'].strftime('%Y-%m-%d %H:%M:%S')}"
1425
+ ):
1426
+ st.json(activity['result'])
1427
+
1428
+ async def _fetch_latest_metrics(self, project_name: str) -> Dict[str, Any]:
1429
+ """Fetch latest metrics for the project"""
1430
+ try:
1431
+ # Get quality metrics
1432
+ quality_metrics = await self.refinement_loop.quality_metrics.analyze_code(project_name)
1433
+
1434
+ # Get performance metrics
1435
+ performance_metrics = await self._get_performance_metrics(project_name)
1436
+
1437
+ # Get security metrics
1438
+ security_metrics = await self._get_security_metrics(project_name)
1439
+
1440
+ return {
1441
+ 'quality_metrics': quality_metrics,
1442
+ 'performance_metrics': performance_metrics,
1443
+ 'security_metrics': security_metrics,
1444
+ 'last_updated': datetime.now()
1445
+ }
1446
+
1447
+ except Exception as e:
1448
+ st.error(f"Error fetching metrics: {str(e)}")
1449
+ return {}
1450
 
1451
+ def _calculate_progress(self) -> float:
1452
+ """Calculate current refinement progress"""
1453
+ if not st.session_state.refinement_status:
1454
+ return 0.0
1455
+
1456
+ if st.session_state.refinement_status == "completed":
1457
+ return 1.0
1458
+
1459
+ current_iteration = self.refinement_loop.current_iteration
1460
+ max_iterations = self.refinement_loop.max_iterations
1461
+
1462
+ return current_iteration / max_iterations
1463
+
1464
+ @staticmethod
1465
+ def _render_gauge(title: str, value: float, min_value: float, max_value: float, help_text: str):
1466
+ """Render a gauge chart"""
1467
+ fig = go.Figure(go.Indicator(
1468
+ mode="gauge+number",
1469
+ value=value,
1470
+ domain={'x': [0, 1], 'y': [0, 1]},
1471
+ title={'text': title},
1472
+ gauge={
1473
+ 'axis': {'range': [min_value, max_value]},
1474
+ 'bar': {'color': "darkblue"},
1475
+ 'steps': [
1476
+ {'range': [min_value, max_value * 0.6], 'color': "red"},
1477
+ {'range': [max_value * 0.6, max_value * 0.8], 'color': "yellow"},
1478
+ {'range': [max_value * 0.8, max_value], 'color': "green"}
1479
+ ]
1480
+ }
1481
  ))
1482
+
1483
+ st.plotly_chart(fig, use_container_width=True, help=help_text)
1484
+
1485
+ @staticmethod
1486
+ def _render_line_chart(title: str, data: List[Dict[str, Any]], x_key: str, y_key: str):
1487
+ """Render a line chart"""
1488
+ df = pd.DataFrame(data)
1489
+ fig = px.line(df, x=x_key, y=y_key, title=title)
1490
+ st.plotly_chart(fig, use_container_width=True)
1491
+
1492
+ class CodeRefinementApp:
1493
+ """Main application class for the Code Refinement System"""
1494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1495
  def __init__(self):
1496
+ self.config = self._load_config()
1497
+ self.pipeline = self._initialize_pipeline()
1498
+ self.refinement_loop = self._initialize_refinement_loop()
1499
+ self.interface = StreamlitInterface(self.refinement_loop)
1500
+
1501
+ def _load_config(self) -> Dict[str, Any]:
1502
+ """Load application configuration"""
1503
+ return {
1504
+ 'app_name': 'Code Refinement System',
1505
+ 'version': '1.0.0',
1506
+ 'max_iterations': int(os.getenv('MAX_ITERATIONS', 5)),
1507
+ 'workspace_dir': os.getenv('WORKSPACE_DIR', './workspace'),
1508
+ 'model_config': {
1509
+ 'model_name': os.getenv('LLM_MODEL', 'gemini/gemini-1.5-pro'),
1510
+ 'api_key': os.getenv('GEMINI_API_KEY'),
1511
+ 'temperature': float(os.getenv('MODEL_TEMPERATURE', 0.7)),
1512
+ 'max_tokens': int(os.getenv('MAX_TOKENS', 2000))
1513
+ },
1514
+ 'performance': {
1515
+ 'cache_enabled': bool(os.getenv('ENABLE_CACHE', True)),
1516
+ 'max_concurrent_tasks': int(os.getenv('MAX_CONCURRENT_TASKS', 3)),
1517
+ 'timeout': int(os.getenv('OPERATION_TIMEOUT', 300))
1518
+ },
1519
+ 'security': {
1520
+ 'enable_vulnerability_scan': bool(os.getenv('ENABLE_VULNERABILITY_SCAN', True)),
1521
+ 'max_file_size_mb': int(os.getenv('MAX_FILE_SIZE_MB', 10))
1522
+ }
1523
+ }
1524
+
1525
+ def _initialize_pipeline(self) -> DevelopmentPipeline:
1526
+ """Initialize the development pipeline"""
1527
+ try:
1528
+ workspace_path = Path(self.config['workspace_dir'])
1529
+ workspace_path.mkdir(parents=True, exist_ok=True)
1530
+
1531
+ return DevelopmentPipeline(
1532
+ workspace_manager=self._setup_workspace_manager(),
1533
+ tool_manager=self._setup_tool_manager()
 
 
 
 
1534
  )
1535
+ except Exception as e:
1536
+ logger.error(f"Failed to initialize pipeline: {str(e)}")
1537
+ raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1538
 
1539
+ def _initialize_refinement_loop(self) -> RefinementLoop:
1540
+ """Initialize the refinement loop"""
1541
+ try:
1542
+ return RefinementLoop(
1543
+ pipeline=self.pipeline,
1544
+ max_iterations=self.config['max_iterations']
1545
+ )
1546
+ except Exception as e:
1547
+ logger.error(f"Failed to initialize refinement loop: {str(e)}")
1548
+ raise
1549
 
1550
+ def _setup_workspace_manager(self):
1551
+ """Setup workspace manager with configuration"""
1552
+ from workspace_manager import WorkspaceManager
1553
+
1554
+ return WorkspaceManager(
1555
+ base_path=self.config['workspace_dir'],
1556
+ max_file_size=self.config['security']['max_file_size_mb'] * 1024 * 1024
1557
+ )
1558
 
1559
+ def _setup_tool_manager(self):
1560
+ """Setup tool manager with configuration"""
1561
+ from tool_manager import ToolManager
1562
+
1563
+ return ToolManager(
1564
+ model_config=self.config['model_config'],
1565
+ max_concurrent=self.config['performance']['max_concurrent_tasks'],
1566
+ timeout=self.config['performance']['timeout']
1567
  )
1568
 
1569
+ async def _setup_async_components(self):
1570
+ """Setup async components and background tasks"""
1571
+ try:
1572
+ # Initialize cache if enabled
1573
+ if self.config['performance']['cache_enabled']:
1574
+ await self._initialize_cache()
1575
 
1576
+ # Setup background tasks
1577
+ asyncio.create_task(self._monitor_system_health())
1578
+ asyncio.create_task(self._cleanup_old_workspaces())
1579
+
1580
+ except Exception as e:
1581
+ logger.error(f"Failed to setup async components: {str(e)}")
1582
+ raise
 
 
 
1583
 
1584
+ async def _initialize_cache(self):
1585
+ """Initialize caching system"""
1586
+ try:
1587
+ from caching import CacheManager
1588
+
1589
+ cache_manager = CacheManager()
1590
+ await cache_manager.initialize()
1591
+ return cache_manager
1592
+ except Exception as e:
1593
+ logger.warning(f"Cache initialization failed: {str(e)}")
1594
+ return None
1595
+
1596
+ async def _monitor_system_health(self):
1597
+ """Monitor system health in background"""
1598
+ while True:
1599
+ try:
1600
+ # Check system resources
1601
+ memory_usage = self._check_memory_usage()
1602
+ cpu_usage = self._check_cpu_usage()
1603
+ disk_usage = self._check_disk_usage()
1604
+
1605
+ # Log metrics
1606
+ logger.info(
1607
+ f"System Health - Memory: {memory_usage}%, "
1608
+ f"CPU: {cpu_usage}%, "
1609
+ f"Disk: {disk_usage}%"
1610
+ )
1611
+
1612
+ # Alert if thresholds exceeded
1613
+ self._check_resource_thresholds(memory_usage, cpu_usage, disk_usage)
1614
+
1615
+ await asyncio.sleep(300) # Check every 5 minutes
1616
+
1617
+ except Exception as e:
1618
+ logger.error(f"Health monitoring error: {str(e)}")
1619
+ await asyncio.sleep(60) # Retry after 1 minute
1620
+
1621
+ async def _cleanup_old_workspaces(self):
1622
+ """Cleanup old workspace directories"""
1623
+ while True:
1624
+ try:
1625
+ workspace_path = Path(self.config['workspace_dir'])
1626
+ current_time = datetime.now()
1627
+
1628
+ for item in workspace_path.glob("*"):
1629
+ if item.is_dir():
1630
+ # Check if directory is older than 7 days
1631
+ age = current_time - datetime.fromtimestamp(item.stat().st_mtime)
1632
+ if age.days > 7:
1633
+ logger.info(f"Cleaning up old workspace: {item}")
1634
+ self._safe_remove_directory(item)
1635
+
1636
+ await asyncio.sleep(86400) # Run daily
1637
+
1638
+ except Exception as e:
1639
+ logger.error(f"Workspace cleanup error: {str(e)}")
1640
+ await asyncio.sleep(3600) # Retry after 1 hour
1641
+
1642
+ def run(self):
1643
+ """Main application entry point"""
1644
+ try:
1645
+ logger.info(f"Starting {self.config['app_name']} v{self.config['version']}")
1646
+
1647
+ # Setup async components
1648
+ asyncio.run(self._setup_async_components())
1649
+
1650
+ # Launch Streamlit interface
1651
+ self.interface.render_main_interface()
1652
+
1653
+ except Exception as e:
1654
+ logger.error(f"Application error: {str(e)}")
1655
+ st.error("An error occurred while starting the application. Please check the logs.")
1656
+ raise
1657
 
1658
+ def main():
1659
+ """Application entry point"""
1660
+ try:
1661
+ # Enable wide mode
1662
+ st.set_page_config(
1663
+ page_title="Code Refinement System",
1664
+ page_icon="🔄",
1665
+ layout="wide",
1666
+ initial_sidebar_state="expanded"
1667
+ )
1668
+
1669
+ # Initialize and run application
1670
+ app = CodeRefinementApp()
1671
+ app.run()
1672
+
1673
+ except Exception as e:
1674
+ st.error(f"Failed to start application: {str(e)}")
1675
+ logger.critical(f"Application failed to start: {str(e)}", exc_info=True)
1676
+ sys.exit(1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1677
 
1678
  if __name__ == "__main__":
1679
  main()