feat(ai_client): add send_result() public API returning Result[str]
This commit is contained in:
+88
-1
@@ -61,7 +61,7 @@ PROVIDERS: List[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minima
|
||||
# existing call sites and the T3.1 test (which asserts
|
||||
# hasattr(src.ai_client, '_require_warmed')) continue to work.
|
||||
from src.module_loader import _require_warmed # noqa: E402,F401
|
||||
from src.result_types import ErrorInfo, ErrorKind # noqa: E402,F401
|
||||
from src.result_types import ErrorInfo, ErrorKind, Result # noqa: E402,F401
|
||||
|
||||
|
||||
_provider: str = "gemini"
|
||||
@@ -2768,6 +2768,93 @@ def send(
|
||||
if monitor.enabled: monitor.end_component("ai_client.send")
|
||||
return res
|
||||
|
||||
def send_result(
|
||||
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,
|
||||
) -> Result[str]:
|
||||
"""
|
||||
[NEW] The Result-based public API. Returns Result[str, ErrorInfo].
|
||||
data is the response text on success; errors contains ErrorInfo on failure.
|
||||
[C: tests/test_ai_client_result.py:test_send_result_public_api_returns_result, tests/test_ai_client_result.py:test_send_result_preserves_errors, tests/test_deprecation_warnings.py:test_send_result_does_not_emit_deprecation]
|
||||
"""
|
||||
monitor = performance_monitor.get_monitor()
|
||||
if monitor.enabled: monitor.start_component("ai_client.send_result")
|
||||
|
||||
if rag_engine and getattr(rag_engine.config, "enabled", False) and "## Retrieved Context" not in user_message:
|
||||
chunks = rag_engine.search(user_message)
|
||||
if chunks:
|
||||
context_block = "## Retrieved Context\n\n"
|
||||
for i, chunk in enumerate(chunks):
|
||||
path = chunk.get("metadata", {}).get("path", "unknown")
|
||||
context_block += f"### Chunk {i+1} (Source: {path})\n{chunk.get('document', '')}\n\n"
|
||||
user_message = context_block + user_message
|
||||
|
||||
_append_comms("OUT", "request", {"message": user_message, "system": _get_combined_system_prompt(_active_tool_preset, _active_bias_profile)})
|
||||
with _send_lock:
|
||||
p = str(_provider).lower().strip()
|
||||
try:
|
||||
if p == "gemini":
|
||||
res = _send_gemini_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
pre_tool_callback, qa_callback, enable_tools, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "gemini_cli":
|
||||
res = _send_gemini_cli_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "anthropic":
|
||||
res = _send_anthropic_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
pre_tool_callback, qa_callback, stream_callback=stream_callback, patch_callback=patch_callback
|
||||
)
|
||||
elif p == "deepseek":
|
||||
res = _send_deepseek_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "minimax":
|
||||
res = _send_minimax_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "qwen":
|
||||
res = _send_qwen_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "llama":
|
||||
res = _send_llama_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "grok":
|
||||
res = _send_grok_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
elif p == "llama_native":
|
||||
res = _send_llama_native_result(
|
||||
md_content, user_message, base_dir, file_items, discussion_history,
|
||||
stream, pre_tool_callback, qa_callback, stream_callback, patch_callback
|
||||
)
|
||||
else:
|
||||
res = Result(data="", errors=[ErrorInfo(kind=ErrorKind.CONFIG, message=f"unknown provider: {_provider}", source="ai_client.send_result")])
|
||||
except Exception as exc:
|
||||
res = Result(data="", errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(exc), source="ai_client.send_result", original=exc)])
|
||||
if monitor.enabled: monitor.end_component("ai_client.send_result")
|
||||
return res
|
||||
|
||||
def _add_bleed_derived(d: dict[str, Any], sys_tok: int = 0, tool_tok: int = 0) -> dict[str, Any]:
|
||||
"""
|
||||
[C: tests/test_token_viz.py:test_add_bleed_derived_aliases, tests/test_token_viz.py:test_add_bleed_derived_breakdown, tests/test_token_viz.py:test_add_bleed_derived_headroom, tests/test_token_viz.py:test_add_bleed_derived_headroom_clamped_to_zero, tests/test_token_viz.py:test_add_bleed_derived_history_clamped_to_zero, tests/test_token_viz.py:test_add_bleed_derived_would_trim_false, tests/test_token_viz.py:test_add_bleed_derived_would_trim_true, tests/test_token_viz.py:test_would_trim_boundary_exact, tests/test_token_viz.py:test_would_trim_just_above_threshold, tests/test_token_viz.py:test_would_trim_just_below_threshold]
|
||||
|
||||
Reference in New Issue
Block a user