Add real-time per-tool-call audit streaming (HARNESS-WP-0002-T03)
Claude Code executes its own tools internally in --print mode -- there is no way for a caller to externally dispatch individual tool calls without abandoning that self-contained agent model. What --output-format stream-json --include-hook-events does allow: observing each tool_use/tool_result/hook event in real time. - adapter.py: AgenticClaudeCodeAdapter gains an optional on_tool_event callback; streaming mode (Popen + background reader thread) is used only when set, blocking subprocess.run path is unchanged otherwise. - runner.py: run_task gains emit_tool_events/on_tool_event, collecting events onto RunResult.tool_events and posting a tool_call hub event per tool when reporting is enabled. - cli.py: --stream-tool-events flag on `run`, prints each event as a tagged JSON line ahead of the unchanged final result block. Live-verified against the real claude CLI: 5 real tool events streamed correctly (2x Bash, 1x Write) plus Stop hook lifecycle events, real commit landed, final result block unchanged. 13 new tests (test_adapter.py + 2 in test_runner.py), all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
c77a643393
commit
6c4f00e2c2
7 changed files with 384 additions and 18 deletions
|
|
@ -130,10 +130,18 @@ def _cmd_run(args: argparse.Namespace) -> int:
|
|||
print(f"invalid task spec: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
def _print_event(event: dict) -> None:
|
||||
# Tagged + single-line so a consumer reading stdout line-by-line
|
||||
# (e.g. glas-harness's ReinAharness) can tell an event line apart
|
||||
# from the pretty-printed final result block below.
|
||||
print(json.dumps({"stream_event": event}), flush=True)
|
||||
|
||||
result = run_task(
|
||||
spec,
|
||||
report_to_hub=not args.no_hub,
|
||||
write_metrics=not args.no_metrics,
|
||||
emit_tool_events=args.stream_tool_events,
|
||||
on_tool_event=_print_event if args.stream_tool_events else None,
|
||||
)
|
||||
|
||||
closed = False
|
||||
|
|
@ -191,6 +199,16 @@ def main(argv: list[str] | None = None) -> int:
|
|||
action="store_true",
|
||||
help="Skip writing .kaizen/metrics in the target repo",
|
||||
)
|
||||
run.add_argument(
|
||||
"--stream-tool-events",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Run claude with --output-format stream-json --include-hook-events "
|
||||
"and print each tool_use/tool_result/hook event as its own JSON "
|
||||
"line while running (real-time audit, not external tool dispatch "
|
||||
"-- HARNESS-WP-0002-T03)"
|
||||
),
|
||||
)
|
||||
|
||||
scan = sub.add_parser(
|
||||
"mail-scan", help="Deterministic company-mailbox scan (no LLM session)"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue