Private
Public Access
0
0

refactor(ai_client): remove deprecated send() function (Phase 6.1)

Removes the @deprecated send() function (was at src/ai_client.py:2939-3000)
and the from typing_extensions import deprecated import (line 38). The
function is replaced by send_result() which has been the canonical public
API since the data_oriented_error_handling_20260606 track (commit 9f86b2be).

All 3 production call sites (src/conductor_tech_lead.py:68,
src/orchestrator_pm.py:86, src/multi_agent_conductor.py:591) and 18 test
files were migrated in Phases 1-2; 4 pre-existing failures were fixed in
Phases 3-4. No remaining callers of ai_client.send(.

Verification:
- uv run rg 'def send\\(' src/ai_client.py returns 0 hits
- import src.ai_client; hasattr(ai, 'send') is False
- 73/73 migrated tests pass
This commit is contained in:
2026-06-15 18:48:44 -04:00
parent c50367c6d5
commit 8c81b727d6
-64
View File
@@ -35,7 +35,6 @@ from collections import deque
from pathlib import Path as _P
from pathlib import Path
from typing import Optional, Callable, Any, List, Union, cast, Iterable
from typing_extensions import deprecated
from src import project_manager
from src import file_cache
@@ -2936,69 +2935,6 @@ def get_token_stats(md_content: str) -> dict[str, Any]:
}
return _add_bleed_derived(stats, sys_tok=total_tokens)
@deprecated("Use ai_client.send_result() instead. The deprecated send() will be removed in the public_api_migration_20260606 track.")
def send(
md_content: str,
user_message: str,
base_dir: str = ".",
file_items: list[dict[str, Any]] | None = None,
discussion_history: str = "",
stream: bool = False,
pre_tool_callback: Optional[Callable[[str, str, Optional[Callable[[str], str]]], Optional[str]]] = None,
qa_callback: Optional[Callable[[str], str]] = None,
enable_tools: bool = True,
stream_callback: Optional[Callable[[str], None]] = None,
patch_callback: Optional[Callable[[str, str], Optional[str]]] = None,
rag_engine: Optional[Any] = None,
) -> str:
"""
[DEPRECATED] Sends a request to the configured AI provider and returns the raw response text.
Functional Purpose:
Acts as the legacy wrapper around send_result(). It extracts the string payload ('data')
from the returned Result container, logging warnings for any internal execution errors
to the communication logs, but suppressing the actual error objects from the caller.
Parameters & Inputs:
md_content (str): Base/system prompt template or markdown content.
user_message (str): The primary user instruction.
base_dir (str): Base workspace directory path (defaults to ".").
file_items (list[dict[str, Any]] | None): Optional list of active context files.
discussion_history (str): Contextual discussion history lines.
stream (bool): Whether to stream the response chunks.
pre_tool_callback (Optional[Callable]): Hook called before a tool call is executed.
qa_callback (Optional[Callable]): Hook for Tier 4 quality/validation checks.
enable_tools (bool): Controls whether LLM tool usage is enabled.
stream_callback (Optional[Callable]): Hook to stream response chunks to.
patch_callback (Optional[Callable]): Custom callback for interactive patch validation.
rag_engine (Optional[Any]): The RAG engine instance for retrieving vector context.
Returns:
str: The raw text response from the active AI provider.
Immediate-Mode DAG / Thread Context:
Called by: Various legacy scripts, tests, PM/Tech Lead orchestrators, and GUI event loops.
See list below.
Calls: send_result()
SSDL:
`[I:send_result] -> [T:text]`
Thread Boundaries:
Executes on whichever thread calls it (typically the GUI main thread, API hook handlers,
or a background async worker pool thread).
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/api_hooks.py:WebSocketServer._handler, src/api_hooks.py:WebSocketServer.broadcast, src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking, tests/test_ai_client_cli.py:test_ai_client_send_gemini_cli, tests/test_api_events.py:test_send_emits_events_proper, tests/test_api_events.py:test_send_emits_tool_events, tests/test_deepseek_provider.py:test_deepseek_completion_logic, tests/test_deepseek_provider.py:test_deepseek_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoning_logic, tests/test_deepseek_provider.py:test_deepseek_streaming, tests/test_deepseek_provider.py:test_deepseek_tool_calling, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_full_flow_integration, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_handles_tool_use_events, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_parses_jsonl_output, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_starts_subprocess_with_correct_args, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_parses_tool_calls_from_streaming_json, tests/test_gemini_cli_adapter_parity.py:TestGeminiCliAdapterParity.test_send_starts_subprocess_with_model, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_context_bleed_prevention, tests/test_gemini_cli_edge_cases.py:test_gemini_cli_loop_termination, tests/test_gemini_cli_integration.py:test_gemini_cli_full_integration, tests/test_gemini_cli_integration.py:test_gemini_cli_rejection_and_history, tests/test_gemini_cli_parity_regression.py:test_send_invokes_adapter_send, tests/test_gui2_mcp.py:test_mcp_tool_call_is_dispatched, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_token_usage.py:test_token_usage_tracking, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
"""
result = send_result(
md_content, user_message, base_dir, file_items, discussion_history,
stream, pre_tool_callback, qa_callback, enable_tools, stream_callback, patch_callback, rag_engine,
)
if not result.ok:
for err in result.errors:
_append_comms("WARN", "deprecated_send_with_errors", {"error": err.ui_message()})
return result.data
def send_result(
md_content: str,
user_message: str,