PYAE1994 commited on
Commit
a0bbd7b
·
verified ·
1 Parent(s): 69ac2d7

Fix: update agents/coding_agent.py

Browse files
Files changed (1) hide show
  1. agents/coding_agent.py +161 -33
agents/coding_agent.py CHANGED
@@ -1,29 +1,32 @@
1
  """
2
- CodingAgent — Autonomous code generation via LLMRouter
3
- Writes files, runs code in sandbox
4
  """
5
  import json
 
 
 
6
  import structlog
7
- from typing import Dict
8
  from .base_agent import BaseAgent
9
 
10
  log = structlog.get_logger()
11
 
12
- CODING_SYSTEM = """You are an elite software engineer. Write production-quality, complete, working code.
13
- - Include all imports
14
- - Handle errors properly
15
- - Add concise comments
16
- - Follow best practices for the language/framework
17
- When asked to create a file, output ONLY the file content — no explanation unless asked."""
 
18
 
19
- CODE_TEMPLATE = """Task: {task}
 
 
 
 
 
20
 
21
- Requirements:
22
- - Write complete, production-ready code
23
- - Include all necessary imports and error handling
24
- - Add brief comments explaining key parts
25
-
26
- Provide the complete implementation."""
27
 
28
 
29
  class CodingAgent(BaseAgent):
@@ -31,33 +34,158 @@ class CodingAgent(BaseAgent):
31
  super().__init__("CodingAgent", ws_manager, ai_router)
32
 
33
  async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
34
- session_id = kwargs.get("session_id", context.get("session_id", ""))
35
- task_id = kwargs.get("task_id", context.get("task_id", ""))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  messages = [
38
- {"role": "system", "content": CODING_SYSTEM},
39
- {"role": "user", "content": CODE_TEMPLATE.format(task=task)},
40
  ]
41
 
42
- await self.emit(task_id, "coding_started", {"task": task[:100]}, session_id)
 
 
 
 
43
 
44
- result = await self.ask_llm(
45
- messages=messages,
46
  task_id=task_id,
47
  session_id=session_id,
48
- temperature=0.3,
49
  max_tokens=8192,
50
  )
51
 
52
- await self.emit(task_id, "coding_completed", {
53
- "task": task[:80],
54
- "length": len(result),
 
 
 
 
55
  }, session_id)
56
 
57
- # Optionally write to sandbox
58
- sandbox = context.get("sandbox_agent")
59
- filename = context.get("filename")
60
- if sandbox and filename and result:
61
- await sandbox.write_file(filename, result, task_id=task_id, session_id=session_id)
62
-
63
  return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
+ CodingAgent — Autonomous code generation, editing, refactoring (Devin/Genspark style)
 
3
  """
4
  import json
5
+ import os
6
+ import re
7
+ from typing import Dict, List
8
  import structlog
 
9
  from .base_agent import BaseAgent
10
 
11
  log = structlog.get_logger()
12
 
13
+ CODING_SYSTEM = """You are an elite autonomous software engineer like Devin combined with Genspark.
14
+ You write production-quality code that is:
15
+ - Clean, readable, well-structured
16
+ - Properly typed (TypeScript/Python type hints)
17
+ - Error-handled and resilient
18
+ - Documented with clear comments
19
+ - Following best practices for the language/framework
20
 
21
+ When generating code:
22
+ 1. Think about the full architecture first
23
+ 2. Write complete, runnable code (not snippets)
24
+ 3. Include proper imports
25
+ 4. Add error handling
26
+ 5. Include brief usage examples in comments
27
 
28
+ Support: Python, TypeScript, JavaScript, Go, Rust, SQL, Shell, YAML, JSON
29
+ """
 
 
 
 
30
 
31
 
32
  class CodingAgent(BaseAgent):
 
34
  super().__init__("CodingAgent", ws_manager, ai_router)
35
 
36
  async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
37
+ session_id = kwargs.get("session_id", "")
38
+ task_id = kwargs.get("task_id", "")
39
+
40
+ await self.emit(task_id, "agent_start", {
41
+ "agent": "CodingAgent",
42
+ "task": task[:80],
43
+ }, session_id)
44
+
45
+ # Build context-aware messages
46
+ prev_results = context.get("previous_results", [])
47
+ project_ctx = context.get("project_context", "")
48
+ plan = context.get("plan", "")
49
+
50
+ system_content = CODING_SYSTEM
51
+ if project_ctx:
52
+ system_content += f"\n\nProject Context:\n{project_ctx[:1000]}"
53
+
54
+ user_content = f"Task: {task}"
55
+ if plan:
56
+ user_content += f"\n\nExecution Plan:\n{plan[:500]}"
57
+ if prev_results:
58
+ user_content += f"\n\nPrevious results:\n" + "\n".join(str(r)[:200] for r in prev_results[-3:])
59
 
60
  messages = [
61
+ {"role": "system", "content": system_content},
62
+ {"role": "user", "content": user_content},
63
  ]
64
 
65
+ await self.emit(task_id, "tool_called", {
66
+ "agent": "CodingAgent",
67
+ "tool": "code_generation",
68
+ "step": task[:60],
69
+ }, session_id)
70
 
71
+ result = await self.llm(
72
+ messages,
73
  task_id=task_id,
74
  session_id=session_id,
75
+ temperature=0.2,
76
  max_tokens=8192,
77
  )
78
 
79
+ # Extract code blocks for display
80
+ code_blocks = self._extract_code_blocks(result)
81
+ await self.emit(task_id, "code_generated", {
82
+ "agent": "CodingAgent",
83
+ "code_blocks": len(code_blocks),
84
+ "total_lines": sum(len(b.split("\n")) for b in code_blocks),
85
+ "languages": list(set(self._detect_language(b) for b in code_blocks)),
86
  }, session_id)
87
 
 
 
 
 
 
 
88
  return result
89
+
90
+ async def generate_file(
91
+ self,
92
+ filename: str,
93
+ description: str,
94
+ task_id: str = "",
95
+ session_id: str = "",
96
+ context: Dict = {},
97
+ ) -> str:
98
+ """Generate a complete file with proper structure."""
99
+ messages = [
100
+ {"role": "system", "content": CODING_SYSTEM},
101
+ {"role": "user", "content": (
102
+ f"Generate a complete, production-ready file.\n"
103
+ f"Filename: {filename}\n"
104
+ f"Description: {description}\n"
105
+ f"Context: {json.dumps(context)[:500]}\n\n"
106
+ f"Return ONLY the file content, no explanation."
107
+ )},
108
+ ]
109
+ content = await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.1, max_tokens=8192)
110
+
111
+ # Strip markdown code fences if present
112
+ content = self._strip_code_fences(content)
113
+
114
+ # Write to workspace
115
+ workspace = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
116
+ filepath = os.path.join(workspace, filename)
117
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
118
+ with open(filepath, "w") as f:
119
+ f.write(content)
120
+
121
+ await self.emit(task_id, "file_written", {
122
+ "filename": filename,
123
+ "size": len(content),
124
+ "lines": len(content.split("\n")),
125
+ }, session_id)
126
+
127
+ return content
128
+
129
+ async def refactor(
130
+ self,
131
+ code: str,
132
+ instructions: str,
133
+ task_id: str = "",
134
+ session_id: str = "",
135
+ ) -> str:
136
+ """Refactor existing code based on instructions."""
137
+ messages = [
138
+ {"role": "system", "content": CODING_SYSTEM},
139
+ {"role": "user", "content": (
140
+ f"Refactor this code based on these instructions:\n"
141
+ f"Instructions: {instructions}\n\n"
142
+ f"Original code:\n```\n{code}\n```\n\n"
143
+ f"Return ONLY the refactored code."
144
+ )},
145
+ ]
146
+ return await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.1, max_tokens=8192)
147
+
148
+ async def scan_repository(self, repo_path: str) -> Dict:
149
+ """Scan repository and build project intelligence graph."""
150
+ import subprocess
151
+ try:
152
+ result = subprocess.run(
153
+ ["find", repo_path, "-type", "f", "-name", "*.py", "-o",
154
+ "-name", "*.ts", "-o", "-name", "*.js", "-o", "-name", "*.go"],
155
+ capture_output=True, text=True, timeout=10
156
+ )
157
+ files = result.stdout.strip().split("\n")[:50]
158
+
159
+ # Read key files
160
+ key_files = {}
161
+ for f in ["package.json", "requirements.txt", "tsconfig.json", "pyproject.toml", "go.mod"]:
162
+ path = os.path.join(repo_path, f)
163
+ if os.path.exists(path):
164
+ with open(path) as fp:
165
+ key_files[f] = fp.read()[:1000]
166
+
167
+ return {
168
+ "files": files,
169
+ "key_configs": key_files,
170
+ "total_files": len(files),
171
+ }
172
+ except Exception as e:
173
+ return {"error": str(e), "files": [], "key_configs": {}}
174
+
175
+ def _extract_code_blocks(self, text: str) -> List[str]:
176
+ pattern = r"```[\w]*\n(.*?)```"
177
+ return re.findall(pattern, text, re.DOTALL)
178
+
179
+ def _strip_code_fences(self, text: str) -> str:
180
+ text = re.sub(r"^```[\w]*\n", "", text.strip())
181
+ text = re.sub(r"\n```$", "", text)
182
+ return text
183
+
184
+ def _detect_language(self, code: str) -> str:
185
+ if "def " in code and "import " in code:
186
+ return "python"
187
+ if "function " in code or "const " in code or "interface " in code:
188
+ return "typescript"
189
+ if "package main" in code:
190
+ return "go"
191
+ return "unknown"