colony-agent: implement worker loop + dream cycle
Worker: - run_pulse(): check inbox → heartbeat → HEARTBEAT_OK or invoke Claude - run_worker_loop(): forever loop with 30s/10s sleep - Builds prompt from inbox items + heartbeat.md - Invokes claude --dangerously-skip-permissions with context - Acks inbox items after Claude completes - Added 'pulse' command for one-shot testing Dream: - Checks memory.md line count (skip if < 50) - Posts "dreaming..." to #general - Invokes Claude to consolidate, prune, evolve - Posts "back from dreaming" when done Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
54
crates/colony-agent/src/dream.rs
Normal file
54
crates/colony-agent/src/dream.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use std::process::Command;
|
||||
|
||||
/// Run one dream cycle
|
||||
pub fn run_dream() {
|
||||
let memory_path = "memory/memory.md";
|
||||
|
||||
// 1. Check if memory is worth dreaming about
|
||||
let memory = std::fs::read_to_string(memory_path).unwrap_or_default();
|
||||
let line_count = memory.lines().count();
|
||||
|
||||
if line_count < 50 {
|
||||
eprintln!("memory too short ({} lines), skipping dream", line_count);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Announce dream
|
||||
let _ = Command::new("colony")
|
||||
.args(["post", "general", "💤 dreaming... back in a few minutes", "--type", "plan", "--quiet"])
|
||||
.status();
|
||||
|
||||
// 3. Invoke Claude for dream cycle
|
||||
eprintln!("dreaming... ({} lines of memory)", line_count);
|
||||
|
||||
let prompt = format!(
|
||||
"Dream cycle. Read memory/memory.md ({} lines). \
|
||||
Consolidate into themes and insights. \
|
||||
Write a dream summary to memory/dreams/ with today's date. \
|
||||
Prune memory/memory.md to the last 100 entries. \
|
||||
If you've learned something about yourself, update your CLAUDE.md \
|
||||
and add a line to the evolution log section.",
|
||||
line_count
|
||||
);
|
||||
|
||||
let status = Command::new("claude")
|
||||
.args([
|
||||
"--dangerously-skip-permissions",
|
||||
"-p",
|
||||
&prompt,
|
||||
"--max-turns",
|
||||
"10",
|
||||
])
|
||||
.status();
|
||||
|
||||
match status {
|
||||
Ok(s) if s.success() => eprintln!("dream completed"),
|
||||
Ok(s) => eprintln!("dream exited with status: {}", s),
|
||||
Err(e) => eprintln!("failed to run claude for dream: {}", e),
|
||||
}
|
||||
|
||||
// 4. Announce return
|
||||
let _ = Command::new("colony")
|
||||
.args(["post", "general", "👁 back from dreaming", "--type", "plan", "--quiet"])
|
||||
.status();
|
||||
}
|
||||
Reference in New Issue
Block a user