Skip to content

Commit 49fa419

Browse files
committed
Updates to agent
1 parent b81ee98 commit 49fa419

3 files changed

Lines changed: 32 additions & 13 deletions

File tree

ensemble_agent/agent.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ async def run_agent(config: AgentConfig):
3232
# Set up archive manager
3333
archive = ArchiveManager(config.output_dir)
3434

35-
# Load skills
36-
skills = load_skills(config.skills, config, archive)
35+
# Load skills — drop generator when using existing scripts
36+
skill_names = config.skills
37+
if config.scripts_dir and "generator" in skill_names:
38+
skill_names = ",".join(s for s in skill_names.split(",") if s.strip() != "generator")
39+
skills = load_skills(skill_names, config, archive)
3740
has_generator = any(isinstance(s, GeneratorSkill) for s in skills)
3841

3942
# MCP setup for generator skill

ensemble_agent/skills/file_ops.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""File operations skill — read, write, list files in the work directory."""
22

3+
import difflib
34
from pathlib import Path
45

56
from pydantic import BaseModel, Field
@@ -36,10 +37,24 @@ async def read_file_tool(filepath: str) -> str:
3637

3738
async def write_file_tool(filepath: str, content: str) -> str:
3839
try:
39-
(work_dir / filepath).write_text(content)
40+
file_path = work_dir / filepath
41+
# Diff against old content for summary
42+
old_lines = file_path.read_text().splitlines() if file_path.exists() else []
43+
new_lines = content.splitlines()
44+
changes = list(difflib.unified_diff(old_lines, new_lines, n=0))
45+
changed = [l for l in changes if l.startswith('+') and not l.startswith('+++')]
46+
47+
file_path.write_text(content)
4048
archive.start("fix")
4149
archive.archive_scripts()
42-
print(f"- Saved: {work_dir / filepath}", flush=True)
50+
51+
if changed and len(changed) <= 3:
52+
summary = "; ".join(l[1:].strip() for l in changed)
53+
print(f"- Fixed: {filepath} ({summary})", flush=True)
54+
elif changed:
55+
print(f"- Fixed: {filepath} ({len(changed)} lines changed)", flush=True)
56+
else:
57+
print(f"- Saved: {filepath}", flush=True)
4358
return f"SUCCESS: Wrote {filepath}"
4459
except Exception as e:
4560
return f"ERROR: {e}"

ensemble_agent/skills/runner.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from langchain_core.tools import StructuredTool
77

88
from .base import Skill
9-
from ..config import MAX_RETRIES
109

1110

1211
class RunScriptInput(BaseModel):
@@ -19,7 +18,8 @@ class RunnerSkill(Skill):
1918
def __init__(self, config, archive):
2019
super().__init__(config, archive)
2120
self._run_count = 0
22-
self._max_runs = config.max_retries + 1 # initial run + retries
21+
self._max_runs = config.max_retries + 1
22+
self._succeeded = False
2323

2424
def get_tools(self):
2525
work_dir = self.archive.work_dir
@@ -28,17 +28,17 @@ def get_tools(self):
2828
skill = self
2929

3030
async def run_script_tool(script_name: str) -> str:
31+
if skill._succeeded:
32+
return "Script already ran successfully. Do not run again."
3133
skill._run_count += 1
3234
if skill._run_count > skill._max_runs:
33-
msg = f"RUN LIMIT REACHED ({skill._max_runs} runs). Stop and report the current status to the user."
34-
print(f"\n{msg}", flush=True)
35-
return msg
35+
return "Run limit reached. Stop and report current status."
3636

3737
script_path = work_dir / script_name
3838
if not script_path.exists():
3939
return f"ERROR: Script '{script_name}' not found"
4040

41-
print(f"\nRunning {script_name}... (run {skill._run_count}/{skill._max_runs})", flush=True)
41+
print(f"\nRunning {script_name}...", flush=True)
4242
try:
4343
result = subprocess.run(
4444
["python", script_name],
@@ -48,6 +48,7 @@ async def run_script_tool(script_name: str) -> str:
4848
timeout=timeout,
4949
)
5050
if result.returncode == 0:
51+
skill._succeeded = True
5152
print("Script ran successfully", flush=True)
5253
return f"SUCCESS\nOutput:\n{result.stdout[:500]}"
5354
else:
@@ -57,13 +58,13 @@ async def run_script_tool(script_name: str) -> str:
5758
f"Stdout: {result.stdout}"
5859
)
5960
print(f"Failed (code {result.returncode})", flush=True)
61+
if result.stderr:
62+
print(f"Error output:\n{result.stderr[:500]}", flush=True)
6063
archive.archive_run_output(error_msg)
61-
remaining = skill._max_runs - skill._run_count
6264
return (
6365
f"FAILED (code {result.returncode})\n"
6466
f"Stderr:\n{result.stderr}\n"
65-
f"Stdout:\n{result.stdout[:500]}\n"
66-
f"\nYou have {remaining} run(s) remaining."
67+
f"Stdout:\n{result.stdout[:500]}"
6768
)
6869
except subprocess.TimeoutExpired:
6970
return f"ERROR: Script timed out ({timeout}s)"

0 commit comments

Comments
 (0)