mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 07:56:52 +08:00
refactor(config): retire RuntimeSettingsCompat host usage
This commit is contained in:
+27
-28
@@ -13,9 +13,8 @@ from typing import Any, Dict, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from app.application.notification import get_notification_configs
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
from app.runtime.log import logger
|
||||
from app.adapters.network.http import RequestUtils
|
||||
|
||||
@@ -61,11 +60,11 @@ class OpenAIAudioProvider(AudioCapabilityProvider):
|
||||
|
||||
@staticmethod
|
||||
def _input_credentials() -> tuple[Optional[str], Optional[str]]:
|
||||
return settings.AUDIO_INPUT_API_KEY, settings.AUDIO_INPUT_BASE_URL
|
||||
return get_runtime_setting('AUDIO_INPUT_API_KEY'), get_runtime_setting('AUDIO_INPUT_BASE_URL')
|
||||
|
||||
@staticmethod
|
||||
def _output_credentials() -> tuple[Optional[str], Optional[str]]:
|
||||
return settings.AUDIO_OUTPUT_API_KEY, settings.AUDIO_OUTPUT_BASE_URL
|
||||
return get_runtime_setting('AUDIO_OUTPUT_API_KEY'), get_runtime_setting('AUDIO_OUTPUT_BASE_URL')
|
||||
|
||||
def is_available_for_audio_input(self) -> bool:
|
||||
api_key, _ = self._input_credentials()
|
||||
@@ -89,9 +88,9 @@ class OpenAIAudioProvider(AudioCapabilityProvider):
|
||||
audio_file = BytesIO(content)
|
||||
audio_file.name = filename
|
||||
response = client.audio.transcriptions.create(
|
||||
model=settings.AUDIO_INPUT_MODEL,
|
||||
model=get_runtime_setting('AUDIO_INPUT_MODEL'),
|
||||
file=audio_file,
|
||||
language=settings.AUDIO_INPUT_LANGUAGE or "zh",
|
||||
language=get_runtime_setting('AUDIO_INPUT_LANGUAGE') or "zh",
|
||||
response_format="verbose_json",
|
||||
)
|
||||
text = getattr(response, "text", None)
|
||||
@@ -109,12 +108,12 @@ class OpenAIAudioProvider(AudioCapabilityProvider):
|
||||
if not api_key:
|
||||
raise ValueError("音频输出 provider 未配置 API Key")
|
||||
client = self._build_client(api_key=api_key, base_url=base_url)
|
||||
voice_dir = settings.TEMP_PATH / "voice"
|
||||
voice_dir = get_runtime_setting('TEMP_PATH') / "voice"
|
||||
voice_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = voice_dir / f"{uuid4().hex}.opus"
|
||||
response = client.audio.speech.create(
|
||||
model=settings.AUDIO_OUTPUT_MODEL,
|
||||
voice=settings.AUDIO_OUTPUT_VOICE,
|
||||
model=get_runtime_setting('AUDIO_OUTPUT_MODEL'),
|
||||
voice=get_runtime_setting('AUDIO_OUTPUT_VOICE'),
|
||||
input=text,
|
||||
response_format="opus",
|
||||
)
|
||||
@@ -163,22 +162,22 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
|
||||
@staticmethod
|
||||
def _input_credentials() -> tuple[Optional[str], Optional[str]]:
|
||||
return settings.AUDIO_INPUT_API_KEY, settings.AUDIO_INPUT_BASE_URL
|
||||
return get_runtime_setting('AUDIO_INPUT_API_KEY'), get_runtime_setting('AUDIO_INPUT_BASE_URL')
|
||||
|
||||
@staticmethod
|
||||
def _output_credentials() -> tuple[Optional[str], Optional[str]]:
|
||||
return settings.AUDIO_OUTPUT_API_KEY, settings.AUDIO_OUTPUT_BASE_URL
|
||||
return get_runtime_setting('AUDIO_OUTPUT_API_KEY'), get_runtime_setting('AUDIO_OUTPUT_BASE_URL')
|
||||
|
||||
def _normalize_stt_model(self) -> str:
|
||||
return self._normalize_model(
|
||||
model=settings.AUDIO_INPUT_MODEL,
|
||||
model=get_runtime_setting('AUDIO_INPUT_MODEL'),
|
||||
supported_models=self.SUPPORTED_STT_MODELS,
|
||||
default_model=self.DEFAULT_STT_MODEL,
|
||||
)
|
||||
|
||||
def _normalize_tts_model(self) -> str:
|
||||
return self._normalize_model(
|
||||
model=settings.AUDIO_OUTPUT_MODEL,
|
||||
model=get_runtime_setting('AUDIO_OUTPUT_MODEL'),
|
||||
supported_models=self.SUPPORTED_TTS_MODELS,
|
||||
default_model=self.DEFAULT_TTS_MODEL,
|
||||
)
|
||||
@@ -268,7 +267,7 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
return None
|
||||
|
||||
suffix = Path(filename or "").suffix.lower() or ".audio"
|
||||
voice_dir = settings.TEMP_PATH / "voice"
|
||||
voice_dir = get_runtime_setting('TEMP_PATH') / "voice"
|
||||
voice_dir.mkdir(parents=True, exist_ok=True)
|
||||
input_path = voice_dir / f"{uuid4().hex}{suffix}"
|
||||
output_path = input_path.with_suffix(self.TRANSCODED_STT_SUFFIX)
|
||||
@@ -391,7 +390,7 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
if not normalized_audio:
|
||||
return None
|
||||
content, filename = normalized_audio
|
||||
language = (settings.AUDIO_INPUT_LANGUAGE or "").strip()
|
||||
language = (get_runtime_setting('AUDIO_INPUT_LANGUAGE') or "").strip()
|
||||
prompt = "请将这段音频完整转写为文字,只输出转写结果,不要添加解释。"
|
||||
if language:
|
||||
prompt += f"音频主要语言是 {language}。"
|
||||
@@ -426,7 +425,7 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
logger.error(
|
||||
"%s TTS 当前不支持该模型或模型未配置: %s",
|
||||
self.DISPLAY_NAME,
|
||||
settings.AUDIO_OUTPUT_MODEL,
|
||||
get_runtime_setting('AUDIO_OUTPUT_MODEL'),
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -435,7 +434,7 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
if not api_key:
|
||||
raise ValueError("音频输出 provider 未配置 API Key")
|
||||
client = self._build_client(api_key=api_key, base_url=base_url)
|
||||
voice_dir = settings.TEMP_PATH / "voice"
|
||||
voice_dir = get_runtime_setting('TEMP_PATH') / "voice"
|
||||
voice_dir.mkdir(parents=True, exist_ok=True)
|
||||
wav_path = voice_dir / f"{uuid4().hex}.wav"
|
||||
request = {
|
||||
@@ -448,7 +447,7 @@ class OpenAIChatAudioProvider(AudioCapabilityProvider):
|
||||
],
|
||||
"audio": {
|
||||
"format": self.AUDIO_RESPONSE_FORMAT,
|
||||
"voice": settings.AUDIO_OUTPUT_VOICE or self.DEFAULT_VOICE,
|
||||
"voice": get_runtime_setting('AUDIO_OUTPUT_VOICE') or self.DEFAULT_VOICE,
|
||||
},
|
||||
}
|
||||
if self.INCLUDE_AUDIO_MODALITIES:
|
||||
@@ -487,7 +486,7 @@ class MiMoAudioProvider(OpenAIChatAudioProvider):
|
||||
)
|
||||
|
||||
def _normalize_tts_model(self) -> str:
|
||||
model = (settings.AUDIO_OUTPUT_MODEL or "").strip().lower()
|
||||
model = (get_runtime_setting('AUDIO_OUTPUT_MODEL') or "").strip().lower()
|
||||
if not model or not model.startswith("mimo-"):
|
||||
return self.DEFAULT_TTS_MODEL
|
||||
return model
|
||||
@@ -546,21 +545,21 @@ class MiniMaxAudioProvider(OpenAIChatAudioProvider):
|
||||
|
||||
def _normalize_stt_model(self) -> str:
|
||||
"""将非 MiniMax 的默认转写模型名兜底为 MiniMax 对话模型。"""
|
||||
model = (settings.AUDIO_INPUT_MODEL or "").strip()
|
||||
model = (get_runtime_setting('AUDIO_INPUT_MODEL') or "").strip()
|
||||
if not model or model.lower().startswith(("gpt-", "mimo-")):
|
||||
return self.DEFAULT_STT_MODEL
|
||||
return model
|
||||
|
||||
def _normalize_tts_model(self) -> str:
|
||||
"""将非 MiniMax 语音模型兜底为官方 T2A 模型。"""
|
||||
model = (settings.AUDIO_OUTPUT_MODEL or "").strip().lower()
|
||||
model = (get_runtime_setting('AUDIO_OUTPUT_MODEL') or "").strip().lower()
|
||||
if model in self.SUPPORTED_TTS_MODELS:
|
||||
return model
|
||||
return self.DEFAULT_TTS_MODEL
|
||||
|
||||
def _normalize_voice_id(self) -> str:
|
||||
"""将其他 provider 的默认音色兜底为 MiniMax 中文系统音色。"""
|
||||
voice_id = (settings.AUDIO_OUTPUT_VOICE or "").strip()
|
||||
voice_id = (get_runtime_setting('AUDIO_OUTPUT_VOICE') or "").strip()
|
||||
if not voice_id or voice_id in {"alloy", "mimo_default"}:
|
||||
return self.DEFAULT_VOICE
|
||||
return voice_id
|
||||
@@ -599,7 +598,7 @@ class MiniMaxAudioProvider(OpenAIChatAudioProvider):
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
},
|
||||
proxies=settings.PROXY or {},
|
||||
proxies=get_runtime_setting('PROXY') or {},
|
||||
timeout=60,
|
||||
).post_res(
|
||||
url=self._build_t2a_url(base_url),
|
||||
@@ -637,7 +636,7 @@ class MiniMaxAudioProvider(OpenAIChatAudioProvider):
|
||||
if not audio_data:
|
||||
raise ValueError("MiniMax T2A 响应中没有音频数据")
|
||||
|
||||
voice_dir = settings.TEMP_PATH / "voice"
|
||||
voice_dir = get_runtime_setting('TEMP_PATH') / "voice"
|
||||
voice_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = voice_dir / f"{uuid4().hex}.opus"
|
||||
output_path.write_bytes(self._decode_audio_payload(audio_data))
|
||||
@@ -681,9 +680,9 @@ class AgentCapabilityManager:
|
||||
@classmethod
|
||||
def get_audio_provider(cls, mode: str) -> Optional[AudioCapabilityProvider]:
|
||||
provider_name = cls._normalize_provider_name(
|
||||
settings.AUDIO_INPUT_PROVIDER
|
||||
get_runtime_setting('AUDIO_INPUT_PROVIDER')
|
||||
if (mode or "").lower() == "input"
|
||||
else settings.AUDIO_OUTPUT_PROVIDER
|
||||
else get_runtime_setting('AUDIO_OUTPUT_PROVIDER')
|
||||
)
|
||||
provider = cls._audio_providers.get(provider_name)
|
||||
if provider:
|
||||
@@ -701,12 +700,12 @@ class AgentCapabilityManager:
|
||||
@staticmethod
|
||||
def supports_audio_input() -> bool:
|
||||
"""当前 Agent 是否启用音频输入能力。"""
|
||||
return bool(settings.LLM_SUPPORT_AUDIO_INPUT)
|
||||
return bool(get_runtime_setting('LLM_SUPPORT_AUDIO_INPUT'))
|
||||
|
||||
@staticmethod
|
||||
def supports_audio_output() -> bool:
|
||||
"""当前 Agent 是否启用音频输出能力。"""
|
||||
return bool(settings.LLM_SUPPORT_AUDIO_OUTPUT)
|
||||
return bool(get_runtime_setting('LLM_SUPPORT_AUDIO_OUTPUT'))
|
||||
|
||||
@classmethod
|
||||
def is_audio_input_available(cls) -> bool:
|
||||
|
||||
+24
-26
@@ -11,10 +11,8 @@ from urllib.parse import urlsplit
|
||||
from langchain_core.messages import AIMessage, AIMessageChunk
|
||||
|
||||
from app.agent.llm.gateway import resolve_llm_provider_runtime
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.agent.llm.server_tools import ServerToolResolution
|
||||
@@ -148,8 +146,8 @@ def _resolve_llm_proxy(use_proxy: bool | None = None) -> str | None:
|
||||
"""
|
||||
解析本次 LLM 调用应使用的系统代理地址。
|
||||
"""
|
||||
should_use_proxy = settings.LLM_USE_PROXY if use_proxy is None else use_proxy
|
||||
return settings.PROXY_HOST if should_use_proxy and settings.PROXY_HOST else None
|
||||
should_use_proxy = get_runtime_setting('LLM_USE_PROXY') if use_proxy is None else use_proxy
|
||||
return get_runtime_setting('PROXY_HOST') if should_use_proxy and get_runtime_setting('PROXY_HOST') else None
|
||||
|
||||
|
||||
def _build_httpx_proxy_kwargs(proxy_url: str | None) -> dict[str, str]:
|
||||
@@ -539,7 +537,7 @@ class LLMHelper:
|
||||
record_input = cls._source_input_limit(model_record)
|
||||
metadata_input = cls._source_input_limit(metadata_source)
|
||||
profile_input = cls._positive_token_limit(profile.get("max_input_tokens"))
|
||||
configured_k = cls._positive_token_limit(settings.LLM_MAX_CONTEXT_TOKENS)
|
||||
configured_k = cls._positive_token_limit(get_runtime_setting('LLM_MAX_CONTEXT_TOKENS'))
|
||||
configured_input = configured_k * 1000 if configured_k else None
|
||||
|
||||
endpoint_matched = runtime.get("model_profile_endpoint_matched") is True
|
||||
@@ -790,8 +788,8 @@ class LLMHelper:
|
||||
base_url_preset: Optional[str] = None,
|
||||
) -> Optional[bool]:
|
||||
"""复用 provider 目录缓存解析当前模型是否支持图片输入。"""
|
||||
provider_name = str(provider if provider is not None else settings.LLM_PROVIDER).strip()
|
||||
model_name = str(model if model is not None else settings.LLM_MODEL).strip()
|
||||
provider_name = str(provider if provider is not None else get_runtime_setting('LLM_PROVIDER')).strip()
|
||||
model_name = str(model if model is not None else get_runtime_setting('LLM_MODEL')).strip()
|
||||
if not provider_name or not model_name:
|
||||
return None
|
||||
|
||||
@@ -799,11 +797,11 @@ class LLMHelper:
|
||||
metadata = resolve_llm_provider_runtime().resolve_cached_model_metadata(
|
||||
provider_id=provider_name,
|
||||
model_id=model_name,
|
||||
base_url=base_url if base_url is not None else settings.LLM_BASE_URL,
|
||||
base_url=base_url if base_url is not None else get_runtime_setting('LLM_BASE_URL'),
|
||||
base_url_preset_id=(
|
||||
base_url_preset
|
||||
if base_url_preset is not None
|
||||
else settings.LLM_BASE_URL_PRESET
|
||||
else get_runtime_setting('LLM_BASE_URL_PRESET')
|
||||
),
|
||||
)
|
||||
except Exception as err:
|
||||
@@ -828,7 +826,7 @@ class LLMHelper:
|
||||
被兼容端点以 400 拒绝。无参调用保持旧版“只读总开关”语义,
|
||||
未知自定义模型也保持原有开关语义。
|
||||
"""
|
||||
if not settings.LLM_SUPPORT_IMAGE_INPUT:
|
||||
if not get_runtime_setting('LLM_SUPPORT_IMAGE_INPUT'):
|
||||
return False
|
||||
if provider is None and model is None:
|
||||
return True
|
||||
@@ -857,8 +855,8 @@ class LLMHelper:
|
||||
这主要用于单测 stub 环境以及极端的最小运行环境,正常生产路径仍优先
|
||||
走 `LLMProviderManager.resolve_runtime()`。
|
||||
"""
|
||||
api_key_value = api_key if api_key is not None else settings.LLM_API_KEY
|
||||
base_url_value = base_url if base_url is not None else settings.LLM_BASE_URL
|
||||
api_key_value = api_key if api_key is not None else get_runtime_setting('LLM_API_KEY')
|
||||
base_url_value = base_url if base_url is not None else get_runtime_setting('LLM_BASE_URL')
|
||||
if not api_key_value:
|
||||
raise ValueError("未配置LLM API Key")
|
||||
|
||||
@@ -1037,7 +1035,7 @@ class LLMHelper:
|
||||
"""
|
||||
规范化 API 协议配置,未知值统一回退为 ``auto`` 以保持兼容。
|
||||
"""
|
||||
normalized = str(api_protocol or settings.LLM_API_PROTOCOL or "").strip().lower()
|
||||
normalized = str(api_protocol or get_runtime_setting('LLM_API_PROTOCOL') or "").strip().lower()
|
||||
if normalized in {"auto", "chat_completions", "responses"}:
|
||||
return normalized
|
||||
if normalized:
|
||||
@@ -1185,15 +1183,15 @@ class LLMHelper:
|
||||
:param prompt_cache_key: 同一 Agent 会话内稳定且脱敏的提示词缓存路由键。
|
||||
:return: LLM实例
|
||||
"""
|
||||
provider_name = str(provider if provider is not None else settings.LLM_PROVIDER).lower()
|
||||
model_name = model if model is not None else settings.LLM_MODEL
|
||||
api_key_value = api_key if api_key is not None else settings.LLM_API_KEY
|
||||
base_url_value = base_url if base_url is not None else settings.LLM_BASE_URL
|
||||
provider_name = str(provider if provider is not None else get_runtime_setting('LLM_PROVIDER')).lower()
|
||||
model_name = model if model is not None else get_runtime_setting('LLM_MODEL')
|
||||
api_key_value = api_key if api_key is not None else get_runtime_setting('LLM_API_KEY')
|
||||
base_url_value = base_url if base_url is not None else get_runtime_setting('LLM_BASE_URL')
|
||||
base_url_preset_value = (
|
||||
base_url_preset if base_url_preset is not None else settings.LLM_BASE_URL_PRESET
|
||||
base_url_preset if base_url_preset is not None else get_runtime_setting('LLM_BASE_URL_PRESET')
|
||||
)
|
||||
user_agent_value = user_agent if user_agent is not None else settings.LLM_USER_AGENT
|
||||
temperature_value = temperature if temperature is not None else settings.LLM_TEMPERATURE
|
||||
user_agent_value = user_agent if user_agent is not None else get_runtime_setting('LLM_USER_AGENT')
|
||||
temperature_value = temperature if temperature is not None else get_runtime_setting('LLM_TEMPERATURE')
|
||||
normalized_thinking_level = cls._resolve_thinking_level(
|
||||
thinking_level=thinking_level,
|
||||
)
|
||||
@@ -1228,12 +1226,12 @@ class LLMHelper:
|
||||
mode=(
|
||||
web_search_mode
|
||||
if web_search_mode is not None
|
||||
else getattr(settings, "LLM_WEB_SEARCH_MODE", "local")
|
||||
else get_runtime_setting("LLM_WEB_SEARCH_MODE", "local")
|
||||
),
|
||||
api_protocol=(
|
||||
api_protocol
|
||||
if api_protocol is not None
|
||||
else settings.LLM_API_PROTOCOL
|
||||
else get_runtime_setting('LLM_API_PROTOCOL')
|
||||
),
|
||||
base_url=runtime.get("base_url"),
|
||||
)
|
||||
@@ -1345,7 +1343,7 @@ class LLMHelper:
|
||||
credentials=aws_auth,
|
||||
base_url=runtime.get("base_url"),
|
||||
use_proxy=use_proxy,
|
||||
read_timeout=settings.LLM_TOOL_TIMEOUT,
|
||||
read_timeout=get_runtime_setting('LLM_TOOL_TIMEOUT'),
|
||||
)
|
||||
model = bedrock_model_cls(
|
||||
model_id=model_name,
|
||||
@@ -1492,8 +1490,8 @@ class LLMHelper:
|
||||
:param api_protocol: OpenAI 兼容接口 API 协议,未显式传入时沿用已保存配置。
|
||||
:param web_search_mode: 联网搜索模式,未显式传入时沿用已保存配置。
|
||||
"""
|
||||
provider_name = provider if provider is not None else settings.LLM_PROVIDER
|
||||
model_name = model if model is not None else settings.LLM_MODEL
|
||||
provider_name = provider if provider is not None else get_runtime_setting('LLM_PROVIDER')
|
||||
model_name = model if model is not None else get_runtime_setting('LLM_MODEL')
|
||||
start = time.perf_counter()
|
||||
llm_kwargs = {
|
||||
"streaming": False,
|
||||
|
||||
+21
-22
@@ -20,9 +20,8 @@ import aiofiles
|
||||
import httpx
|
||||
import jwt
|
||||
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.runtime.log import logger
|
||||
from app.schemas.types import LlmProviderAction, SystemConfigKey
|
||||
@@ -268,7 +267,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
self._models_dev_data: dict[str, Any] | None = None
|
||||
self._models_dev_loaded_at: float = 0
|
||||
self._models_dev_cache_path = (
|
||||
Path(settings.TEMP_PATH) / "llm_provider_models_dev_cache.json"
|
||||
Path(get_runtime_setting('TEMP_PATH')) / "llm_provider_models_dev_cache.json"
|
||||
)
|
||||
|
||||
def _cleanup_auth_sessions_locked(self, now: Optional[float] = None) -> None:
|
||||
@@ -1498,13 +1497,13 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
|
||||
def _build_httpx_kwargs(self, use_proxy: Optional[bool] = None) -> dict[str, Any]:
|
||||
"""构造用于 httpx 客户端的参数,如代理等。"""
|
||||
should_use_proxy = settings.LLM_USE_PROXY if use_proxy is None else use_proxy
|
||||
should_use_proxy = get_runtime_setting('LLM_USE_PROXY') if use_proxy is None else use_proxy
|
||||
kwargs: dict[str, Any] = {
|
||||
"timeout": self._DEFAULT_TIMEOUT,
|
||||
"trust_env": False,
|
||||
}
|
||||
if should_use_proxy and settings.PROXY_HOST:
|
||||
kwargs[self._httpx_proxy_key()] = settings.PROXY_HOST
|
||||
if should_use_proxy and get_runtime_setting('PROXY_HOST'):
|
||||
kwargs[self._httpx_proxy_key()] = get_runtime_setting('PROXY_HOST')
|
||||
return kwargs
|
||||
|
||||
@staticmethod
|
||||
@@ -1616,7 +1615,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
|
||||
async def _fetch_models_dev(self, use_proxy: Optional[bool] = None) -> dict[str, Any]:
|
||||
"""通过网络请求获取最新 models.dev 数据。"""
|
||||
headers = {"User-Agent": settings.USER_AGENT}
|
||||
headers = {"User-Agent": get_runtime_setting('USER_AGENT')}
|
||||
async with httpx.AsyncClient(**self._build_httpx_kwargs(use_proxy)) as client:
|
||||
response = await client.get(self._MODELS_DEV_URL, headers=headers)
|
||||
response.raise_for_status()
|
||||
@@ -2043,10 +2042,10 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
from google import genai
|
||||
from google.genai.types import HttpOptions
|
||||
|
||||
should_use_proxy = settings.LLM_USE_PROXY if use_proxy is None else use_proxy
|
||||
should_use_proxy = get_runtime_setting('LLM_USE_PROXY') if use_proxy is None else use_proxy
|
||||
client_args: dict[str, Any] = {"trust_env": False}
|
||||
if should_use_proxy and settings.PROXY_HOST:
|
||||
client_args[self._httpx_proxy_key()] = settings.PROXY_HOST
|
||||
if should_use_proxy and get_runtime_setting('PROXY_HOST'):
|
||||
client_args[self._httpx_proxy_key()] = get_runtime_setting('PROXY_HOST')
|
||||
http_options = HttpOptions(
|
||||
client_args=client_args,
|
||||
async_client_args=client_args,
|
||||
@@ -2160,10 +2159,10 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
"""
|
||||
from botocore.config import Config
|
||||
|
||||
should_use_proxy = settings.LLM_USE_PROXY if use_proxy is None else use_proxy
|
||||
should_use_proxy = get_runtime_setting('LLM_USE_PROXY') if use_proxy is None else use_proxy
|
||||
proxies = None
|
||||
if should_use_proxy and settings.PROXY_HOST:
|
||||
proxies = {"http": settings.PROXY_HOST, "https": settings.PROXY_HOST}
|
||||
if should_use_proxy and get_runtime_setting('PROXY_HOST'):
|
||||
proxies = {"http": get_runtime_setting('PROXY_HOST'), "https": get_runtime_setting('PROXY_HOST')}
|
||||
return Config(
|
||||
connect_timeout=10,
|
||||
read_timeout=60,
|
||||
@@ -2388,7 +2387,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
仅补充 Copilot 必需的意图头,避免重复覆盖。
|
||||
"""
|
||||
headers = {
|
||||
"User-Agent": settings.USER_AGENT,
|
||||
"User-Agent": get_runtime_setting('USER_AGENT'),
|
||||
"Openai-Intent": "conversation-edits",
|
||||
"x-initiator": "user",
|
||||
}
|
||||
@@ -2769,7 +2768,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
f"{self._CHATGPT_ISSUER}/api/accounts/deviceauth/usercode",
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": settings.USER_AGENT,
|
||||
"User-Agent": get_runtime_setting('USER_AGENT'),
|
||||
},
|
||||
json={"client_id": self._CHATGPT_CLIENT_ID},
|
||||
)
|
||||
@@ -2806,7 +2805,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": settings.USER_AGENT,
|
||||
"User-Agent": get_runtime_setting('USER_AGENT'),
|
||||
},
|
||||
json={
|
||||
"client_id": self._COPILOT_CLIENT_ID,
|
||||
@@ -3036,11 +3035,11 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
"""管理动作:使用传入配置或当前已保存配置执行一次最小 LLM 调用。"""
|
||||
from app.agent.llm.helper import LLMHelper, LLMTestTimeout
|
||||
|
||||
provider_name = provider or settings.LLM_PROVIDER
|
||||
model = params.get("model") if params.get("model") is not None else settings.LLM_MODEL
|
||||
provider_name = provider or get_runtime_setting('LLM_PROVIDER')
|
||||
model = params.get("model") if params.get("model") is not None else get_runtime_setting('LLM_MODEL')
|
||||
enabled = params.get("enabled")
|
||||
enabled = bool(enabled) if enabled is not None else bool(settings.AI_AGENT_ENABLE)
|
||||
api_key = params.get("api_key") if params.get("api_key") is not None else settings.LLM_API_KEY
|
||||
enabled = bool(enabled) if enabled is not None else bool(get_runtime_setting('AI_AGENT_ENABLE'))
|
||||
api_key = params.get("api_key") if params.get("api_key") is not None else get_runtime_setting('LLM_API_KEY')
|
||||
|
||||
data = {"provider": provider_name, "model": model}
|
||||
if not provider_name:
|
||||
@@ -3151,7 +3150,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
f"{self._CHATGPT_ISSUER}/api/accounts/deviceauth/token",
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": settings.USER_AGENT,
|
||||
"User-Agent": get_runtime_setting('USER_AGENT'),
|
||||
},
|
||||
json={
|
||||
"device_auth_id": session.context["device_auth_id"],
|
||||
@@ -3196,7 +3195,7 @@ class LLMProviderManager(metaclass=Singleton):
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": settings.USER_AGENT,
|
||||
"User-Agent": get_runtime_setting('USER_AGENT'),
|
||||
},
|
||||
json={
|
||||
"client_id": self._COPILOT_CLIENT_ID,
|
||||
|
||||
Reference in New Issue
Block a user