Skip to content

Commit ac76f3a

Browse files
author
Mateusz
committed
test(dynamic-compression): cover tool-name substring exclusions for MCP tools
Add regression tests for disable_tool_name_substrings across config/env/CLI and runtime behavior, and document how to exclude optimized MCP families like fff from redundant compression.
1 parent d094a34 commit ac76f3a

4 files changed

Lines changed: 74 additions & 8 deletions

File tree

docs/user_guide/features/dynamic-tool-output-compression.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ dynamic_compression:
107107
# Specific tool exclusions
108108
disable_tools: [] # e.g., ["shell", "bash", "run_command"]
109109

110+
# Tool-name substring exclusions (match anywhere, case-insensitive)
111+
disable_tool_name_substrings: [] # e.g., ["fff", "mcp_"]
112+
110113
# Command prefix exclusions
111114
disable_command_prefixes: [] # e.g., ["git diff --stat", "pytest -v"]
112115

@@ -153,8 +156,25 @@ dynamic_compression:
153156
| `--dynamic-compression-disable-categories CSV` | Comma-separated categories to bypass |
154157
| `--dynamic-compression-disable-methods CSV` | Comma-separated methods to disable |
155158
| `--dynamic-compression-disable-tools CSV` | Comma-separated tool names to bypass |
159+
| `--dynamic-compression-disable-tool-name-substrings CSV` | Comma-separated substrings matched anywhere in tool names |
156160
| `--dynamic-compression-disable-command-prefixes CSV` | Comma-separated command prefixes to bypass |
157161

162+
### Excluding MCP Tool Families (for example `fff`)
163+
164+
If a tool family already produces compact output, skip dynamic compression for it using `disable_tool_name_substrings`.
165+
166+
```yaml
167+
dynamic_compression:
168+
enabled: true
169+
disable_tool_name_substrings: ["fff"]
170+
```
171+
172+
This matches tool names case-insensitively and anywhere in the name, including:
173+
- `fff_grep`
174+
- `fff_find_files`
175+
- `fff_multi_grep`
176+
- `turbo_fff_grep`
177+
158178
### Compression Levels
159179

160180
The `level` setting controls compression aggressiveness:

tests/unit/core/cli_support/applicators/test_dynamic_compression_applicator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def test_dynamic_compression_applicator_sets_overrides_and_resolution() -> None:
3737
args.dynamic_compression_per_output_evaluation_log_level = "off"
3838
args.dynamic_compression_file_detail_include_line_numbers = True
3939
args.dynamic_compression_disable_methods = "ansi_normalize,line_dedupe"
40+
args.dynamic_compression_disable_tool_name_substrings = "fff,mcp_"
4041

4142
overrides: dict[str, object] = {}
4243
resolution = ParameterResolution()
@@ -53,6 +54,7 @@ def test_dynamic_compression_applicator_sets_overrides_and_resolution() -> None:
5354
assert dc_typed.get("per_output_evaluation_log_level") == "off"
5455
assert dc_typed.get("file_detail_include_line_numbers") is True
5556
assert dc_typed.get("disable_methods") == ["ansi_normalize", "line_dedupe"]
57+
assert dc_typed.get("disable_tool_name_substrings") == ["fff", "mcp_"]
5658

5759
cli_paths = set(resolution.latest_by_source(ParameterSource.CLI))
5860
assert "dynamic_compression.enabled" in cli_paths
@@ -62,6 +64,7 @@ def test_dynamic_compression_applicator_sets_overrides_and_resolution() -> None:
6264
assert "dynamic_compression.per_output_evaluation_log_level" in cli_paths
6365
assert "dynamic_compression.file_detail_include_line_numbers" in cli_paths
6466
assert "dynamic_compression.disable_methods" in cli_paths
67+
assert "dynamic_compression.disable_tool_name_substrings" in cli_paths
6568

6669

6770
def test_dynamic_compression_applicator_is_noop_when_no_args() -> None:

tests/unit/core/config/test_dynamic_compression_config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ def test_dynamic_compression_env_is_loaded_and_tracked() -> None:
318318
"DYNAMIC_COMPRESSION_PER_OUTPUT_EVALUATION_LOG_LEVEL": "off",
319319
"DYNAMIC_COMPRESSION_FILE_DETAIL_INCLUDE_LINE_NUMBERS": "true",
320320
"DYNAMIC_COMPRESSION_DISABLE_METHODS": "ansi_normalize,line_dedupe",
321+
"DYNAMIC_COMPRESSION_DISABLE_TOOL_NAME_SUBSTRINGS": "fff,mcp_",
321322
},
322323
resolution=resolution,
323324
)
@@ -332,6 +333,7 @@ def test_dynamic_compression_env_is_loaded_and_tracked() -> None:
332333
"ansi_normalize",
333334
"line_dedupe",
334335
]
336+
assert cfg.dynamic_compression.disable_tool_name_substrings == ["fff", "mcp_"]
335337

336338
env_paths = set(resolution.latest_by_source(ParameterSource.ENVIRONMENT))
337339
assert "dynamic_compression.enabled" in env_paths
@@ -341,3 +343,4 @@ def test_dynamic_compression_env_is_loaded_and_tracked() -> None:
341343
assert "dynamic_compression.per_output_evaluation_log_level" in env_paths
342344
assert "dynamic_compression.file_detail_include_line_numbers" in env_paths
343345
assert "dynamic_compression.disable_methods" in env_paths
346+
assert "dynamic_compression.disable_tool_name_substrings" in env_paths

tests/unit/core/services/test_tool_output_compression_service.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,11 +1553,9 @@ async def test_service_skips_tool_matching_tool_name_substring() -> None:
15531553

15541554
result = await service.compress_messages(messages=messages, config=cfg)
15551555

1556-
assert result.records[0].applied is False, (
1557-
f"Expected applied=False, got {result.records[0].applied}. "
1558-
f"Identity: {result.records[0].identity}"
1559-
)
1560-
assert "tool_name_substring_disabled" in result.records[0].warnings
1556+
assert result.records[0].applied is False
1557+
assert result.messages[1].content == messages[1].content
1558+
assert result.records[0].methods == []
15611559

15621560

15631561
@pytest.mark.asyncio
@@ -1593,7 +1591,8 @@ async def test_service_skips_tool_matching_substring_anywhere_in_name() -> None:
15931591
result = await service.compress_messages(messages=messages, config=cfg)
15941592

15951593
assert result.records[0].applied is False
1596-
assert "tool_name_substring_disabled" in result.records[0].warnings
1594+
assert result.messages[1].content == messages[1].content
1595+
assert result.records[0].methods == []
15971596

15981597

15991598
@pytest.mark.asyncio
@@ -1620,7 +1619,7 @@ async def test_service_does_not_skip_tool_not_matching_substring() -> None:
16201619
CompressionRule(
16211620
name="default",
16221621
priority=1,
1623-
when=CompressionRulePredicate(tool_category="search"),
1622+
when=CompressionRulePredicate(),
16241623
pipeline=["half_trim"],
16251624
)
16261625
],
@@ -1629,6 +1628,7 @@ async def test_service_does_not_skip_tool_not_matching_substring() -> None:
16291628
result = await service.compress_messages(messages=messages, config=cfg)
16301629

16311630
assert result.records[0].applied is True
1631+
assert result.messages[1].content != messages[1].content
16321632

16331633

16341634
@pytest.mark.asyncio
@@ -1664,4 +1664,44 @@ async def test_tool_name_substring_is_case_insensitive() -> None:
16641664
result = await service.compress_messages(messages=messages, config=cfg)
16651665

16661666
assert result.records[0].applied is False
1667-
assert "tool_name_substring_disabled" in result.records[0].warnings
1667+
assert result.messages[1].content == messages[1].content
1668+
assert result.records[0].methods == []
1669+
1670+
1671+
@pytest.mark.asyncio
1672+
async def test_tool_name_substring_appears_in_effective_config_diagnostics() -> None:
1673+
registry = CompressionStrategyRegistry()
1674+
registry.register("half_trim", _HalfTrimStrategy())
1675+
service = ToolOutputCompressionService(
1676+
strategy_registry=registry,
1677+
identity_resolver=ToolIdentityResolver(),
1678+
selector=RuleBasedStrategySelector(),
1679+
)
1680+
messages = _build_messages_for_tool(
1681+
tool_name="grep_tool",
1682+
arguments='{"pattern":"target","path":"src"}',
1683+
output="src/a.py:10:def target()\n" * 100,
1684+
)
1685+
cfg = DynamicCompressionConfig(
1686+
enabled=True,
1687+
min_bytes=0,
1688+
marker=CompressionMarkerConfig(enabled=False),
1689+
methods={"half_trim": True},
1690+
disable_tool_name_substrings=["fff"],
1691+
rules=[
1692+
CompressionRule(
1693+
name="default",
1694+
priority=1,
1695+
when=CompressionRulePredicate(),
1696+
pipeline=["half_trim"],
1697+
)
1698+
],
1699+
)
1700+
1701+
result = await service.compress_messages(messages=messages, config=cfg)
1702+
1703+
assert result.effective_config is not None
1704+
assert (
1705+
"dynamic_compression.disable_tool_name_substrings.fff"
1706+
in result.effective_config.active_controls
1707+
)

0 commit comments

Comments
 (0)