feat(swarm-worker): dispatch prose swarm slots to ephemeral Muse subagents
- daemon: route non-shell slot tasks to a fresh subagent session on dev/def/muse via muse_hybrid; add bin/ to sys.path so muse_hybrid/prompt_envelope import under the tmux supervisor - prompt_envelope: add wrap_subagent_task() - plain task assignment without [TOOL tmux/swarm/cron] meta tags (subagents refused those as relayed test traffic) - box-ctl/reporter: swarm-attach accepts optional session-id, stored as slot.subagent_session_id - executor: _looks_like_shell requires an existing executable (prose like 'verify ...' no longer misread as shell) - poller: pick up pending swarms as well as running - response-harvester: monitor running slot subagent sessions from swarms.json, allow '/' in RESULT/VERB job ids, archive ephemeral threads on any verdict (OK or FAIL), reap slot sessions for terminal swarms
This commit is contained in:
+10
-8
@@ -2004,7 +2004,7 @@ def act_swarm_status(sid):
|
||||
out(True, swarm=swarm, counts=_swarm_counts(swarm))
|
||||
|
||||
|
||||
def act_swarm_attach(sid, slot_str, agent_id):
|
||||
def act_swarm_attach(sid, slot_str, agent_id, session_id=None):
|
||||
if not agent_id or not SWARM_AGENT_RE.match(agent_id):
|
||||
fail("BAD_NAME", "agent id must match ^[A-Za-z0-9-]{1,64}$",
|
||||
{"field": "agent_id", "value": agent_id})
|
||||
@@ -2021,13 +2021,15 @@ def act_swarm_attach(sid, slot_str, agent_id):
|
||||
{"swarm_id": sid, "slot": slot_rec["slot"]})
|
||||
slot_rec["agent_id"] = agent_id
|
||||
slot_rec["status"] = "running"
|
||||
if session_id:
|
||||
slot_rec["subagent_session_id"] = str(session_id)
|
||||
slot_rec["updated_ts"] = utcnow()
|
||||
swarm["status"] = _swarm_rollup(swarm)
|
||||
swarm["updated_ts"] = utcnow()
|
||||
_swarm_save(swarms)
|
||||
audit("swarm-attach", "%s/%d" % (sid, slot_rec["slot"]))
|
||||
out(True, swarm_id=sid, slot=slot_rec["slot"], agent_id=agent_id,
|
||||
status="running")
|
||||
subagent_session_id=session_id, status="running")
|
||||
|
||||
|
||||
def act_swarm_report(sid, slot_str):
|
||||
@@ -3432,9 +3434,9 @@ def main(argv):
|
||||
fail("BAD_ARGS", "usage: swarm-status <swarm-id>")
|
||||
act_swarm_status(rest[0])
|
||||
elif op == "attach":
|
||||
if len(rest) != 3:
|
||||
fail("BAD_ARGS", "usage: swarm-attach <swarm-id> <slot> <agent-id>")
|
||||
act_swarm_attach(rest[0], rest[1], rest[2])
|
||||
if len(rest) not in (3, 4):
|
||||
fail("BAD_ARGS", "usage: swarm-attach <swarm-id> <slot> <agent-id> [session-id]")
|
||||
act_swarm_attach(rest[0], rest[1], rest[2], rest[3] if len(rest) > 3 else None)
|
||||
elif op == "report":
|
||||
if len(rest) != 2:
|
||||
fail("BAD_ARGS", "usage: swarm-report <swarm-id> <slot> (result JSON on stdin)")
|
||||
@@ -3479,9 +3481,9 @@ def main(argv):
|
||||
fail("BAD_ARGS", "usage: swarm status <swarm-id>")
|
||||
act_swarm_status(args[0])
|
||||
elif sub == "attach":
|
||||
if len(args) != 3:
|
||||
fail("BAD_ARGS", "usage: swarm attach <swarm-id> <slot> <agent-id>")
|
||||
act_swarm_attach(args[0], args[1], args[2])
|
||||
if len(args) not in (3, 4):
|
||||
fail("BAD_ARGS", "usage: swarm attach <swarm-id> <slot> <agent-id> [session-id]")
|
||||
act_swarm_attach(args[0], args[1], args[2], args[3] if len(args) > 3 else None)
|
||||
elif sub == "report":
|
||||
if len(args) != 2:
|
||||
fail("BAD_ARGS", "usage: swarm report <swarm-id> <slot> (result JSON on stdin)")
|
||||
|
||||
Reference in New Issue
Block a user