fix(agents): finish_scan drops its coverage reconciliation step when the coverage tools are off

This commit is contained in:
Ahmed Allam 2026-10-24 17:44:27 +00:00 • committed by Ahmed Allam
parent bac386e509
commit aaf1f8c823
2 changed files with 21 additions and 0 deletions

View file

@ -620,6 +620,15 @@ def _finish_tool_use_behavior(
_COVERAGE_TOOLS: tuple[Tool, ...] = (record_coverage, update_coverage, list_coverage)
_FINISH_SCAN_COVERAGE_STEP = re.compile(
r"\n5\. \*\*Coverage reconciliation\.\*\*.*?(?=\n\n)", re.DOTALL
)
def _without_coverage_step(tool: FunctionTool) -> FunctionTool:
description = _FINISH_SCAN_COVERAGE_STEP.sub("", tool.description)
return dataclasses.replace(tool, description=description)
_BASE_TOOLS: tuple[Tool, ...] = (
think,
@ -771,6 +780,8 @@ def build_strix_agent(
base_tools = [report_tool if t is create_vulnerability_report else t for t in _BASE_TOOLS]
if not coverage_tools:
base_tools = [t for t in base_tools if t not in _COVERAGE_TOOLS]
if finish_tool is finish_scan:
finish_tool = _without_coverage_step(finish_scan)
if is_root:
tools: list[Tool] = [*base_tools, *agent_tools, finish_tool]
else:

View file

@ -104,6 +104,10 @@ def test_report_tool_replaces_create_vulnerability_report() -> None:
assert "create_vulnerability_report" not in agent.instructions
def _descriptions(tools: list[Any]) -> list[str]:
return [t.description for t in tools if isinstance(t, FunctionTool)]
def test_coverage_tools_can_be_turned_off() -> None:
coverage = {"record_coverage", "update_coverage", "list_coverage"}
for is_root in (True, False):
@ -116,6 +120,12 @@ def test_coverage_tools_can_be_turned_off() -> None:
assert "- COVERAGE" in on.instructions
assert "## Recording Closure" in on.instructions
assert not any(name in off.instructions for name in coverage)
on_descriptions = "\n".join(_descriptions(on.tools))
off_descriptions = "\n".join(_descriptions(off.tools))
if is_root:
assert "Coverage reconciliation" in on_descriptions
assert "Coverage reconciliation" not in off_descriptions
assert not any(name in off_descriptions for name in coverage)
def test_instructions_override_is_used_verbatim() -> None: