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:
+13
-3
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user