Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion inkbox_claude/a2a_progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def _clean_update(value: Any, tool_names: list[str]) -> str:
return _fallback_update()
normalized_text = _normalize_identifier_text(text)
if any(
re.search(rf"(?:^|_){re.escape(tool_name)}(?:_|$)", normalized_text)
re.search(rf"(?<![a-z0-9]){re.escape(tool_name)}(?![a-z0-9])", normalized_text)
for tool_name in tool_names
if tool_name
):
Expand Down
16 changes: 16 additions & 0 deletions tests/test_a2a_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,22 @@ def test_a2a_progress_summary_rejects_echoed_tool_identifier():
)


def test_a2a_progress_summary_rejects_tool_identifier_across_separators():
# The leak guard must suppress an echoed tool name regardless of the
# surrounding punctuation, not only underscores. The remote agent controls
# the task text (an untrusted prompt-injection surface), and the update is
# sent on to that untrusted agent, so a tool name bordered by '-', '.', or
# ':' must not slip through to them.
for update in (
"Running bash-based checks now",
"Inspecting the bash.exe helper",
"Using bash:mode for this step",
):
assert progress_mod._clean_update(update, ["bash"]) == (
"I'm continuing the requested work."
)


def test_a2a_progress_tool_names_are_bounded_and_do_not_retain_inputs():
progress_mod.start_a2a_progress("task-1")

Expand Down