Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion astrbot/core/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
"t2i_use_file_service": False,
"t2i_active_template": "base",
"http_proxy": "",
"no_proxy": ["localhost", "127.0.0.1", "::1"],
"no_proxy": ["localhost", "127.0.0.1", "::1", "10.*", "192.168.*"],
"dashboard": {
"enable": True,
"username": "astrbot",
Expand Down Expand Up @@ -913,6 +913,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.openai.com/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"Google Gemini": {
Expand All @@ -935,6 +936,7 @@ class ChatProviderTemplate(TypedDict):
"dangerous_content": "BLOCK_MEDIUM_AND_ABOVE",
},
"gm_thinking_config": {"budget": 0, "level": "HIGH"},
"proxy": "",
},
"Anthropic": {
"id": "anthropic",
Expand All @@ -945,6 +947,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.anthropic.com/v1",
"timeout": 120,
"proxy": "",
"anth_thinking_config": {"budget": 0},
},
"Moonshot": {
Expand All @@ -956,6 +959,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"timeout": 120,
"api_base": "https://api.moonshot.cn/v1",
"proxy": "",
"custom_headers": {},
},
"xAI": {
Expand All @@ -967,6 +971,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.x.ai/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
"xai_native_search": False,
},
Expand All @@ -979,6 +984,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.deepseek.com/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"Zhipu": {
Expand All @@ -990,6 +996,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"timeout": 120,
"api_base": "https://open.bigmodel.cn/api/paas/v4/",
"proxy": "",
"custom_headers": {},
},
"Azure OpenAI": {
Expand All @@ -1002,6 +1009,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"Ollama": {
Expand All @@ -1012,6 +1020,7 @@ class ChatProviderTemplate(TypedDict):
"enable": True,
"key": ["ollama"], # ollama 的 key 默认是 ollama
"api_base": "http://127.0.0.1:11434/v1",
"proxy": "",
"custom_headers": {},
},
"LM Studio": {
Expand All @@ -1022,6 +1031,7 @@ class ChatProviderTemplate(TypedDict):
"enable": True,
"key": ["lmstudio"],
"api_base": "http://127.0.0.1:1234/v1",
"proxy": "",
"custom_headers": {},
},
"Gemini_OpenAI_API": {
Expand All @@ -1033,6 +1043,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://generativelanguage.googleapis.com/v1beta/openai/",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"Groq": {
Expand All @@ -1044,6 +1055,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.groq.com/openai/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"302.AI": {
Expand All @@ -1055,6 +1067,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.302.ai/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"SiliconFlow": {
Expand All @@ -1066,6 +1079,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"timeout": 120,
"api_base": "https://api.siliconflow.cn/v1",
"proxy": "",
"custom_headers": {},
},
"PPIO": {
Expand All @@ -1077,6 +1091,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.ppinfra.com/v3/openai",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"TokenPony": {
Expand All @@ -1088,6 +1103,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.tokenpony.cn/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"Compshare": {
Expand All @@ -1099,6 +1115,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.modelverse.cn/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
},
"ModelScope": {
Expand All @@ -1110,6 +1127,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"timeout": 120,
"api_base": "https://api-inference.modelscope.cn/v1",
"proxy": "",
"custom_headers": {},
},
"Dify": {
Expand All @@ -1125,6 +1143,7 @@ class ChatProviderTemplate(TypedDict):
"dify_query_input_key": "astrbot_text_query",
"variables": {},
"timeout": 60,
"proxy": "",
},
"Coze": {
"id": "coze",
Expand All @@ -1136,6 +1155,7 @@ class ChatProviderTemplate(TypedDict):
"bot_id": "",
"coze_api_base": "https://api.coze.cn",
"timeout": 60,
"proxy": "",
# "auto_save_history": True,
},
"阿里云百炼应用": {
Expand All @@ -1154,6 +1174,7 @@ class ChatProviderTemplate(TypedDict):
},
"variables": {},
"timeout": 60,
"proxy": "",
},
"FastGPT": {
"id": "fastgpt",
Expand All @@ -1164,6 +1185,7 @@ class ChatProviderTemplate(TypedDict):
"key": [],
"api_base": "https://api.fastgpt.in/api/v1",
"timeout": 60,
"proxy": "",
"custom_headers": {},
"custom_extra_body": {},
},
Expand All @@ -1176,6 +1198,7 @@ class ChatProviderTemplate(TypedDict):
"api_key": "",
"api_base": "",
"model": "whisper-1",
"proxy": "",
},
"Whisper(Local)": {
"provider": "openai",
Expand Down Expand Up @@ -1205,6 +1228,7 @@ class ChatProviderTemplate(TypedDict):
"model": "tts-1",
"openai-tts-voice": "alloy",
"timeout": "20",
"proxy": "",
},
"Genie TTS": {
"id": "genie_tts",
Expand Down Expand Up @@ -1285,6 +1309,7 @@ class ChatProviderTemplate(TypedDict):
"fishaudio-tts-character": "可莉",
"fishaudio-tts-reference-id": "",
"timeout": "20",
"proxy": "",
},
"阿里云百炼 TTS(API)": {
"hint": "API Key 从 https://bailian.console.aliyun.com/?tab=model#/api-key 获取。模型和音色的选择文档请参考: 阿里云百炼语音合成音色名称。具体可参考 https://help.aliyun.com/zh/model-studio/speech-synthesis-and-speech-recognition",
Expand All @@ -1311,6 +1336,7 @@ class ChatProviderTemplate(TypedDict):
"azure_tts_volume": "100",
"azure_tts_subscription_key": "",
"azure_tts_region": "eastus",
"proxy": "",
},
"MiniMax TTS(API)": {
"id": "minimax_tts",
Expand All @@ -1333,6 +1359,7 @@ class ChatProviderTemplate(TypedDict):
"minimax-voice-latex": False,
"minimax-voice-english-normalization": False,
"timeout": 20,
"proxy": "",
},
"火山引擎_TTS(API)": {
"id": "volcengine_tts",
Expand All @@ -1347,6 +1374,7 @@ class ChatProviderTemplate(TypedDict):
"volcengine_speed_ratio": 1.0,
"api_base": "https://openspeech.bytedance.com/api/v1/tts",
"timeout": 20,
"proxy": "",
},
"Gemini TTS": {
"id": "gemini_tts",
Expand All @@ -1360,6 +1388,7 @@ class ChatProviderTemplate(TypedDict):
"gemini_tts_model": "gemini-2.5-flash-preview-tts",
"gemini_tts_prefix": "",
"gemini_tts_voice_name": "Leda",
"proxy": "",
},
"OpenAI Embedding": {
"id": "openai_embedding",
Expand All @@ -1372,6 +1401,7 @@ class ChatProviderTemplate(TypedDict):
"embedding_model": "",
"embedding_dimensions": 1024,
"timeout": 20,
"proxy": "",
},
"Gemini Embedding": {
"id": "gemini_embedding",
Expand All @@ -1384,6 +1414,7 @@ class ChatProviderTemplate(TypedDict):
"embedding_model": "gemini-embedding-exp-03-07",
"embedding_dimensions": 768,
"timeout": 20,
"proxy": "",
},
"vLLM Rerank": {
"id": "vllm_rerank",
Expand Down Expand Up @@ -2080,6 +2111,11 @@ class ChatProviderTemplate(TypedDict):
"description": "API Base URL",
"type": "string",
},
"proxy": {
"description": "代理地址",
"type": "string",
"hint": "HTTP/HTTPS 代理地址,格式如 http://127.0.0.1:7890。仅对该提供商的 API 请求生效,不影响 Docker 内网通信。",
},
"model": {
"description": "模型 ID",
"type": "string",
Expand Down
32 changes: 29 additions & 3 deletions astrbot/core/provider/sources/anthropic_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from collections.abc import AsyncGenerator

import anthropic
import httpx
from anthropic import AsyncAnthropic
from anthropic.types import Message
from anthropic.types.message_delta_usage import MessageDeltaUsage
Expand All @@ -14,6 +15,11 @@
from astrbot.core.provider.entities import LLMResponse, TokenUsage
from astrbot.core.provider.func_tool_manager import ToolSet
from astrbot.core.utils.io import download_image_by_url
from astrbot.core.utils.network_utils import (
create_proxy_client,
is_connection_error,
log_connection_failure,
)

from ..register import register_provider_adapter

Expand Down Expand Up @@ -45,12 +51,18 @@ def __init__(
api_key=self.chosen_api_key,
timeout=self.timeout,
base_url=self.base_url,
http_client=self._create_http_client(provider_config),
)

self.thinking_config = provider_config.get("anth_thinking_config", {})

self.set_model(provider_config.get("model", "unknown"))

def _create_http_client(self, provider_config: dict) -> httpx.AsyncClient | None:
"""创建带代理的 HTTP 客户端"""
proxy = provider_config.get("proxy", "")
return create_proxy_client("Anthropic", proxy)

def _prepare_payload(self, messages: list[dict]):
"""准备 Anthropic API 的请求 payload

Expand Down Expand Up @@ -207,9 +219,19 @@ async def _query(self, payloads: dict, tools: ToolSet | None) -> LLMResponse:
"type": "enabled",
}

completion = await self.client.messages.create(
**payloads, stream=False, extra_body=extra_body
)
try:
completion = await self.client.messages.create(
**payloads, stream=False, extra_body=extra_body
)
except httpx.RequestError as e:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openai source 我看记录了 os.environ 里面的 proxy 作为provider_config.get("proxy", "")为空时的fallback,但是其他source好像没有。是不是可以考虑把 os.environ 里面的 proxy fallback 放到 log_connection_failure 内。如 proxy 为空的时候,就换成os.environ 里面的 proxy 去输出日志。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okk我看到了

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Soulter review

proxy = self.provider_config.get("proxy", "")
log_connection_failure("Anthropic", e, proxy)
raise
except Exception as e:
if is_connection_error(e):
proxy = self.provider_config.get("proxy", "")
log_connection_failure("Anthropic", e, proxy)
raise

assert isinstance(completion, Message)
logger.debug(f"completion: {completion}")
Expand Down Expand Up @@ -622,3 +644,7 @@ async def get_models(self) -> list[str]:

def set_key(self, key: str):
self.chosen_api_key = key

async def terminate(self):
if self.client:
await self.client.close()
12 changes: 11 additions & 1 deletion astrbot/core/provider/sources/azure_tts_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from httpx import AsyncClient, Timeout

from astrbot import logger
from astrbot.core.config.default import VERSION

from ..entities import ProviderType
Expand All @@ -29,6 +30,9 @@ def __init__(self, config: dict):
self.last_sync_time = 0
self.timeout = Timeout(10.0)
self.retry_count = 3
self.proxy = config.get("proxy", "")
if self.proxy:
logger.info(f"[Azure TTS] 使用代理: {self.proxy}")
self._client: AsyncClient | None = None

@property
Expand All @@ -40,7 +44,9 @@ def client(self) -> AsyncClient:
return self._client

async def __aenter__(self):
self._client = AsyncClient(timeout=self.timeout)
self._client = AsyncClient(
timeout=self.timeout, proxy=self.proxy if self.proxy else None
)
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
Expand Down Expand Up @@ -125,6 +131,9 @@ def __init__(self, provider_config: dict, provider_settings: dict):
"rate": provider_config.get("azure_tts_rate", "1"),
"volume": provider_config.get("azure_tts_volume", "100"),
}
self.proxy = provider_config.get("proxy", "")
if self.proxy:
logger.info(f"[Azure TTS Native] 使用代理: {self.proxy}")

@property
def client(self) -> AsyncClient:
Expand All @@ -141,6 +150,7 @@ async def __aenter__(self):
"Content-Type": "application/ssml+xml",
"X-Microsoft-OutputFormat": "riff-48khz-16bit-mono-pcm",
},
proxy=self.proxy if self.proxy else None,
)
return self

Expand Down
Loading