Spaces:
Running
Running
feat: stream Claude Code output to conv-loop log with [CC] prefix
Browse files- Replace subprocess.run(capture_output) with Popen streaming, so each
line of Claude Code output appears in real-time with [CC] prefix
- Add [CC-RESULT] summary (800 chars) after each claude_code action
- Both opening turn and do_turn() now log CC results
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- scripts/conversation-loop.py +24 -6
scripts/conversation-loop.py
CHANGED
|
@@ -352,23 +352,34 @@ def action_claude_code(task):
|
|
| 352 |
|
| 353 |
print(f"[CLAUDE-CODE] Running: {task[:200]}...")
|
| 354 |
try:
|
| 355 |
-
|
| 356 |
["claude", "-p", task, "--output-format", "text"],
|
| 357 |
cwd=CLAUDE_WORK_DIR,
|
| 358 |
env=env,
|
| 359 |
-
|
| 360 |
-
|
| 361 |
text=True,
|
|
|
|
| 362 |
)
|
| 363 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
if not output.strip():
|
| 365 |
output = "(no output)"
|
| 366 |
-
except subprocess.TimeoutExpired:
|
| 367 |
-
return "Claude Code timed out after 5 minutes."
|
| 368 |
except FileNotFoundError:
|
| 369 |
return "Claude Code CLI not found. Is @anthropic-ai/claude-code installed?"
|
| 370 |
except Exception as e:
|
| 371 |
return f"Claude Code failed: {e}"
|
|
|
|
| 372 |
|
| 373 |
# 3. Push changes back to Cain's Space
|
| 374 |
try:
|
|
@@ -814,6 +825,9 @@ if reply:
|
|
| 814 |
print(f"[Adam/ZH] {zh}")
|
| 815 |
for ar in actions:
|
| 816 |
print(f"[Adam/DID] {ar['action']}")
|
|
|
|
|
|
|
|
|
|
| 817 |
entry = {"speaker": "Adam", "text": en, "text_zh": zh}
|
| 818 |
if actions:
|
| 819 |
labels = " ".join(f"🔧{ar['action'].split(':')[0]}" for ar in actions)
|
|
@@ -855,6 +869,10 @@ def do_turn(speaker, other, space_url):
|
|
| 855 |
if action_results:
|
| 856 |
for ar in action_results:
|
| 857 |
print(f"[{speaker}/DID] {ar['action']}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 858 |
print(f"[{speaker}] Turn #{turn_count}: {len(action_results)} action(s) in {elapsed:.1f}s")
|
| 859 |
else:
|
| 860 |
print(f"[{speaker}] Turn #{turn_count}: discussion only ({elapsed:.1f}s)")
|
|
|
|
| 352 |
|
| 353 |
print(f"[CLAUDE-CODE] Running: {task[:200]}...")
|
| 354 |
try:
|
| 355 |
+
proc = subprocess.Popen(
|
| 356 |
["claude", "-p", task, "--output-format", "text"],
|
| 357 |
cwd=CLAUDE_WORK_DIR,
|
| 358 |
env=env,
|
| 359 |
+
stdout=subprocess.PIPE,
|
| 360 |
+
stderr=subprocess.STDOUT,
|
| 361 |
text=True,
|
| 362 |
+
bufsize=1,
|
| 363 |
)
|
| 364 |
+
output_lines = []
|
| 365 |
+
deadline = time.time() + CLAUDE_TIMEOUT
|
| 366 |
+
for line in proc.stdout:
|
| 367 |
+
line = line.rstrip('\n')
|
| 368 |
+
print(f" [CC] {line}")
|
| 369 |
+
output_lines.append(line)
|
| 370 |
+
if time.time() > deadline:
|
| 371 |
+
proc.kill()
|
| 372 |
+
output_lines.append("(killed: timeout)")
|
| 373 |
+
break
|
| 374 |
+
proc.wait(timeout=10)
|
| 375 |
+
output = '\n'.join(output_lines)
|
| 376 |
if not output.strip():
|
| 377 |
output = "(no output)"
|
|
|
|
|
|
|
| 378 |
except FileNotFoundError:
|
| 379 |
return "Claude Code CLI not found. Is @anthropic-ai/claude-code installed?"
|
| 380 |
except Exception as e:
|
| 381 |
return f"Claude Code failed: {e}"
|
| 382 |
+
print(f"[CLAUDE-CODE] Done ({len(output)} chars, exit={proc.returncode})")
|
| 383 |
|
| 384 |
# 3. Push changes back to Cain's Space
|
| 385 |
try:
|
|
|
|
| 825 |
print(f"[Adam/ZH] {zh}")
|
| 826 |
for ar in actions:
|
| 827 |
print(f"[Adam/DID] {ar['action']}")
|
| 828 |
+
if ar['action'] == 'claude_code':
|
| 829 |
+
result_preview = ar['result'][:800].replace('\n', '\n ')
|
| 830 |
+
print(f" [CC-RESULT] {result_preview}")
|
| 831 |
entry = {"speaker": "Adam", "text": en, "text_zh": zh}
|
| 832 |
if actions:
|
| 833 |
labels = " ".join(f"🔧{ar['action'].split(':')[0]}" for ar in actions)
|
|
|
|
| 869 |
if action_results:
|
| 870 |
for ar in action_results:
|
| 871 |
print(f"[{speaker}/DID] {ar['action']}")
|
| 872 |
+
# Log Claude Code result summary so agents can see what happened
|
| 873 |
+
if ar['action'] == 'claude_code':
|
| 874 |
+
result_preview = ar['result'][:800].replace('\n', '\n ')
|
| 875 |
+
print(f" [CC-RESULT] {result_preview}")
|
| 876 |
print(f"[{speaker}] Turn #{turn_count}: {len(action_results)} action(s) in {elapsed:.1f}s")
|
| 877 |
else:
|
| 878 |
print(f"[{speaker}] Turn #{turn_count}: discussion only ({elapsed:.1f}s)")
|