Skip to content

Commit e39ce97

Browse files
committed
style: fix ruff formatting in new v3 swarm and utility files
1 parent 5bc578b commit e39ce97

3 files changed

Lines changed: 31 additions & 50 deletions

File tree

devguardian/agents/swarm.py

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,32 @@ def _get_llm(temperature: float = 0.2) -> ChatGoogleGenerativeAI:
4242
# Nodes
4343
# ---------------------------------------------------------------------------
4444

45+
4546
def load_context(state: SwarmState) -> SwarmState:
4647
"""Initialize project DNA and Semantic Memory."""
4748
dna = build_project_context(state["project_path"])
4849
mem = ProjectMemory(state["project_path"])
49-
50+
5051
return {
5152
**state,
5253
"project_dna": dna,
5354
"memory_context": mem.get_context_string(),
5455
"iteration_count": 1,
5556
"reviewer_feedback": "",
56-
"messages": state.get("messages", [])
57+
"messages": state.get("messages", []),
5758
}
5859

5960

6061
def coder_agent(state: SwarmState) -> SwarmState:
6162
"""Writes code, considering memory and previous reviewer rejections."""
6263
llm = _get_llm(temperature=0.3)
63-
64+
6465
# Pillar 1: Adversarial Loop
6566
is_fix = len(state["reviewer_feedback"]) > 0
6667
mode_instruction = (
6768
f"FIX the following code based on reviewer feedback:\n{state['reviewer_feedback']}"
68-
if is_fix else "Write the implementation from scratch."
69+
if is_fix
70+
else "Write the implementation from scratch."
6971
)
7072

7173
system = SystemMessage(
@@ -88,21 +90,22 @@ def coder_agent(state: SwarmState) -> SwarmState:
8890

8991
response: AIMessage = llm.invoke([system, user])
9092
code = response.content.strip()
91-
93+
9294
if "```" in code:
9395
code = "\n".join([l for l in code.splitlines() if not l.strip().startswith("```")]).strip()
9496

9597
return {
9698
**state,
9799
"code_draft": code,
98-
"messages": state.get("messages", []) + [HumanMessage(content=f"[Coder produced draft v{state['iteration_count']}]")]
100+
"messages": state.get("messages", [])
101+
+ [HumanMessage(content=f"[Coder produced draft v{state['iteration_count']}]")],
99102
}
100103

101104

102105
def tester_agent(state: SwarmState) -> SwarmState:
103106
"""Audits code and RUNS it in a sandbox to catch real crashes."""
104107
llm = _get_llm(temperature=0.4)
105-
108+
106109
# Pillar 3: Sandbox Execution
107110
execution_result = verify_code_logic(state["code_draft"])
108111

@@ -125,7 +128,7 @@ def tester_agent(state: SwarmState) -> SwarmState:
125128
return {
126129
**state,
127130
"test_report": f"### Sandbox Result\n{execution_result}\n\n### Audit Notes\n{response.content.strip()}",
128-
"messages": state.get("messages", []) + [HumanMessage(content="[Tester produced report]")]
131+
"messages": state.get("messages", []) + [HumanMessage(content="[Tester produced report]")],
129132
}
130133

131134

@@ -147,21 +150,21 @@ def reviewer_agent(state: SwarmState) -> SwarmState:
147150
f"## Task\n{state['task']}\n\n"
148151
f"## Draft Code\n```python\n{state['code_draft']}\n```\n\n"
149152
f"## Tester Feedback\n{state['test_report']}\n\n"
150-
"Decide: Is this production-ready? (Iteration: " + str(state['iteration_count']) + ")"
153+
"Decide: Is this production-ready? (Iteration: " + str(state["iteration_count"]) + ")"
151154
)
152155
)
153156

154157
response: AIMessage = llm.invoke([system, user])
155158
verdict_text = response.content.strip()
156-
159+
157160
is_rejected = "REJECT" in verdict_text.upper() and state["iteration_count"] < 3
158161

159162
return {
160163
**state,
161164
"reviewer_feedback": verdict_text if is_rejected else "",
162165
"final_verdict": verdict_text,
163166
"iteration_count": state["iteration_count"] + 1,
164-
"messages": state.get("messages", []) + [HumanMessage(content="[Reviewer verdict]")]
167+
"messages": state.get("messages", []) + [HumanMessage(content="[Reviewer verdict]")],
165168
}
166169

167170

@@ -172,12 +175,12 @@ def router(state: SwarmState) -> Literal["coder", "end"]:
172175
"""Determines if we should loop back or finish."""
173176
if state["reviewer_feedback"] and state["iteration_count"] <= 3:
174177
return "coder"
175-
178+
176179
# Update Semantic Memory on success
177180
if "ACCEPTED" in state["final_verdict"].upper():
178181
mem = ProjectMemory(state["project_path"])
179182
mem.add_lesson(state["task"], "Code passed sandbox and adversarial review.")
180-
183+
181184
return "end"
182185

183186

@@ -196,27 +199,15 @@ def create_swarm_graph():
196199
workflow.add_edge("load_context", "coder")
197200
workflow.add_edge("coder", "tester")
198201
workflow.add_edge("tester", "reviewer")
199-
200-
workflow.add_conditional_edges(
201-
"reviewer",
202-
router,
203-
{
204-
"coder": "coder",
205-
"end": END
206-
}
207-
)
202+
203+
workflow.add_conditional_edges("reviewer", router, {"coder": "coder", "end": END})
208204

209205
return workflow.compile()
210206

211207

212208
async def run_swarm(task: str, project_path: str) -> str:
213209
graph = create_swarm_graph()
214-
result = await graph.ainvoke({
215-
"task": task,
216-
"project_path": project_path,
217-
"messages": [],
218-
"iteration_count": 0
219-
})
210+
result = await graph.ainvoke({"task": task, "project_path": project_path, "messages": [], "iteration_count": 0})
220211

221212
return (
222213
f"# 🤖 DevGuardian v3 Swarm Report\n\n"

devguardian/utils/executor.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,41 @@
99
import tempfile
1010
from pathlib import Path
1111

12+
1213
def execute_python_snippet(code: str, timeout: int = 5) -> dict:
1314
"""
1415
Executes a Python snippet and returns the result/errors.
1516
"""
16-
with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode='w', encoding='utf-8') as tmp:
17+
with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode="w", encoding="utf-8") as tmp:
1718
tmp.write(code)
1819
tmp_path = Path(tmp.name)
1920

2021
try:
2122
# Run with current python executable
2223
result = subprocess.run(
23-
[sys.executable, str(tmp_path)],
24-
capture_output=True,
25-
text=True,
26-
timeout=timeout,
27-
stdin=subprocess.DEVNULL
24+
[sys.executable, str(tmp_path)], capture_output=True, text=True, timeout=timeout, stdin=subprocess.DEVNULL
2825
)
29-
26+
3027
return {
3128
"success": result.returncode == 0,
3229
"stdout": result.stdout[:2000],
3330
"stderr": result.stderr[:2000],
34-
"exit_code": result.returncode
31+
"exit_code": result.returncode,
3532
}
3633
except subprocess.TimeoutExpired:
3734
return {
3835
"success": False,
3936
"stdout": "",
4037
"stderr": f"Execution timed out after {timeout} seconds.",
41-
"exit_code": -1
38+
"exit_code": -1,
4239
}
4340
except Exception as e:
44-
return {
45-
"success": False,
46-
"stdout": "",
47-
"stderr": str(e),
48-
"exit_code": -1
49-
}
41+
return {"success": False, "stdout": "", "stderr": str(e), "exit_code": -1}
5042
finally:
5143
if tmp_path.exists():
5244
tmp_path.unlink()
5345

46+
5447
def verify_code_logic(code: str) -> str:
5548
"""
5649
Higher-level check: tries to compile and run the code.

devguardian/utils/memory.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pathlib import Path
1010
from datetime import datetime
1111

12+
1213
class ProjectMemory:
1314
def __init__(self, project_path: str):
1415
self.root = Path(project_path)
@@ -34,11 +35,7 @@ def add_preference(self, pref: str):
3435

3536
def add_lesson(self, task: str, finding: str):
3637
"""Record a lesson learned from a specific task."""
37-
self.data["lessons"].append({
38-
"timestamp": datetime.now().isoformat(),
39-
"task": task,
40-
"finding": finding
41-
})
38+
self.data["lessons"].append({"timestamp": datetime.now().isoformat(), "task": task, "finding": finding})
4239
# Keep only last 10 lessons to prevent context bloat
4340
self.data["lessons"] = self.data["lessons"][-10:]
4441
self.save()
@@ -48,10 +45,10 @@ def get_context_string(self) -> str:
4845
parts = []
4946
if self.data["preferences"]:
5047
parts.append("### User Preferences\n- " + "\n- ".join(self.data["preferences"]))
51-
48+
5249
if self.data["lessons"]:
5350
parts.append("### Recent Lessons Learned")
5451
for l in self.data["lessons"]:
5552
parts.append(f"- Task: {l['task']}\n Lesson: {l['finding']}")
56-
53+
5754
return "\n\n".join(parts) if parts else "No specific project memory yet."

0 commit comments

Comments
 (0)