9e07fac1db
Per post_module_taxonomy_de_cruft_20260627 Phase 2 (FR7 continued).
The previous migration commit (8f11340b) handled the
'from src.models import X' pattern (85 sites). This commit handles
the 'models.<moved_class>' attribute access pattern (44 sites in 20
files), which the __getattr__ shim previously supported.
The migration was performed by the one-time script
scripts/tier2/artifacts/post_module_taxonomy_de_cruft_20260627/migrate_models_attr.py
which:
1. For each 'models.<moved_class>' reference, replaces it with the
bare class name (e.g., 'models.MCPConfiguration' -> 'MCPConfiguration')
2. Adds the import 'from src.<destination> import <moved_class>' at
the top of the file (deduplicated if the import already exists)
3. Skips moved classes that the file already imports directly
The migration script inserts the import after the 'from __future__
import annotations' line if present; otherwise it adds the import
to the destination module's existing import block. Two files
required manual fixes because the script's regex didn't handle them:
- src/rag_engine.py: uses 'from src import models' (not 'from
src.models import X'); the class is accessed
via 'models.RAGConfig'. Replaced with a
direct 'from src.mcp_client import RAGConfig'
import and removed the 'from src import models'.
- tests/test_project_context_20260627.py: uses the parens-style
multi-line 'from src.models import (X, Y, Z)'.
Replaced with the parens-style direct import.
After this commit:
- 'models.MCPConfiguration', 'models.FileItem', 'models.Ticket', etc.
no longer work in src/ and tests/ (the AttributeError raises
because models.py no longer has the __getattr__ entries for
moved classes)
- All consumer files have direct imports of the moved classes
Total: 44 'models.<moved_class>' references rewritten across 20 files.
56 lines
1.5 KiB
Python
56 lines
1.5 KiB
Python
import asyncio
|
|
import json
|
|
import sys
|
|
import pytest
|
|
from src import mcp_client
|
|
from src import models
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_external_mcp_real_process():
|
|
manager = mcp_client.ExternalMCPManager()
|
|
|
|
# Use our mock script
|
|
mock_script = "scripts/mock_mcp_server.py"
|
|
config = MCPServerConfig(
|
|
name="real-mock",
|
|
command="python",
|
|
args=[mock_script]
|
|
)
|
|
|
|
await manager.add_server(config)
|
|
|
|
try:
|
|
tools = manager.get_all_tools()
|
|
assert "echo" in tools
|
|
assert tools["echo"]["server"] == "real-mock"
|
|
|
|
result = await manager.async_dispatch("echo", {"hello": "world"})
|
|
assert "ECHO: {'hello': 'world'}" in result
|
|
finally:
|
|
await manager.stop_all()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_tool_schemas_includes_external():
|
|
manager = mcp_client.get_external_mcp_manager()
|
|
# Reset manager
|
|
await manager.stop_all()
|
|
|
|
mock_script = "scripts/mock_mcp_server.py"
|
|
config = MCPServerConfig(
|
|
name="test-server",
|
|
command="python",
|
|
args=[mock_script]
|
|
)
|
|
|
|
await manager.add_server(config)
|
|
|
|
try:
|
|
schemas = mcp_client.get_tool_schemas()
|
|
echo_schema = next((s for s in schemas if s["name"] == "echo"), None)
|
|
|
|
assert echo_schema is not None
|
|
assert echo_schema["description"] == "Echo input"
|
|
assert echo_schema["parameters"] == {"type": "object"}
|
|
finally:
|
|
await manager.stop_all()
|