diff --git a/src/timmy/tools.py b/src/timmy/tools.py index 79f9455..a751399 100644 --- a/src/timmy/tools.py +++ b/src/timmy/tools.py @@ -504,8 +504,11 @@ def create_full_toolkit(base_dir: str | Path | None = None): toolkit = Toolkit( name="full", - requires_confirmation_tools=list(DANGEROUS_TOOLS), ) + # Set requires_confirmation_tools AFTER construction (avoids agno WARNING + # about tools not yet registered) but BEFORE register() calls (so each + # Function gets requires_confirmation=True). Fixes #79. + toolkit.requires_confirmation_tools = list(DANGEROUS_TOOLS) # Web search (optional — degrades gracefully if ddgs not installed) if _DUCKDUCKGO_AVAILABLE: diff --git a/tests/timmy/test_timmy_tools.py b/tests/timmy/test_timmy_tools.py index 31f4d26..f3ccaa4 100644 --- a/tests/timmy/test_timmy_tools.py +++ b/tests/timmy/test_timmy_tools.py @@ -194,3 +194,38 @@ class TestAiderTool: catalog = get_all_available_tools() assert "aider" in catalog assert "forge" in catalog["aider"]["available_in"] + + +class TestFullToolkitConfirmationWarning: + """Regression tests for issue #79 — confirmation tool WARNING spam.""" + + def test_create_full_toolkit_no_confirmation_warning(self, caplog): + """create_full_toolkit should not emit 'Requires confirmation tool(s)' warnings. + + Agno's Toolkit.__init__ validates requires_confirmation_tools against the + initial (empty) tool list. We set the attribute *after* construction to + avoid the spurious warning while keeping per-tool confirmation checks. + """ + import logging + + from timmy.tools import create_full_toolkit + + with caplog.at_level(logging.WARNING): + create_full_toolkit() + + warning_msgs = [ + r.message for r in caplog.records if "Requires confirmation tool" in r.message + ] + assert warning_msgs == [], f"Unexpected confirmation warnings: {warning_msgs}" + + def test_dangerous_tools_listed_for_confirmation(self): + """After the fix, the toolkit still carries the full DANGEROUS_TOOLS list + so Agno can gate execution at runtime.""" + from timmy.tool_safety import DANGEROUS_TOOLS + from timmy.tools import create_full_toolkit + + toolkit = create_full_toolkit() + if toolkit is None: + pytest.skip("Agno tools not available") + + assert set(toolkit.requires_confirmation_tools) == set(DANGEROUS_TOOLS)