Merge pull request 'fix: replace print() with proper logging (#29, #51)' (#59) from fix/print-to-logging into main

This commit is contained in:
rockachopa
2026-03-14 16:34:48 -04:00
committed by Kimi Agent
6 changed files with 109 additions and 25 deletions

View File

@@ -302,3 +302,42 @@ def test_create_timmy_no_extra_kwargs():
f"Unknown Agent kwargs {invalid} — verify they exist in agno "
f"before adding to VALID_AGENT_KWARGS"
)
# ── skip_mcp flag (#72) ─────────────────────────────────────────────────────
def test_create_timmy_skip_mcp_omits_mcp_tools():
"""create_timmy(skip_mcp=True) must not add MCP tool servers."""
with (
patch("timmy.agent.Agent"),
patch("timmy.agent.Ollama"),
patch("timmy.agent.SqliteDb"),
patch("timmy.mcp_tools.create_gitea_mcp_tools") as mock_gitea_mcp,
patch("timmy.mcp_tools.create_filesystem_mcp_tools") as mock_fs_mcp,
):
from timmy.agent import create_timmy
create_timmy(skip_mcp=True)
# MCP factory functions should never be called
mock_gitea_mcp.assert_not_called()
mock_fs_mcp.assert_not_called()
def test_create_timmy_default_includes_mcp_tools():
"""create_timmy() without skip_mcp should attempt MCP tool creation."""
with (
patch("timmy.agent.Agent"),
patch("timmy.agent.Ollama"),
patch("timmy.agent.SqliteDb"),
patch("timmy.mcp_tools.create_gitea_mcp_tools", return_value=None) as mock_gitea_mcp,
patch("timmy.mcp_tools.create_filesystem_mcp_tools", return_value=None) as mock_fs_mcp,
):
from timmy.agent import create_timmy
create_timmy(skip_mcp=False)
# MCP factories should be called when skip_mcp is False
mock_gitea_mcp.assert_called_once()
mock_fs_mcp.assert_called_once()

View File

@@ -842,3 +842,46 @@ def test_thinking_chain_api_404(client):
"""GET /thinking/api/{bad_id}/chain should return 404."""
response = client.get("/thinking/api/nonexistent/chain")
assert response.status_code == 404
# ---------------------------------------------------------------------------
# _call_agent uses skip_mcp=True (#72)
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_call_agent_uses_skip_mcp(tmp_path):
"""_call_agent must create_timmy(skip_mcp=True) to avoid cancel-scope errors."""
engine = _make_engine(tmp_path)
mock_agent = AsyncMock()
mock_run = AsyncMock()
mock_run.content = "thought output"
mock_agent.arun.return_value = mock_run
with patch("timmy.agent.create_timmy", return_value=mock_agent) as mock_factory:
result = await engine._call_agent("test prompt")
mock_factory.assert_called_once_with(skip_mcp=True)
mock_agent.arun.assert_awaited_once_with("test prompt", stream=False)
assert result == "thought output"
@pytest.mark.asyncio
async def test_call_agent_does_not_use_session_chat(tmp_path):
"""_call_agent should NOT go through session.chat() (which uses the singleton
with MCP tools). It creates its own agent directly."""
engine = _make_engine(tmp_path)
mock_agent = AsyncMock()
mock_run = AsyncMock()
mock_run.content = "direct agent"
mock_agent.arun.return_value = mock_run
with (
patch("timmy.agent.create_timmy", return_value=mock_agent),
patch("timmy.session.chat", new_callable=AsyncMock) as mock_session_chat,
):
await engine._call_agent("prompt")
mock_session_chat.assert_not_awaited()