Spaces:
Running
Running
perf: all Claude Code calls use Skills (/fix-cain, /fix-loop)
Browse filesStatic instructions now live in .claude/commands/ as custom slash commands:
- /fix-cain: worker skill for Cain tasks (rules, Dockerfile/FastAPI, speed)
- /fix-loop: God skill for fixing conversation-loop.py (commit convention, rules)
Prompts only pass dynamic content (task description or diagnosis).
Claude Code caches skill instructions, reducing per-call token usage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- scripts/conversation-loop.py +60 -19
scripts/conversation-loop.py
CHANGED
|
@@ -564,6 +564,60 @@ Always use: git commit -m "god: <brief description>"
|
|
| 564 |
except Exception as e:
|
| 565 |
print(f"[CLAUDE.md] Failed to write: {e}")
|
| 566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 567 |
|
| 568 |
def _reset_workspace(workspace, repo_url):
|
| 569 |
"""Reset workspace to latest origin/main, preserving .claude/ and .acpx/ directories."""
|
|
@@ -715,10 +769,12 @@ def action_claude_code(task):
|
|
| 715 |
"CI": "true",
|
| 716 |
})
|
| 717 |
|
| 718 |
-
|
|
|
|
|
|
|
| 719 |
try:
|
| 720 |
proc = subprocess.Popen(
|
| 721 |
-
["acpx", "claude",
|
| 722 |
cwd=CLAUDE_WORK_DIR,
|
| 723 |
env=env,
|
| 724 |
stdout=subprocess.PIPE,
|
|
@@ -2424,23 +2480,8 @@ def do_god_turn():
|
|
| 2424 |
except Exception as e:
|
| 2425 |
print(f"[God] Warning: Could not write context file: {e}")
|
| 2426 |
|
| 2427 |
-
#
|
| 2428 |
-
prompt = f"
|
| 2429 |
-
{diagnosis}
|
| 2430 |
-
|
| 2431 |
-
## Current System State
|
| 2432 |
-
{context}
|
| 2433 |
-
|
| 2434 |
-
## Task
|
| 2435 |
-
The diagnosis above identified a problem with the orchestration mechanism.
|
| 2436 |
-
Fix it in scripts/conversation-loop.py. Be specific and minimal.
|
| 2437 |
-
|
| 2438 |
-
1. Read scripts/conversation-loop.py
|
| 2439 |
-
2. Fix the specific issue identified in the diagnosis
|
| 2440 |
-
3. Commit with "god: <description>" and push
|
| 2441 |
-
4. End with:
|
| 2442 |
-
[PROBLEM] <what the problem was>
|
| 2443 |
-
[FIX] <what you changed to fix it>"""
|
| 2444 |
|
| 2445 |
# Set up env for Claude Code
|
| 2446 |
env = os.environ.copy()
|
|
|
|
| 564 |
except Exception as e:
|
| 565 |
print(f"[CLAUDE.md] Failed to write: {e}")
|
| 566 |
|
| 567 |
+
# Write custom slash commands (Skills) — static instructions cached by Claude Code
|
| 568 |
+
# Saves tokens: prompt only passes the dynamic task, static rules live in the skill file
|
| 569 |
+
cmd_dir = f"{workspace}/.claude/commands"
|
| 570 |
+
os.makedirs(cmd_dir, exist_ok=True)
|
| 571 |
+
try:
|
| 572 |
+
if role == "worker":
|
| 573 |
+
with open(f"{cmd_dir}/fix-cain.md", "w") as f:
|
| 574 |
+
f.write(f"""# /fix-cain — Fix or improve {CHILD_NAME}'s Space
|
| 575 |
+
|
| 576 |
+
## Input
|
| 577 |
+
$ARGUMENTS — The specific task to complete
|
| 578 |
+
|
| 579 |
+
## Instructions
|
| 580 |
+
1. Read the relevant files in the workspace (this is {CHILD_NAME}'s Space repo)
|
| 581 |
+
2. Complete the task described in $ARGUMENTS
|
| 582 |
+
3. Validate Python syntax before writing .py files
|
| 583 |
+
4. Push changes when done: git add -A && git commit -m "Claude Code: <brief>" && git push
|
| 584 |
+
|
| 585 |
+
## Rules
|
| 586 |
+
- All Spaces use sdk: docker — do NOT use Gradio (no gr.Interface, no .launch())
|
| 587 |
+
- Use FastAPI + uvicorn for web server, bind to port 7860
|
| 588 |
+
- NEVER install torch/transformers (2GB+, causes OOM on free tier)
|
| 589 |
+
- Push within 60-90 seconds — trial-and-error > deliberation
|
| 590 |
+
- If unsure, pick a reasonable fix and push — see what breaks
|
| 591 |
+
- Space ID: {CHILD_SPACE_ID}
|
| 592 |
+
- Dataset ID: {CHILD_DATASET_ID}
|
| 593 |
+
""")
|
| 594 |
+
elif role == "god":
|
| 595 |
+
with open(f"{cmd_dir}/fix-loop.md", "w") as f:
|
| 596 |
+
f.write("""# /fix-loop — Fix conversation-loop.py orchestration issues
|
| 597 |
+
|
| 598 |
+
## Input
|
| 599 |
+
$ARGUMENTS — The specific diagnosis/problem to fix
|
| 600 |
+
|
| 601 |
+
## Instructions
|
| 602 |
+
1. Read scripts/conversation-loop.py
|
| 603 |
+
2. Fix the specific issue described in $ARGUMENTS
|
| 604 |
+
3. Validate: python3 -c "import py_compile; py_compile.compile('scripts/conversation-loop.py', doraise=True)"
|
| 605 |
+
4. Commit: git commit -m "god: <brief description>"
|
| 606 |
+
5. Push: git push
|
| 607 |
+
6. End output with:
|
| 608 |
+
[PROBLEM] <what the problem was>
|
| 609 |
+
[FIX] <what you changed>
|
| 610 |
+
|
| 611 |
+
## Rules
|
| 612 |
+
- ONLY modify scripts/conversation-loop.py
|
| 613 |
+
- Only push fixes for real problems, not cosmetic changes
|
| 614 |
+
- Pushing triggers a Space restart — be confident the fix is correct
|
| 615 |
+
- Minimal changes — fix exactly what's broken
|
| 616 |
+
- Trial-and-error is GOOD — push frequently, fail fast
|
| 617 |
+
""")
|
| 618 |
+
except Exception as e:
|
| 619 |
+
print(f"[SKILLS] Failed to write commands: {e}")
|
| 620 |
+
|
| 621 |
|
| 622 |
def _reset_workspace(workspace, repo_url):
|
| 623 |
"""Reset workspace to latest origin/main, preserving .claude/ and .acpx/ directories."""
|
|
|
|
| 769 |
"CI": "true",
|
| 770 |
})
|
| 771 |
|
| 772 |
+
# Use /fix-cain skill: static instructions in .claude/commands/, only task is dynamic
|
| 773 |
+
skill_prompt = f"/fix-cain {task}"
|
| 774 |
+
print(f"[ACP/CLAUDE] Running via skill: {task[:200]}...")
|
| 775 |
try:
|
| 776 |
proc = subprocess.Popen(
|
| 777 |
+
["acpx", "claude", skill_prompt],
|
| 778 |
cwd=CLAUDE_WORK_DIR,
|
| 779 |
env=env,
|
| 780 |
stdout=subprocess.PIPE,
|
|
|
|
| 2480 |
except Exception as e:
|
| 2481 |
print(f"[God] Warning: Could not write context file: {e}")
|
| 2482 |
|
| 2483 |
+
# Use /fix-loop skill: static instructions in .claude/commands/, only diagnosis is dynamic
|
| 2484 |
+
prompt = f"/fix-loop {diagnosis}\n\nSystem state:\n{context}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2485 |
|
| 2486 |
# Set up env for Claude Code
|
| 2487 |
env = os.environ.copy()
|