feat(autonomy): add followup.create primitive and tool-continuation directives to enforce silence-kills-work

This commit is contained in:
operator
2026-10-05 05:24:45 +00:00
parent 03374795d8
commit c90e096192
5 changed files with 172 additions and 16 deletions
+44 -9
View File
@@ -197,9 +197,10 @@ def cron_to_oncalendar(schedule):
# M H DOM * * -> *-*-DOM HH:MM:00 (monthly)
if m.isdigit() and h.isdigit() and dom.isdigit() and is_star(mon) and is_star(dow):
return f"*-*-{int(dom):02d} {int(h):02d}:{int(m):02d}:00"
# M H * * * with stepped hour: M */n * * * -> 0/n:MM
if m.isdigit() and h.startswith("*/") and h[2:].isdigit() and all(is_star(f) for f in (dom, mon, dow)):
return f"0/{h[2:]}:{int(m):02d}"
# M,M... * * * * -> *:M1,M2...
if all(part.isdigit() for part in m.split(",")) and all(is_star(f) for f in (h, dom, mon, dow)):
formatted_m = ",".join(f"{int(part):02d}" for part in m.split(","))
return f"*:{formatted_m}"
return None
@@ -885,9 +886,12 @@ def _valid_sidechat_name(name):
ord(c) < 32 or ord(c) == 127 for c in name)
def act_notify(agent, message, sidechat=None, allow_main_chat=False):
def act_notify(agent, message, sidechat=None, allow_main_chat=False, sender=None):
if agent not in VALID_AGENTS:
fail("BAD_NAME", f"agent must be one of {sorted(VALID_AGENTS)}")
if sender is not None and sender not in VALID_AGENTS:
fail("BAD_NAME", f"sender must be one of {sorted(VALID_AGENTS)}")
sender_agent = sender if sender else "opm"
if not message or len(message) > 1000:
fail("INVALID_JOB", "message must be 1\u20131000 chars")
# Sidechat-first policy: default to the agent's sidechat, never main.
@@ -902,7 +906,7 @@ def act_notify(agent, message, sidechat=None, allow_main_chat=False):
fail("BAD_NAME", "sidechat name must be 1-64 chars, no control characters")
extra = []
r = run([sys.executable, str(DM_PY), "send",
"--agent", "opm", "--to", agent, "--target", target,
"--agent", sender_agent, "--to", agent, "--target", target,
*extra, message],
timeout=120)
if r.returncode != 0:
@@ -2642,6 +2646,30 @@ def main(argv):
if len(rest) != 1:
fail("BAD_NAME", f"usage: {action} <name>")
act_timer_control(rest[0], action[len("timer-"):])
elif action == "timer":
if not rest:
act_timer_list()
else:
sub = rest[0]
if sub in ("list",):
act_timer_list()
elif sub in ("status",):
if len(rest) != 2:
fail("BAD_NAME", "usage: timer status <name>")
act_timer_status(rest[1])
elif sub in ("create",):
if len(rest) != 2:
fail("BAD_NAME", "usage: timer create <name>")
act_timer_create(rest[1])
elif sub in ("delete",):
keep = "--keep-job" in rest[2:]
act_timer_delete(rest[1], keep_job=keep)
elif sub in ("start", "stop", "enable", "disable"):
if len(rest) != 2:
fail("BAD_NAME", f"usage: timer {sub} <name>")
act_timer_control(rest[1], sub)
else:
fail("BAD_NAME", "usage: timer list|status|create|delete|start|stop|enable|disable [...]")
elif action == "job-list":
act_job_list()
elif action == "job-get":
@@ -2809,22 +2837,29 @@ def main(argv):
fail("BAD_NAME", f"usage: {action} --agent <agent> --thread <id> [--title <title>]")
act_thread(op, agent, thread, title)
elif action == "notify":
# notify <agent> <message> [--sidechat <name>] [--allow-main-chat]
# notify <agent> <message> [--sidechat <name>] [--allow-main-chat] [--sender <agent>]
args = list(rest)
allow_main = False
sidechat = None
sender = None
if "--allow-main-chat" in args:
allow_main = True
args.remove("--allow-main-chat")
if "--sidechat" in args:
i = args.index("--sidechat")
if i + 1 >= len(args):
fail("BAD_NAME", "usage: notify <agent> <message> [--sidechat <name>] [--allow-main-chat]")
fail("BAD_NAME", "usage: notify <agent> <message> [--sidechat <name>] [--allow-main-chat] [--sender <agent>]")
sidechat = args[i + 1]
del args[i:i + 2]
if "--sender" in args:
i = args.index("--sender")
if i + 1 >= len(args):
fail("BAD_NAME", "usage: notify <agent> <message> [--sidechat <name>] [--allow-main-chat] [--sender <agent>]")
sender = args[i + 1]
del args[i:i + 2]
if len(args) != 2:
fail("BAD_NAME", "usage: notify <agent> <message> [--sidechat <name>] [--allow-main-chat]")
act_notify(args[0], args[1], sidechat=sidechat, allow_main_chat=allow_main)
fail("BAD_NAME", "usage: notify <agent> <message> [--sidechat <name>] [--allow-main-chat] [--sender <agent>]")
act_notify(args[0], args[1], sidechat=sidechat, allow_main_chat=allow_main, sender=sender)
elif action == "policy":
if not rest:
act_policy()