feat(messaging): balanced TOOL parsing, DM shorthand, box.exec, tools.list

- response-harvester: extract [TOOL]/[EXEC] JSON args with balanced-brace
  scanning (']' and nesting inside args no longer truncate calls); add
  [DM {...}] shorthand mapping to dm.send; native aliases (dm, box,
  tools) plus arg-synonym normalization; formatters and expanded hints.
- exec-constrained: new read-only box.exec op (27 allowlisted box-ctl
  reads) and tools.list op backed by --list-ops for dynamic discovery.
- prompt_envelope: advertise dm.send/box.exec/tools.list in every timer
  DM; add dm_call builder.
- lookup_engine + regex_patterns.json: canonical tool_call pattern
  accepts the DM engine, ']' in args, one nesting level.
- tests/test_tool_calls.py: 38 tests; docs/INBAND-MESSAGING-SPEC.md:
  accepted decision record (Final).
This commit is contained in:
operator-main
2026-10-06 07:29:16 +00:00
parent 345eb09559
commit f2640397ed
7 changed files with 571 additions and 24 deletions
+13 -3
View File
@@ -57,14 +57,22 @@ def pick_profile(job_name):
def _tool(op, args):
# no ']' inside the JSON: the harvester's [TOOL ...] regex stops at the first one
# the harvester extracts JSON args with balanced-brace scanning, so
# ']' and nested objects/arrays inside args are safe
return "[TOOL %s %s]" % (op, json.dumps(args, separators=(", ", ": ")))
def spawn_call(job_id, job_name, profile):
count, _, hint = PROFILES[profile]
# no brackets in the task text: the harvester's [TOOL ...] regex stops at the first ']'
task = "Subagent for job %s (%s): %s." % (job_id, job_name, hint)
def dm_call(to, target, message):
return "[DM %s]" % json.dumps(
{"to": to, "target": target, "message": message[:900]},
separators=(", ", ": "))
return _tool("swarm.spawn", {"count": count, "task": task[:900], "label": (job_name or "job")[:60]})
@@ -111,7 +119,9 @@ def wrap(job_name, job_id, agent, target, rendered):
bottom = (
"\n--- End Task ---\n\n"
f"Inspect tmux output: [TOOL tmux.capture {{\"session\": \"{session_name}\", \"lines\": 30}}]\n"
"Tools available: cron.create, cron.runs, health.check, swarm.spawn, swarm.list.\n"
"Tools: cron.create, cron.runs, health.check, swarm.spawn, swarm.list, dm.send, box.exec, tools.list.\n"
"Message a peer: [DM {\"to\": \"<agent>\", \"target\": \"<sidechat>\", \"message\": \"<text>\"}].\n"
"Query box: [TOOL box.exec {\"action\": \"<fleet-status|dm-log|job-get|...>\"}] \u2014 [TOOL tools.list {}] lists every op.\n"
)
if not has_result:
bottom += f"When complete, report your verdict: [RESULT {job_id}] OK: <summary of actions>\n"