8414c59557
Five rounds of sweep across the tree. Net ~544 lines removed. Removed: - Section-divider banners and one-line section labels (# Display utilities, # ----- list_requests -----, # CVSS breakdown, etc.). - Module-level prose docstrings on internal modules. Kept one-line summaries; trimmed multi-paragraph narration about SDK/Strix responsibility splits, cache strategies, three-source precedence. - Internal-helper docstrings that just restate the function name — caido_api helpers (caido_url, get_client, view_request, etc.), settings-class one-liners (LLMSettings, RuntimeSettings, ...), UI helper docstrings. - Args/Returns blocks on non-LLM-facing internal helpers (build_strix_agent, render_system_prompt, create_or_reuse, bootstrap_caido) — kept only the genuinely non-obvious params. - Internal-history phrasing — "Mirrors main-branch shape", "pre-SDK harness", "previous lookup matched no attribute". - Narrative comments inside function bodies that explained what the next line does, design rationale obvious from the surrounding code, or "we used to..." asides. - Trailing periods on every error-string literal across the tool tree. - Duplicated roundtripTime quirk comment (kept the LLM-facing copy in tools/proxy/tools.py). Kept (every one names an upstream bug, vendored-code provenance, or non-obvious data quirk): - core/runner.py: SDK replay-with-empty-initial-input + on_agent_end lifecycle gap. - runtime/docker_client.py: VERBATIM COPY block of the upstream _create_container body, pinned to SDK v0.14.6. - runtime/session_manager.py: NO_PROXY for agent-browser CDP loopback. - tools/proxy/caido_api.py: generated-pydantic Request.raw quirk, replay double-history pitfall. - tools/proxy/tools.py: Caido roundtripTime=0 quirk for proxy captures. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
101 lines
2.8 KiB
Python
101 lines
2.8 KiB
Python
"""SDK model configuration helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import TYPE_CHECKING
|
|
|
|
from agents import set_default_openai_api, set_default_openai_key
|
|
from agents.retry import (
|
|
ModelRetryBackoffSettings,
|
|
ModelRetrySettings,
|
|
retry_policies,
|
|
)
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
from strix.config.settings import Settings
|
|
|
|
|
|
_SDK_PREFIXES = {"any-llm", "litellm", "openai"}
|
|
|
|
|
|
DEFAULT_MODEL_RETRY = ModelRetrySettings(
|
|
max_retries=5,
|
|
backoff=ModelRetryBackoffSettings(
|
|
initial_delay=2.0,
|
|
max_delay=90.0,
|
|
multiplier=2.0,
|
|
jitter=False,
|
|
),
|
|
policy=retry_policies.any(
|
|
retry_policies.provider_suggested(),
|
|
retry_policies.network_error(),
|
|
retry_policies.http_status((429, 500, 502, 503, 504)),
|
|
),
|
|
)
|
|
|
|
|
|
def configure_sdk_model_defaults(settings: Settings) -> None:
|
|
"""Apply Strix config to SDK-native defaults.
|
|
|
|
OpenAI-compatible base URLs are handled by the SDK OpenAI provider.
|
|
Non-OpenAI providers should use the SDK's native ``litellm/`` or
|
|
``any-llm/`` routing, produced by :func:`normalize_model_name`.
|
|
"""
|
|
llm = settings.llm
|
|
_configure_litellm_compatibility()
|
|
if llm.api_key:
|
|
set_default_openai_key(llm.api_key, use_for_tracing=False)
|
|
_configure_litellm_default("api_key", llm.api_key)
|
|
if llm.api_base:
|
|
os.environ["OPENAI_BASE_URL"] = llm.api_base
|
|
_configure_litellm_default("api_base", llm.api_base)
|
|
set_default_openai_api("chat_completions")
|
|
else:
|
|
set_default_openai_api("responses")
|
|
|
|
|
|
def _configure_litellm_compatibility() -> None:
|
|
"""Enable LiteLLM's permissive param-handling mode."""
|
|
import litellm
|
|
|
|
litellm.drop_params = True
|
|
litellm.modify_params = True
|
|
|
|
|
|
def _configure_litellm_default(name: str, value: str) -> None:
|
|
"""Set LiteLLM's module-level defaults without adding a provider wrapper."""
|
|
import litellm
|
|
|
|
setattr(litellm, name, value)
|
|
|
|
|
|
def normalize_model_name(model_name: str) -> str:
|
|
"""Normalize friendly Strix model names to SDK-native model ids."""
|
|
model = model_name.strip()
|
|
if not model:
|
|
return model
|
|
|
|
if "/" in model:
|
|
prefix = model.split("/", 1)[0].lower()
|
|
if prefix in _SDK_PREFIXES:
|
|
return model
|
|
return f"litellm/{model}"
|
|
|
|
lower = model.lower()
|
|
if lower.startswith("claude"):
|
|
return f"litellm/anthropic/{model}"
|
|
if lower.startswith("gemini"):
|
|
return f"litellm/gemini/{model}"
|
|
|
|
return model
|
|
|
|
|
|
def uses_chat_completions_tool_schema(model_name: str, settings: Settings) -> bool:
|
|
"""Return whether the resolved SDK route can only receive JSON function tools."""
|
|
model = model_name.strip().lower()
|
|
if model.startswith(("litellm/", "any-llm/")):
|
|
return True
|
|
return bool(settings.llm.api_base)
|