chore(orchestration): drop XML wrappers + close remaining audit gaps

Final pass after re-audit. Three sub-specs landed:

**XML simplification** — the legacy XML envelopes were prompt-engineering
ceremony, not parser primitives (the SDK uses native tool-calling). Drop
the verbose wrappers in favor of one-liner labeled headers. Side benefit:
fixes the unescaped-content XML-injection bug the audit caught (peer
content containing ``</content>`` no longer breaks the wrapper).

- ``_format_inter_agent_message``: ``<inter_agent_message><sender>...
  <content>...`` 9-line XML → ``[Message from {name} ({id}) | type=... |
  priority=...]\n{content}``.
- ``_render_completion_report``: ``<agent_completion_report><agent_info>
  ...<results>...`` XML → human-readable structured text with section
  headers and bulleted lists.
- ``inherited_context``: ``<inherited_context_from_parent>...`` →
  ``== Inherited context from parent (background only) ==``.

**MG1: TUI stop-agent uses graceful cancel.** ``tui.py`` was calling
``bus.cancel_descendants`` (hard, ``task.cancel()`` mid-stream) for the
stop-agent button. Switched to ``bus.cancel_descendants_graceful``, which
uses ``RunResultStreaming.cancel(mode="after_turn")`` to let each agent
finish its current turn (and save to session) before honoring the cancel.
The hard path remains in ``entry.py`` for KeyboardInterrupt where
graceful isn't possible.

**MG2: Document hook lock-free stats mutation.** Added a comment in
``hooks.on_llm_start`` explaining why ``warned_85`` / ``warned_final``
are mutated lock-free: SDK serializes ``on_llm_start`` per agent, so this
hook is the sole writer to those keys; ``record_usage`` only writes
disjoint keys (in/out/cached/calls).

**AG3: Auto-load ``coordination/root_agent`` skill for the root.**
Legacy auto-loaded the orchestration-guidance skill for root agents
only. Threaded ``is_root`` through ``render_system_prompt`` →
``_resolve_skills``; root agents now get the skill, children don't.

Skipped (per user direction): whitebox-wiki integration (CG2-4) — the
auto-injection / auto-update of the shared repo wiki was a pre-migration
feature; user opted not to restore it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-04-25 17:48:55 -07:00
parent f4834cd6f7
commit 25decb0685
6 changed files with 66 additions and 46 deletions
+28 -19
View File
@@ -19,6 +19,7 @@ import asyncio
import json
import logging
import uuid
from datetime import UTC, datetime
from typing import TYPE_CHECKING, Any, Literal
from agents import RunContextWrapper, function_tool
@@ -52,26 +53,34 @@ def _render_completion_report(
findings: list[str],
recommendations: list[str],
) -> str:
"""Render an ``<agent_completion_report>`` XML payload (legacy parity)."""
from datetime import UTC, datetime
from html import escape
"""Render a child's completion report as plain structured text.
Goes into the parent's bus inbox; the inject filter prepends a
``[Message from ...]`` header on top, so this body just carries the
contents. No XML — no escaping concerns, no parser ambiguity.
"""
status = "SUCCESS" if success else "FAILED"
completion_time = datetime.now(UTC).isoformat()
findings_xml = "".join(f"<finding>{escape(f)}</finding>" for f in findings)
recs_xml = "".join(f"<recommendation>{escape(r)}</recommendation>" for r in recommendations)
return (
"<agent_completion_report>\n"
f" <agent_info><agent_name>{escape(agent_name)}</agent_name>"
f"<agent_id>{escape(agent_id)}</agent_id>"
f"<task>{escape(task)}</task>"
f"<status>{status}</status>"
f"<completion_time>{completion_time}</completion_time></agent_info>\n"
f" <results><summary>{escape(result_summary)}</summary>"
f"<findings>{findings_xml}</findings>"
f"<recommendations>{recs_xml}</recommendations></results>\n"
"</agent_completion_report>"
)
lines: list[str] = [
f"== Completion report from {agent_name} ({agent_id}) ==",
f"Status: {status}",
f"Time: {completion_time}",
]
if task:
lines.append(f"Task: {task}")
lines.append("")
lines.append("Summary:")
lines.append(result_summary or "(none)")
if findings:
lines.append("")
lines.append("Findings:")
lines.extend(f"- {f}" for f in findings)
if recommendations:
lines.append("")
lines.append("Recommendations:")
lines.extend(f"- {r}" for r in recommendations)
return "\n".join(lines)
@function_tool(timeout=30)
@@ -456,9 +465,9 @@ async def create_agent(
{
"role": "user",
"content": (
"<inherited_context_from_parent>\n"
"== Inherited context from parent (background only) ==\n"
f"{rendered}\n"
"</inherited_context_from_parent>\n"
"== End of inherited context ==\n"
"Use the above as background only; do not continue the "
"parent's work. Your task follows."
),