Add apps modules and improve captain_claude logging
- Add apps/ directory with modular components: - captain.py: Main orchestrator - corp/, deck/, devops/, docker/, hst/: Domain-specific apps - Fix duplicate logger handlers in long sessions - Add flush=True to print statements for real-time output Note: flow-ui, mindlink, tzzr-cli are separate repos (not included) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,11 @@ class CaptainClaude:
|
||||
self.cost_tracker = CostTracker()
|
||||
logger = logging.getLogger("captain-claude")
|
||||
logger.setLevel(logging.INFO)
|
||||
# Evitar handlers duplicados en sesiones largas
|
||||
if not logger.handlers:
|
||||
handler = logging.StreamHandler()
|
||||
handler.setFormatter(logging.Formatter('%(message)s'))
|
||||
logger.addHandler(handler)
|
||||
self.logger = StructuredLogger(logger)
|
||||
self.output_dir = Path(output_dir) if output_dir else Path.cwd() / "captain_output"
|
||||
self.output_dir.mkdir(exist_ok=True)
|
||||
@@ -244,33 +249,33 @@ Continue and complete this work."""
|
||||
"""Execute a task using intelligent agent orchestration."""
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print("CAPTAIN CLAUDE by dadiaar")
|
||||
print(f"{'='*60}")
|
||||
print(f"Task: {task[:100]}...")
|
||||
print(f"{'='*60}\n")
|
||||
print(f"\n{'='*60}", flush=True)
|
||||
print("CAPTAIN CLAUDE by dadiaar", flush=True)
|
||||
print(f"{'='*60}", flush=True)
|
||||
print(f"Task: {task[:100]}...", flush=True)
|
||||
print(f"{'='*60}\n", flush=True)
|
||||
|
||||
# Phase 1: Analyze task
|
||||
print("[Captain] Analyzing task...")
|
||||
print("[Captain] Analyzing task...", flush=True)
|
||||
plan = await self.analyze_task(task)
|
||||
print(f"[Captain] Plan created: {len(plan.get('steps', []))} steps")
|
||||
print(f"[Captain] Plan created: {len(plan.get('steps', []))} steps", flush=True)
|
||||
|
||||
# Phase 2: Execute plan
|
||||
results = []
|
||||
if plan.get("parallel_possible") and len(plan.get("agents_needed", [])) > 1:
|
||||
print("[Captain] Executing agents in parallel...")
|
||||
print("[Captain] Executing agents in parallel...", flush=True)
|
||||
parallel_result = await self.run_parallel(
|
||||
task,
|
||||
plan.get("agents_needed", ["coder"])
|
||||
)
|
||||
results.append(parallel_result)
|
||||
else:
|
||||
print("[Captain] Executing agents sequentially...")
|
||||
print("[Captain] Executing agents sequentially...", flush=True)
|
||||
sequential_results = await self.run_sequential(plan.get("steps", []))
|
||||
results.extend(sequential_results)
|
||||
|
||||
# Phase 3: Synthesize results
|
||||
print("[Captain] Synthesizing results...")
|
||||
print("[Captain] Synthesizing results...", flush=True)
|
||||
synthesis_prompt = f"""Synthesize these results into a coherent final output:
|
||||
|
||||
Original task: {task}
|
||||
@@ -298,12 +303,12 @@ Provide a clear, actionable final result."""
|
||||
with open(output_file, "w") as f:
|
||||
json.dump(final_result, f, indent=2, default=str)
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print("EXECUTION COMPLETE")
|
||||
print(f"{'='*60}")
|
||||
print(f"Output saved: {output_file}")
|
||||
print(f"Cost: {self.cost_tracker.summary()}")
|
||||
print(f"{'='*60}\n")
|
||||
print(f"\n{'='*60}", flush=True)
|
||||
print("EXECUTION COMPLETE", flush=True)
|
||||
print(f"{'='*60}", flush=True)
|
||||
print(f"Output saved: {output_file}", flush=True)
|
||||
print(f"Cost: {self.cost_tracker.summary()}", flush=True)
|
||||
print(f"{'='*60}\n", flush=True)
|
||||
|
||||
return final_result
|
||||
|
||||
@@ -322,18 +327,18 @@ async def main():
|
||||
"""Interactive Captain Claude session."""
|
||||
captain = CaptainClaude()
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("CAPTAIN CLAUDE by dadiaar")
|
||||
print("Multi-Agent Orchestration System")
|
||||
print("="*60)
|
||||
print("\nCommands:")
|
||||
print(" /execute <task> - Full multi-agent execution")
|
||||
print(" /chat <message> - Chat with Captain")
|
||||
print(" /agent <name> <message> - Chat with specific agent")
|
||||
print(" /parallel <task> - Run all agents in parallel")
|
||||
print(" /cost - Show cost summary")
|
||||
print(" /quit - Exit")
|
||||
print("="*60 + "\n")
|
||||
print("\n" + "="*60, flush=True)
|
||||
print("CAPTAIN CLAUDE by dadiaar", flush=True)
|
||||
print("Multi-Agent Orchestration System", flush=True)
|
||||
print("="*60, flush=True)
|
||||
print("\nCommands:", flush=True)
|
||||
print(" /execute <task> - Full multi-agent execution", flush=True)
|
||||
print(" /chat <message> - Chat with Captain", flush=True)
|
||||
print(" /agent <name> <message> - Chat with specific agent", flush=True)
|
||||
print(" /parallel <task> - Run all agents in parallel", flush=True)
|
||||
print(" /cost - Show cost summary", flush=True)
|
||||
print(" /quit - Exit", flush=True)
|
||||
print("="*60 + "\n", flush=True)
|
||||
|
||||
while True:
|
||||
try:
|
||||
@@ -343,24 +348,24 @@ async def main():
|
||||
continue
|
||||
|
||||
if user_input.lower() == "/quit":
|
||||
print("Goodbye!")
|
||||
print("Goodbye!", flush=True)
|
||||
break
|
||||
|
||||
if user_input.lower() == "/cost":
|
||||
print(f"Cost: {captain.cost_tracker.summary()}")
|
||||
print(f"Cost: {captain.cost_tracker.summary()}", flush=True)
|
||||
continue
|
||||
|
||||
if user_input.startswith("/execute "):
|
||||
task = user_input[9:]
|
||||
result = await captain.execute(task)
|
||||
print(f"\nFinal Output:\n{result['final_output']}\n")
|
||||
print(f"\nFinal Output:\n{result['final_output']}\n", flush=True)
|
||||
continue
|
||||
|
||||
if user_input.startswith("/parallel "):
|
||||
task = user_input[10:]
|
||||
agents = ["coder", "reviewer", "researcher"]
|
||||
result = await captain.run_parallel(task, agents)
|
||||
print(f"\nParallel Results:\n{result}\n")
|
||||
print(f"\nParallel Results:\n{result}\n", flush=True)
|
||||
continue
|
||||
|
||||
if user_input.startswith("/agent "):
|
||||
@@ -368,24 +373,24 @@ async def main():
|
||||
if len(parts) == 2:
|
||||
agent, message = parts
|
||||
response = await captain.chat(message, agent)
|
||||
print(f"\n[{agent}]: {response}\n")
|
||||
print(f"\n[{agent}]: {response}\n", flush=True)
|
||||
else:
|
||||
print("Usage: /agent <name> <message>")
|
||||
print("Usage: /agent <name> <message>", flush=True)
|
||||
continue
|
||||
|
||||
if user_input.startswith("/chat ") or not user_input.startswith("/"):
|
||||
message = user_input[6:] if user_input.startswith("/chat ") else user_input
|
||||
response = await captain.chat(message)
|
||||
print(f"\n[Captain]: {response}\n")
|
||||
print(f"\n[Captain]: {response}\n", flush=True)
|
||||
continue
|
||||
|
||||
print("Unknown command. Use /quit to exit.")
|
||||
print("Unknown command. Use /quit to exit.", flush=True)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nGoodbye!")
|
||||
print("\nGoodbye!", flush=True)
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
print(f"Error: {e}", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user