some org on ai_client

This commit is contained in:
ed
2026-06-06 11:35:20 -04:00
parent 9d72d98b50
commit 9ccaf0594c
+40 -95
View File
@@ -14,6 +14,7 @@ during chat creation to avoid massive history bloat.
# ai_client.py # ai_client.py
import anthropic import anthropic
from google import genai from google import genai
from google.api_core import exceptions as gac
from google.genai import types from google.genai import types
from openai import OpenAI from openai import OpenAI
@@ -91,7 +92,6 @@ class ProviderError(Exception):
def set_model_params(temp: float, max_tok: int, trunc_limit: int = 8000, top_p: float = 1.0) -> None: def set_model_params(temp: float, max_tok: int, trunc_limit: int = 8000, top_p: float = 1.0) -> None:
""" """
Sets global generation parameters like temperature and max tokens. Sets global generation parameters like temperature and max tokens.
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate] [C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate]
""" """
@@ -148,7 +148,6 @@ _tool_approval_modes: dict[str, str] = {}
def get_current_tier() -> Optional[str]: def get_current_tier() -> Optional[str]:
""" """
Returns the current tier from thread-local storage. Returns the current tier from thread-local storage.
[C: src/app_controller.py:AppController._on_tool_log, tests/test_ai_client_concurrency.py:intercepted_append] [C: src/app_controller.py:AppController._on_tool_log, tests/test_ai_client_concurrency.py:intercepted_append]
""" """
@@ -156,7 +155,6 @@ def get_current_tier() -> Optional[str]:
def set_current_tier(tier: Optional[str]) -> None: def set_current_tier(tier: Optional[str]) -> None:
""" """
Sets the current tier in thread-local storage. Sets the current tier in thread-local storage.
[C: src/app_controller.py:AppController._handle_request_event, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_mma_agent_focus_phase1.py:reset_tier, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2] [C: src/app_controller.py:AppController._handle_request_event, src/conductor_tech_lead.py:generate_tickets, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_ai_client_concurrency.py:run_t1, tests/test_ai_client_concurrency.py:run_t2, tests/test_mma_agent_focus_phase1.py:reset_tier, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2]
""" """
@@ -198,7 +196,6 @@ _project_context_marker: str = ""
def set_custom_system_prompt(prompt: str) -> None: def set_custom_system_prompt(prompt: str) -> None:
""" """
Sets a custom system prompt to be combined with the default instructions. Sets a custom system prompt to be combined with the default instructions.
[C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, 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_system_prompt_exposure.py:TestSystemPromptExposure.setUp] [C: simulation/user_agent.py:UserSimAgent.generate_response, src/app_controller.py:AppController._do_generate, 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_system_prompt_exposure.py:TestSystemPromptExposure.setUp]
""" """
@@ -263,7 +260,6 @@ COMMS_CLAMP_CHARS: int = 300
def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]: def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
""" """
Returns the comms log callback (thread-local with global fallback). Returns the comms log callback (thread-local with global fallback).
[C: src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -273,7 +269,6 @@ def get_comms_log_callback() -> Optional[Callable[[dict[str, Any]], None]]:
def set_comms_log_callback(cb: Optional[Callable[[dict[str, Any]], None]]) -> None: def set_comms_log_callback(cb: Optional[Callable[[dict[str, Any]], None]]) -> None:
""" """
Sets the comms log callback (both global and thread-local). Sets the comms log callback (both global and thread-local).
[C: src/app_controller.py:AppController._init_ai_and_hooks, src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/app_controller.py:AppController._init_ai_and_hooks, src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -339,27 +334,18 @@ def _load_credentials() -> dict[str, Any]:
def _classify_anthropic_error(exc: Exception) -> ProviderError: def _classify_anthropic_error(exc: Exception) -> ProviderError:
try: try:
if isinstance(exc, anthropic.RateLimitError): if isinstance(exc, anthropic.RateLimitError): return ProviderError("rate_limit", "anthropic", exc)
return ProviderError("rate_limit", "anthropic", exc) if isinstance(exc, anthropic.AuthenticationError): return ProviderError("auth", "anthropic", exc)
if isinstance(exc, anthropic.AuthenticationError): if isinstance(exc, anthropic.PermissionDeniedError): return ProviderError("auth", "anthropic", exc)
return ProviderError("auth", "anthropic", exc) if isinstance(exc, anthropic.APIConnectionError): return ProviderError("network", "anthropic", exc)
if isinstance(exc, anthropic.PermissionDeniedError):
return ProviderError("auth", "anthropic", exc)
if isinstance(exc, anthropic.APIConnectionError):
return ProviderError("network", "anthropic", exc)
if isinstance(exc, anthropic.APIStatusError): if isinstance(exc, anthropic.APIStatusError):
status = getattr(exc, "status_code", 0) status = getattr(exc, "status_code", 0)
body = str(exc).lower() body = str(exc).lower()
if status == 429: if status == 429: return ProviderError("rate_limit", "anthropic", exc)
return ProviderError("rate_limit", "anthropic", exc) if status in (401, 403): return ProviderError("auth", "anthropic", exc)
if status in (401, 403): if status == 402: return ProviderError("balance", "anthropic", exc)
return ProviderError("auth", "anthropic", exc) if "credit" in body or "balance" in body or "billing" in body: return ProviderError("balance", "anthropic", exc)
if status == 402: if "quota" in body or "limit" in body or "exceeded" in body: return ProviderError("quota", "anthropic", exc)
return ProviderError("balance", "anthropic", exc)
if "credit" in body or "balance" in body or "billing" in body:
return ProviderError("balance", "anthropic", exc)
if "quota" in body or "limit" in body or "exceeded" in body:
return ProviderError("quota", "anthropic", exc)
except ImportError: except ImportError:
pass pass
return ProviderError("unknown", "anthropic", exc) return ProviderError("unknown", "anthropic", exc)
@@ -367,27 +353,17 @@ def _classify_anthropic_error(exc: Exception) -> ProviderError:
def _classify_gemini_error(exc: Exception) -> ProviderError: def _classify_gemini_error(exc: Exception) -> ProviderError:
body = str(exc).lower() body = str(exc).lower()
try: try:
from google.api_core import exceptions as gac if isinstance(exc, gac.ResourceExhausted): return ProviderError("quota", "gemini", exc)
if isinstance(exc, gac.ResourceExhausted): if isinstance(exc, gac.TooManyRequests): return ProviderError("rate_limit", "gemini", exc)
return ProviderError("quota", "gemini", exc) if isinstance(exc, (gac.Unauthenticated, gac.PermissionDenied)): return ProviderError("auth", "gemini", exc)
if isinstance(exc, gac.TooManyRequests): if isinstance(exc, gac.ServiceUnavailable): return ProviderError("network", "gemini", exc)
return ProviderError("rate_limit", "gemini", exc)
if isinstance(exc, (gac.Unauthenticated, gac.PermissionDenied)):
return ProviderError("auth", "gemini", exc)
if isinstance(exc, gac.ServiceUnavailable):
return ProviderError("network", "gemini", exc)
except ImportError: except ImportError:
pass pass
if "429" in body or "quota" in body or "resource exhausted" in body: if "429" in body or "quota" in body or "resource exhausted" in body: return ProviderError("quota", "gemini", exc)
return ProviderError("quota", "gemini", exc) if "rate" in body and "limit" in body: return ProviderError("rate_limit", "gemini", exc)
if "rate" in body and "limit" in body: if "401" in body or "403" in body or "api key" in body or "unauthenticated" in body: return ProviderError("auth", "gemini", exc)
return ProviderError("rate_limit", "gemini", exc) if "402" in body or "billing" in body or "balance" in body or "payment" in body: return ProviderError("balance", "gemini", exc)
if "401" in body or "403" in body or "api key" in body or "unauthenticated" in body: if "connection" in body or "timeout" in body or "unreachable" in body: return ProviderError("network", "gemini", exc)
return ProviderError("auth", "gemini", exc)
if "402" in body or "billing" in body or "balance" in body or "payment" in body:
return ProviderError("balance", "gemini", exc)
if "connection" in body or "timeout" in body or "unreachable" in body:
return ProviderError("network", "gemini", exc)
return ProviderError("unknown", "gemini", exc) return ProviderError("unknown", "gemini", exc)
def _classify_deepseek_error(exc: Exception) -> ProviderError: def _classify_deepseek_error(exc: Exception) -> ProviderError:
@@ -396,31 +372,21 @@ def _classify_deepseek_error(exc: Exception) -> ProviderError:
try: try:
# Try to get the detailed error from DeepSeek's JSON response # Try to get the detailed error from DeepSeek's JSON response
err_data = exc.response.json() err_data = exc.response.json()
if "error" in err_data: if "error" in err_data: body = str(err_data["error"].get("message", exc.response.text))
body = str(err_data["error"].get("message", exc.response.text)) else: body = exc.response.text
else:
body = exc.response.text
except: except:
body = exc.response.text body = exc.response.text
else: else:
body = str(exc) body = str(exc)
body_l = body.lower() body_l = body.lower()
if "429" in body_l or "rate" in body_l: if "429" in body_l or "rate" in body_l: return ProviderError("rate_limit", "deepseek", Exception(body))
return ProviderError("rate_limit", "deepseek", Exception(body)) if "401" in body_l or "403" in body_l or "auth" in body_l or "api key" in body_l: return ProviderError("auth", "deepseek", Exception(body))
if "401" in body_l or "403" in body_l or "auth" in body_l or "api key" in body_l: if "402" in body_l or "balance" in body_l or "billing" in body_l: return ProviderError("balance", "deepseek", Exception(body))
return ProviderError("auth", "deepseek", Exception(body)) if "quota" in body_l or "limit exceeded" in body_l: return ProviderError("quota", "deepseek", Exception(body))
if "402" in body_l or "balance" in body_l or "billing" in body_l: if "connection" in body_l or "timeout" in body_l or "network" in body_l: return ProviderError("network", "deepseek", Exception(body))
return ProviderError("balance", "deepseek", Exception(body))
if "quota" in body_l or "limit exceeded" in body_l:
return ProviderError("quota", "deepseek", Exception(body))
if "connection" in body_l or "timeout" in body_l or "network" in body_l:
return ProviderError("network", "deepseek", Exception(body))
# If we have a body for a 400 error, wrap it # If we have a body for a 400 error, wrap it
if "400" in body_l or "bad request" in body_l: if "400" in body_l or "bad request" in body_l: return ProviderError("unknown", "deepseek", Exception(f"DeepSeek Bad Request: {body}"))
return ProviderError("unknown", "deepseek", Exception(f"DeepSeek Bad Request: {body}"))
return ProviderError("unknown", "deepseek", Exception(body)) return ProviderError("unknown", "deepseek", Exception(body))
def _classify_minimax_error(exc: Exception) -> ProviderError: def _classify_minimax_error(exc: Exception) -> ProviderError:
@@ -428,35 +394,25 @@ def _classify_minimax_error(exc: Exception) -> ProviderError:
if isinstance(exc, requests.exceptions.HTTPError) and exc.response is not None: if isinstance(exc, requests.exceptions.HTTPError) and exc.response is not None:
try: try:
err_data = exc.response.json() err_data = exc.response.json()
if "error" in err_data: if "error" in err_data: body = str(err_data["error"].get("message", exc.response.text))
body = str(err_data["error"].get("message", exc.response.text)) else: body = exc.response.text
else:
body = exc.response.text
except: except:
body = exc.response.text body = exc.response.text
else: else:
body = str(exc) body = str(exc)
body_l = body.lower() body_l = body.lower()
if "429" in body_l or "rate" in body_l: if "429" in body_l or "rate" in body_l: return ProviderError("rate_limit", "minimax", Exception(body))
return ProviderError("rate_limit", "minimax", Exception(body)) if "401" in body_l or "403" in body_l or "auth" in body_l or "api key" in body_l: return ProviderError("auth", "minimax", Exception(body))
if "401" in body_l or "403" in body_l or "auth" in body_l or "api key" in body_l: if "402" in body_l or "balance" in body_l or "billing" in body_l: return ProviderError("balance", "minimax", Exception(body))
return ProviderError("auth", "minimax", Exception(body)) if "quota" in body_l or "limit exceeded" in body_l: return ProviderError("quota", "minimax", Exception(body))
if "402" in body_l or "balance" in body_l or "billing" in body_l: if "connection" in body_l or "timeout" in body_l or "network" in body_l: return ProviderError("network", "minimax", Exception(body))
return ProviderError("balance", "minimax", Exception(body))
if "quota" in body_l or "limit exceeded" in body_l:
return ProviderError("quota", "minimax", Exception(body))
if "connection" in body_l or "timeout" in body_l or "network" in body_l:
return ProviderError("network", "minimax", Exception(body))
if "400" in body_l or "bad request" in body_l:
return ProviderError("unknown", "minimax", Exception(f"MiniMax Bad Request: {body}"))
if "400" in body_l or "bad request" in body_l: return ProviderError("unknown", "minimax", Exception(f"MiniMax Bad Request: {body}"))
return ProviderError("unknown", "minimax", Exception(body)) return ProviderError("unknown", "minimax", Exception(body))
def set_provider(provider: str, model: str) -> None: def set_provider(provider: str, model: str) -> None:
""" """
Updates the active LLM provider and model name. Updates the active LLM provider and model name.
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.do_fetch, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/conftest.py:reset_ai_client, 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_model_selection, 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_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_minimax_provider.py:test_minimax_default_model, tests/test_minimax_provider.py:test_minimax_model_selection, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_rag_integration.py:test_rag_integration, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script, tests/test_token_usage.py:test_token_usage_tracking] [C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController._init_ai_and_hooks, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.do_fetch, src/multi_agent_conductor.py:run_worker_lifecycle, src/orchestrator_pm.py:generate_tracks, tests/conftest.py:reset_ai_client, 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_model_selection, 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_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_minimax_provider.py:test_minimax_default_model, tests/test_minimax_provider.py:test_minimax_model_selection, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_rag_integration.py:test_rag_integration, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tier4_interceptor.py:test_gemini_provider_passes_qa_callback_to_run_script, tests/test_token_usage.py:test_token_usage_tracking]
""" """
@@ -483,7 +439,6 @@ def set_provider(provider: str, model: str) -> None:
def get_provider() -> str: def get_provider() -> str:
""" """
Returns the current active provider name. Returns the current active provider name.
[C: src/multi_agent_conductor.py:run_worker_lifecycle] [C: src/multi_agent_conductor.py:run_worker_lifecycle]
""" """
@@ -491,7 +446,6 @@ def get_provider() -> str:
def cleanup() -> None: def cleanup() -> None:
""" """
Performs cleanup operations like deleting server-side Gemini caches. Performs cleanup operations like deleting server-side Gemini caches.
[C: src/app_controller.py:AppController.clear_cache, src/app_controller.py:AppController.shutdown, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking_cleanup, tests/test_log_registry.py:TestLogRegistry.tearDown, tests/test_project_serialization.py:TestProjectSerialization.tearDown] [C: src/app_controller.py:AppController.clear_cache, src/app_controller.py:AppController.shutdown, tests/test_ai_cache_tracking.py:test_gemini_cache_tracking_cleanup, tests/test_log_registry.py:TestLogRegistry.tearDown, tests/test_project_serialization.py:TestProjectSerialization.tearDown]
""" """
@@ -505,7 +459,6 @@ def cleanup() -> None:
def reset_session() -> None: def reset_session() -> None:
""" """
Clears conversation history and resets provider-specific session state. Clears conversation history and resets provider-specific session state.
[C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, 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_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, 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_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking] [C: src/app_controller.py:AppController._handle_reset_session, src/app_controller.py:AppController.current_model, src/app_controller.py:AppController.current_provider, src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_provider_panel, src/gui_2.py:App._show_menus, src/multi_agent_conductor.py:run_worker_lifecycle, tests/conftest.py:live_gui, tests/conftest.py:reset_ai_client, 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_payload_verification, tests/test_deepseek_provider.py:test_deepseek_reasoner_payload_verification, 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_metrics.py:test_get_gemini_cache_stats_with_mock_client, tests/test_headless_simulation.py:test_mma_track_lifecycle_simulation, tests/test_mma_agent_focus_phase1.py:test_append_comms_has_source_tier_key, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_none_when_unset, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_set_when_current_tier_set, tests/test_mma_agent_focus_phase1.py:test_append_comms_source_tier_tier2, tests/test_session_logger_reset.py:test_reset_session, tests/test_token_usage.py:test_token_usage_tracking]
""" """
@@ -533,7 +486,6 @@ def reset_session() -> None:
_gemini_cli_adapter = GeminiCliAdapter(binary_path=old_path) _gemini_cli_adapter = GeminiCliAdapter(binary_path=old_path)
_anthropic_client = None _anthropic_client = None
with _anthropic_history_lock: with _anthropic_history_lock:
_anthropic_history = [] _anthropic_history = []
_deepseek_client = None _deepseek_client = None
@@ -551,16 +503,11 @@ def list_models(provider: str) -> list[str]:
[C: src/app_controller.py:AppController.do_fetch, tests/test_agent_capabilities.py:test_agent_capabilities_listing, tests/test_ai_client_list_models.py:test_list_models_gemini_cli, tests/test_deepseek_infra.py:test_deepseek_model_listing, tests/test_minimax_provider.py:test_minimax_list_models] [C: src/app_controller.py:AppController.do_fetch, tests/test_agent_capabilities.py:test_agent_capabilities_listing, tests/test_ai_client_list_models.py:test_list_models_gemini_cli, tests/test_deepseek_infra.py:test_deepseek_model_listing, tests/test_minimax_provider.py:test_minimax_list_models]
""" """
creds = _load_credentials() creds = _load_credentials()
if provider == "gemini": if provider == "gemini": return _list_gemini_models(creds["gemini"]["api_key"])
return _list_gemini_models(creds["gemini"]["api_key"]) elif provider == "anthropic": return _list_anthropic_models()
elif provider == "anthropic": elif provider == "deepseek": return _list_deepseek_models(creds["deepseek"]["api_key"])
return _list_anthropic_models() elif provider == "gemini_cli": return _list_gemini_cli_models()
elif provider == "deepseek": elif provider == "minimax": return _list_minimax_models(creds["minimax"]["api_key"])
return _list_deepseek_models(creds["deepseek"]["api_key"])
elif provider == "gemini_cli":
return _list_gemini_cli_models()
elif provider == "minimax":
return _list_minimax_models(creds["minimax"]["api_key"])
return [] return []
#endregion: Comms Log #endregion: Comms Log
@@ -573,7 +520,6 @@ _agent_tools: dict[str, bool] = {}
def set_agent_tools(tools: dict[str, bool]) -> None: def set_agent_tools(tools: dict[str, bool]) -> None:
""" """
Configures which tools are enabled for the AI agent. Configures which tools are enabled for the AI agent.
[C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches] [C: src/app_controller.py:AppController._handle_request_event, src/app_controller.py:_api_generate, tests/test_agent_tools_wiring.py:test_build_anthropic_tools_conversion, tests/test_agent_tools_wiring.py:test_set_agent_tools, tests/test_tool_access_exclusion.py:test_build_anthropic_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_build_deepseek_tools_excludes_disabled, tests/test_tool_access_exclusion.py:test_gemini_tool_declaration_excludes_disabled, tests/test_tool_access_exclusion.py:test_set_agent_tools_clears_caches]
""" """
@@ -584,7 +530,6 @@ def set_agent_tools(tools: dict[str, bool]) -> None:
def set_tool_preset(preset_name: Optional[str]) -> None: def set_tool_preset(preset_name: Optional[str]) -> None:
""" """
Loads a tool preset and applies it via set_agent_tools. Loads a tool preset and applies it via set_agent_tools.
[C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_bias_integration.py:test_set_tool_preset_with_objects, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_execution.py:test_tool_ask_approval, tests/test_tool_presets_execution.py:test_tool_auto_approval, tests/test_tool_presets_execution.py:test_tool_rejection] [C: src/app_controller.py:AppController.init_state, src/gui_2.py:App._render_persona_selector_panel, src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_bias_integration.py:test_set_tool_preset_with_objects, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_execution.py:test_tool_ask_approval, tests/test_tool_presets_execution.py:test_tool_auto_approval, tests/test_tool_presets_execution.py:test_tool_rejection]
""" """