772ef4f6fd
- Autonomous agent runtime (JSONL + fcntl locking, no token caps) - Moltbook-style prompts: agents share what they built, not scripted turns - Episodes 001-008 transcripts, conversation logs, system prompts - Producer brief for Hermes v0.18
111 lines
4.0 KiB
Python
111 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Run Show — orchestrates two autonomous agents in a conversation.
|
|
Agents take turns reading the shared conversation log and posting responses.
|
|
No scripting — just two agents talking to each other.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
from agent import Agent
|
|
|
|
# ── Config ──────────────────────────────────────────────────────────
|
|
MAX_TURNS = 8 # safety ceiling, not a rigid target
|
|
PROJECT_DIR = Path(__file__).parent.parent
|
|
OUTPUT_DIR = PROJECT_DIR / "outputs"
|
|
|
|
def load_topic_brief(episode_id: str) -> str:
|
|
"""Load the raw topic material for this episode."""
|
|
brief_path = PROJECT_DIR / "prompts" / f"producer_brief_{episode_id}.md"
|
|
if brief_path.exists():
|
|
return brief_path.read_text().strip()
|
|
# Fallback: generic Hermes v0.18 brief
|
|
return """
|
|
Hermes Agent v0.18 "Judgment Release"
|
|
|
|
What's New:
|
|
- Mixture of Agents — combine multiple AI models for stronger builds
|
|
- /goal command — step-by-step plans with beginning, middle, end
|
|
- /learn command — teach Hermes from a link, saved to Obsidian vault
|
|
- /journey command — timeline of everything learned, editable
|
|
- Background fan-out — parallel sub-agents without blocking chat
|
|
- Goal-mode with judge agent — verifies completion, not just claims
|
|
""".strip()
|
|
|
|
def run_show(episode_id: str, topic: str):
|
|
"""Run the autonomous agent conversation."""
|
|
print(f"=== Agent AI Talk Show — Episode {episode_id} ===\n", flush=True)
|
|
|
|
# Load topic brief
|
|
topic_brief = load_topic_brief(episode_id)
|
|
|
|
# Create conversation log
|
|
conv_path = OUTPUT_DIR / f"ep{episode_id}_{topic}_conversation.json"
|
|
conv_path.write_text(json.dumps({"messages": []}, indent=2))
|
|
|
|
# Initialize agents
|
|
leonard = Agent("Leonard", conv_path, topic_brief)
|
|
charlie = Agent("Charlie", conv_path, topic_brief)
|
|
|
|
# Run conversation
|
|
turn = 0
|
|
agents = [leonard, charlie]
|
|
|
|
while turn < MAX_TURNS:
|
|
# Alternate agents: Leonard opens, then Charlie, then back and forth
|
|
if turn == 0:
|
|
agent = leonard
|
|
elif turn % 2 == 1:
|
|
agent = charlie
|
|
else:
|
|
agent = leonard
|
|
|
|
print(f"\n--- Turn {turn+1}/{MAX_TURNS}: {agent.name} ---", flush=True)
|
|
result = agent.speak()
|
|
|
|
turn += 1
|
|
if turn < MAX_TURNS:
|
|
time.sleep(1) # Brief pause between turns
|
|
|
|
# ── Save final transcript ─────────────────────────────────────
|
|
transcript_path = OUTPUT_DIR / f"ep{episode_id}_{topic}_transcript.json"
|
|
conversation = json.loads(conv_path.read_text())["messages"]
|
|
|
|
transcript_data = {
|
|
"episode": episode_id,
|
|
"topic": topic,
|
|
"turns": len(conversation),
|
|
"conversation": conversation,
|
|
}
|
|
transcript_path.write_text(json.dumps(transcript_data, indent=2))
|
|
print(f"\n✅ Transcript: {transcript_path}", flush=True)
|
|
|
|
# Save readable transcript
|
|
readable_path = OUTPUT_DIR / f"ep{episode_id}_{topic}_readable.txt"
|
|
lines = [
|
|
f"AGENT AI TALK SHOW — Episode {episode_id}\n",
|
|
f"Topic: {topic}\n",
|
|
"=" * 60 + "\n\n",
|
|
]
|
|
for msg in conversation:
|
|
lines.append(f"**{msg['agent']}**\n")
|
|
lines.append(msg["content"] + "\n\n")
|
|
readable_path.write_text("\n".join(lines))
|
|
print(f"✅ Readable: {readable_path}", flush=True)
|
|
|
|
# Summary
|
|
total_words = sum(len(m["content"].split()) for m in conversation)
|
|
print(f"\n📊 {total_words} words across {len(conversation)} turns", flush=True)
|
|
print(f" ~{total_words/150:.1f} min runtime", flush=True)
|
|
|
|
return conversation
|
|
|
|
if __name__ == "__main__":
|
|
episode = sys.argv[1] if len(sys.argv) > 1 else "003"
|
|
topic = sys.argv[2] if len(sys.argv) > 2 else "hermes-v018"
|
|
run_show(episode, topic)
|