refactor(ai_client): remove top-level SDK imports; use _require_warmed
Phase 3 T3.2 + T3.3 of startup_speedup_20260606 track. The 5 heavy SDKs (anthropic, google.genai, openai, google.genai.types, requests) are no longer imported at module level. Each function that needs them now calls _require_warmed(name) to get the module from sys.modules (populated by AppController's warmup on _io_pool). This is the load-bearing wall of the Main Thread Purity Invariant: heavy modules are never in the main thread's import chain. run_discussion_compression now uses _require_warmed for both google.genai.types (gemini branch) and requests (deepseek branch). Tests/test_tier4_patch_generation.py adapted: the 2 tests that mocked 'src.ai_client.types' (no longer a module-level attr) now mock 'src.ai_client._require_warmed' (the new public mechanism). T3.1 tests now pass (9/9). T3.3 breakage fixed. All 25 ai_client + tier4 tests pass.
This commit is contained in:
@@ -36,31 +36,33 @@ def test_run_tier4_patch_generation_empty_error() -> None:
|
||||
|
||||
def test_run_tier4_patch_generation_calls_ai() -> None:
|
||||
"""Test that run_tier4_patch_generation calls the AI with the correct prompt."""
|
||||
mock_types = MagicMock()
|
||||
mock_types.GenerateContentConfig = MagicMock()
|
||||
with patch("src.ai_client._ensure_gemini_client"), \
|
||||
patch("src.ai_client._gemini_client", create=True) as mock_client, \
|
||||
patch("src.ai_client.types") as mock_types:
|
||||
patch("src.ai_client._require_warmed", return_value=mock_types):
|
||||
mock_resp = MagicMock()
|
||||
mock_resp.text = "--- a/test.py\n+++ b/test.py\n@@ -1 +1 @@\n-old\n+new"
|
||||
mock_client.models.generate_content.return_value = mock_resp
|
||||
mock_types.GenerateContentConfig = MagicMock()
|
||||
|
||||
|
||||
error = "TypeError: unsupported operand"
|
||||
file_context = "def foo():\n pass"
|
||||
result = ai_client.run_tier4_patch_generation(error, file_context)
|
||||
|
||||
|
||||
mock_client.models.generate_content.assert_called()
|
||||
|
||||
def test_run_tier4_patch_generation_returns_diff() -> None:
|
||||
"""Test that run_tier4_patch_generation returns diff text."""
|
||||
mock_types = MagicMock()
|
||||
mock_types.GenerateContentConfig = MagicMock()
|
||||
with patch("src.ai_client._ensure_gemini_client"), \
|
||||
patch("src.ai_client._gemini_client", create=True) as mock_client, \
|
||||
patch("src.ai_client.types") as mock_types:
|
||||
patch("src.ai_client._require_warmed", return_value=mock_types):
|
||||
expected_diff = "--- a/src/test.py\n+++ b/src/test.py\n@@ -10,5 +10,6 @@\n def test_func():\n- old_value = 1\n+ old_value = 1\n+ new_value = 2"
|
||||
mock_resp = MagicMock()
|
||||
mock_resp.text = expected_diff
|
||||
mock_client.models.generate_content.return_value = mock_resp
|
||||
mock_types.GenerateContentConfig = MagicMock()
|
||||
|
||||
|
||||
result = ai_client.run_tier4_patch_generation("error", "context")
|
||||
assert "---" in result
|
||||
assert "+++" in result
|
||||
|
||||
Reference in New Issue
Block a user