tao-shen Claude Opus 4.6 commited on
Commit
8a21cd0
·
1 Parent(s): ddef022

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>

Files changed (1) hide show
  1. 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
- result = subprocess.run(
356
  ["claude", "-p", task, "--output-format", "text"],
357
  cwd=CLAUDE_WORK_DIR,
358
  env=env,
359
- timeout=CLAUDE_TIMEOUT,
360
- capture_output=True,
361
  text=True,
 
362
  )
363
- output = (result.stdout or "") + (result.stderr or "")
 
 
 
 
 
 
 
 
 
 
 
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)")