diff --git a/doc/usage.md b/doc/usage.md index f994230..ef67265 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -270,10 +270,11 @@ For long-lived parallel agents, create named sessions and pass prompts between them via the filesystem: ```sh -printf 'name=writer\ncwd=%s\n' "$PWD" | o write session/new -printf 'name=reviewer\ncwd=%s\n' "$PWD" | o write session/new -o write prompt "Draft a design doc" # with session=writer agent={aname} -o tail # read writer's response +o write session/new "name=writer cwd=$PWD" +o write session/new "name=reviewer cwd=$PWD" +agent=$(o ls session/writer/agent | grep -v '^new$') +o write "session/writer/agent/$agent/prompt" "Draft a design doc" +o read "session/writer/agent/$agent/chat" # read writer's response ``` Key files per agent: @@ -300,39 +301,44 @@ workflow using named sessions and `statewait`: #!/bin/sh cwd=${1:?usage: $0 } -printf 'name=developer\nagent=developer\ncwd=%s\n' "$cwd" | 9p write session/new -printf 'name=reviewer\nagent=reviewer\ncwd=%s\n' "$cwd" | 9p write session/new -printf 'name=tester\nagent=tester\ncwd=%s\n' "$cwd" | 9p write session/new +# Create named sessions with agent profiles +o write session/new "name=developer agent=developer cwd=$cwd" +o write session/new "name=reviewer agent=reviewer cwd=$cwd" +o write session/new "name=tester agent=tester cwd=$cwd" + +# Discover agent names (first agent in each session) +agent_developer=$(o ls session/developer/agent | grep -v '^new$') +agent_reviewer=$(o ls session/reviewer/agent | grep -v '^new$') +agent_tester=$(o ls session/tester/agent | grep -v '^new$') send() { sid=$1; shift - exec 3< session/$sid/agent/{aname}/statewait - printf '%s' "$*" > session/$sid/agent/{aname}/prompt - while true; do - read -r _ <&3 && { exec 3<&-; break; } - exec 3<&- - [ "$(cat session/$sid/agent/{aname}/state)" != "idle" ] && break - exec 3< session/$sid/agent/{aname}/statewait - done - until [ "$(cat session/$sid/agent/{aname}/state)" = "idle" ]; do sleep 0.5; done - tail -c +$(($(cat session/$sid/agent/{aname}/offset) + 1)) session/$sid/agent/{aname}/chat + aname=$1; shift + # Open statewait, send prompt, wait for completion, read response + exec 3< <(o readloop "session/$sid/agent/$aname/statewait" &) + sleep 0.1 + o write "session/$sid/agent/$aname/prompt" "$*" + until o read "session/$sid/agent/$aname/state" | grep -q idle; do sleep 0.5; done + exec 3<&- + offset=$(o read "session/$sid/agent/$aname/offset" | tr -d '[:space:]') + o read "session/$sid/agent/$aname/chat" | tail -c +$((offset + 1)) } -reply=$(send developer "Implement a function that parses a JSON config file.") +reply=$(send developer "$agent_developer" "Implement a function that parses a JSON config file.") while true; do - review=$(send reviewer "Review the following code. Reply LGTM if ready, or PTAL with feedback. + review=$(send reviewer "$agent_reviewer" "Review the following code. Reply LGTM if ready, or PTAL with feedback. $reply") if ! printf '%s' "$review" | grep -qi "LGTM"; then - reply=$(send developer "Revise based on this feedback: + reply=$(send developer "$agent_developer" "Revise based on this feedback: $review") continue fi - result=$(send tester "Test the following code. Reply Approved if all tests pass, or Rejected with details. + result=$(send tester "$agent_tester" "Test the following code. Reply Approved if all tests pass, or Rejected with details. $reply") @@ -341,12 +347,14 @@ $reply") break fi - reply=$(send developer "Fix the following test failures: + reply=$(send developer "$agent_developer" "Fix the following test failures: $result") done -rm -r session/developer session/reviewer session/tester +o kill developer +o kill reviewer +o kill tester ``` The agents have no knowledge of each other — the script holds all the routing logic.