Skip to content

Commit 17d70f0

Browse files
authored
Merge pull request #10 from study-basic-hackathon/feat/retry-agent
feat: 修正失敗時のリトライを追加
2 parents d4ec0bd + e77a20d commit 17d70f0

2 files changed

Lines changed: 113 additions & 2 deletions

File tree

.dockerignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Node.js
2+
frontend/node_modules/
3+
**/node_modules/
4+
npm-debug.log*
5+
yarn-debug.log*
6+
7+
# Python
8+
**/__pycache__/
9+
*.py[cod]
10+
backend/.venv/
11+
backend/.mypy_cache/
12+
backend/.ruff_cache/
13+
backend/.pytest_cache/
14+
15+
# Git
16+
.git/
17+
18+
# IDE
19+
.vscode/
20+
.idea/
21+
22+
# OS
23+
.DS_Store
24+
Thumbs.db
25+
26+
# Temporary / build artifacts
27+
tmp/
28+
*.log
29+
.cache/
30+
dist/
31+
build/
32+
33+
# K8s configs (not needed in image)
34+
k8s/
35+
36+
# Environment files
37+
.env
38+
.env.*

docker/worker-implement.py

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,47 @@ async def _process_messages(client: ClaudeSDKClient, phase: str) -> None:
186186
_emit_tool_detail(phase, block.name, json.dumps(block.input))
187187

188188

189+
async def kill_dev_servers(repo_dir: str) -> None:
190+
"""Kill any lingering dev server processes (node, vite, next, etc.)."""
191+
for pattern in ["node", "vite", "next"]:
192+
subprocess.run(
193+
["pkill", "-f", pattern],
194+
capture_output=True,
195+
)
196+
# Give processes time to terminate
197+
await asyncio.sleep(2)
198+
199+
200+
async def fix_with_claude(repo_dir: str, error_message: str) -> None:
201+
"""Use Claude to diagnose and fix the dev server launch failure."""
202+
options = ClaudeAgentOptions(
203+
allowed_tools=["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
204+
cwd=repo_dir,
205+
max_turns=20,
206+
max_budget_usd=1.5,
207+
include_partial_messages=True,
208+
)
209+
210+
async with ClaudeSDKClient(options=options) as client:
211+
await client.query(f"""The dev server failed to start in the project at {repo_dir}.
212+
213+
Here is the error output:
214+
215+
```
216+
{error_message}
217+
```
218+
219+
Please diagnose and fix the issue. Common causes include:
220+
- Missing or incorrect dependencies (run `npm install` or similar)
221+
- Build errors in the source code (syntax errors, import errors, type errors)
222+
- Port conflicts (change the port configuration)
223+
- Missing environment variables or config files
224+
225+
Fix the code so the dev server can start successfully. Make minimal, targeted changes.
226+
""")
227+
await _process_messages(client, "implementing")
228+
229+
189230
async def launch_and_screenshot(repo_dir: str, screenshot_output: str) -> None:
190231
"""Launch dev server and take screenshot in a single session.
191232
@@ -228,6 +269,13 @@ async def launch_and_screenshot(repo_dir: str, screenshot_output: str) -> None:
228269
""")
229270
await _process_messages(client, "screenshot")
230271

272+
# Verify screenshot was actually created
273+
if not Path(screenshot_output).exists():
274+
raise RuntimeError(
275+
f"Screenshot was not created at {screenshot_output}. "
276+
"The dev server likely failed to start or the screenshot command failed."
277+
)
278+
231279

232280
async def main() -> None:
233281
# Read environment variables
@@ -320,8 +368,33 @@ async def main() -> None:
320368
emit_log("implementing", "Implementing design proposal")
321369
await implement_changes(repo_dir, proposal_plan)
322370

323-
# Launch + screenshot in a single session (shares dev server URL context)
324-
await launch_and_screenshot(repo_dir, screenshot_path)
371+
# Launch + screenshot with retry loop
372+
max_retries = 2 # up to 3 total attempts
373+
last_error = None
374+
for attempt in range(max_retries + 1):
375+
try:
376+
await launch_and_screenshot(repo_dir, screenshot_path)
377+
last_error = None
378+
break # success
379+
except Exception as e:
380+
last_error = str(e)
381+
if attempt < max_retries:
382+
emit_log(
383+
"implementing",
384+
f"Dev server launch failed (attempt {attempt + 1}/{max_retries + 1}), attempting fix...",
385+
detail=last_error,
386+
)
387+
await kill_dev_servers(repo_dir)
388+
await fix_with_claude(repo_dir, last_error)
389+
else:
390+
emit_log(
391+
"implementing",
392+
f"Dev server launch failed after {max_retries + 1} attempts, proceeding without screenshot",
393+
detail=last_error,
394+
)
395+
396+
if last_error:
397+
emit_log("implementing", "WARNING: Could not launch dev server, screenshot may be missing")
325398

326399
# Step 4: Generate cumulative patch (squash everything since base_branch)
327400
emit_log("uploading", "Generating cumulative patch")

0 commit comments

Comments
 (0)