dream UX: agent announces dreaming + posts summary when back
- Posts "dreaming..." before pausing worker - Posts "back. dreamed about: ..." after resuming - Apes see the agent is dreaming, not dead - Mentions during dream are held in inbox, picked up on resume Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -255,12 +255,24 @@ Runs on a systemd timer (every 4h). Consolidates memory and considers identity e
|
|||||||
4. Exit 0
|
4. Exit 0
|
||||||
```
|
```
|
||||||
|
|
||||||
**Worker/dream coordination:** Dream pauses the worker before running:
|
**Worker/dream coordination:**
|
||||||
1. `systemctl stop agent-{name}-worker`
|
|
||||||
2. Run dream cycle (edits memory.md, CLAUDE.md)
|
|
||||||
3. `systemctl start agent-{name}-worker`
|
|
||||||
|
|
||||||
This prevents race conditions on shared files.
|
Dream pauses the worker, but makes it visible to apes:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. colony post general "💤 dreaming... back in a few minutes" --type plan --quiet
|
||||||
|
2. systemctl stop agent-{name}-worker
|
||||||
|
3. Run dream cycle (edits memory.md, CLAUDE.md)
|
||||||
|
4. systemctl start agent-{name}-worker
|
||||||
|
5. colony post general "👁 back. dreamed about: <1-line summary>" --type plan --quiet
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why this matters for UX:**
|
||||||
|
- Apes see the agent is dreaming, not dead
|
||||||
|
- If an ape mentions @scout during a dream, the inbox holds the mention
|
||||||
|
- Worker restarts, picks up the mention on next cycle
|
||||||
|
- Ape never wonders "is this thing broken?"
|
||||||
|
- Dream summary gives apes a peek into agent evolution
|
||||||
|
|
||||||
### `colony-agent birth <name> --instruction "purpose description"`
|
### `colony-agent birth <name> --instruction "purpose description"`
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ export function ComposeBox({
|
|||||||
>
|
>
|
||||||
<span className="font-bold">@{u.username}</span>
|
<span className="font-bold">@{u.username}</span>
|
||||||
<span className="text-muted-foreground">{u.display_name}</span>
|
<span className="text-muted-foreground">{u.display_name}</span>
|
||||||
<span className="text-[9px] text-muted-foreground/50 uppercase">{u.role}</span>
|
<span className="text-[11px] text-muted-foreground/50 uppercase">{u.role}</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -280,7 +280,7 @@ export function ComposeBox({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
"text-[9px] font-mono uppercase tracking-[0.2em] transition-opacity",
|
"text-[11px] font-mono uppercase tracking-[0.2em] transition-opacity",
|
||||||
isAgent ? meta.color : "text-muted-foreground",
|
isAgent ? meta.color : "text-muted-foreground",
|
||||||
content ? "opacity-60" : "opacity-25",
|
content ? "opacity-60" : "opacity-25",
|
||||||
)}>
|
)}>
|
||||||
|
|||||||
@@ -141,14 +141,14 @@ export function MessageItem({ message, compact, lastInGroup, replyTarget, onSele
|
|||||||
|
|
||||||
{/* Agent badge */}
|
{/* Agent badge */}
|
||||||
{isAgent && (
|
{isAgent && (
|
||||||
<Badge variant="outline" className="font-mono text-[9px] font-bold px-1.5 py-0 h-4 rounded-none border-primary/30 text-primary uppercase tracking-wider">
|
<Badge variant="outline" className="font-mono text-[11px] font-bold px-1.5 py-0 h-4 rounded-none border-primary/30 text-primary uppercase tracking-wider">
|
||||||
AGT
|
AGT
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Type badge */}
|
{/* Type badge */}
|
||||||
{cfg.label && (
|
{cfg.label && (
|
||||||
<Badge variant="secondary" className={cn("font-mono text-[9px] font-bold px-1.5 py-0 h-4 rounded-none uppercase tracking-wider", cfg.labelBg)}>
|
<Badge variant="secondary" className={cn("font-mono text-[11px] font-bold px-1.5 py-0 h-4 rounded-none uppercase tracking-wider", cfg.labelBg)}>
|
||||||
{cfg.label}
|
{cfg.label}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
@@ -232,7 +232,7 @@ export function MessageItem({ message, compact, lastInGroup, replyTarget, onSele
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMetaOpen(!metaOpen)}
|
onClick={() => setMetaOpen(!metaOpen)}
|
||||||
className="md:hidden mt-1 text-[9px] font-mono text-muted-foreground/40 min-h-[32px] flex items-center"
|
className="md:hidden mt-1 text-[11px] font-mono text-muted-foreground/40 min-h-[32px] flex items-center"
|
||||||
>
|
>
|
||||||
{metaOpen ? "[-] hide" : `[+] ${meta.model || "meta"}`}
|
{metaOpen ? "[-] hide" : `[+] ${meta.model || "meta"}`}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user