Skip to content
Open
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
48 changes: 48 additions & 0 deletions astrbot/core/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,7 @@ class ChatProviderTemplate(TypedDict):
},
"gm_thinking_config": {"budget": 0, "level": "HIGH"},
"proxy": "",
"custom_headers": {},
},
"Anthropic": {
"id": "anthropic",
Expand All @@ -980,6 +981,7 @@ class ChatProviderTemplate(TypedDict):
"api_base": "https://api.anthropic.com/v1",
"timeout": 120,
"proxy": "",
"custom_headers": {},
"anth_thinking_config": {"type": "", "budget": 0, "effort": ""},
},
"Moonshot": {
Expand Down Expand Up @@ -1212,6 +1214,7 @@ class ChatProviderTemplate(TypedDict):
"variables": {},
"timeout": 60,
"proxy": "",
"custom_headers": {},
},
"Coze": {
"id": "coze",
Expand All @@ -1224,6 +1227,7 @@ class ChatProviderTemplate(TypedDict):
"coze_api_base": "https://api.coze.cn",
"timeout": 60,
"proxy": "",
"custom_headers": {},
# "auto_save_history": True,
},
"阿里云百炼应用": {
Expand All @@ -1243,6 +1247,7 @@ class ChatProviderTemplate(TypedDict):
"variables": {},
"timeout": 60,
"proxy": "",
"custom_headers": {},
},
"FastGPT": {
"id": "fastgpt",
Expand All @@ -1267,6 +1272,7 @@ class ChatProviderTemplate(TypedDict):
"api_base": "",
"model": "whisper-1",
"proxy": "",
"custom_headers": {},
},
"Whisper(Local)": {
"provider": "openai",
Expand All @@ -1275,6 +1281,7 @@ class ChatProviderTemplate(TypedDict):
"enable": False,
"id": "whisper_selfhost",
"model": "tiny",
"custom_headers": {},
},
"SenseVoice(Local)": {
"type": "sensevoice_stt_selfhost",
Expand All @@ -1284,6 +1291,7 @@ class ChatProviderTemplate(TypedDict):
"id": "sensevoice",
"stt_model": "iic/SenseVoiceSmall",
"is_emotion": False,
"custom_headers": {},
},
"OpenAI TTS(API)": {
"id": "openai_tts",
Expand All @@ -1297,6 +1305,7 @@ class ChatProviderTemplate(TypedDict):
"openai-tts-voice": "alloy",
"timeout": "20",
"proxy": "",
"custom_headers": {},
},
"Genie TTS": {
"id": "genie_tts",
Expand All @@ -1310,6 +1319,7 @@ class ChatProviderTemplate(TypedDict):
"genie_refer_audio_path": "",
"genie_refer_text": "",
"timeout": 20,
"custom_headers": {},
},
"Edge TTS": {
"id": "edge_tts",
Expand All @@ -1322,6 +1332,7 @@ class ChatProviderTemplate(TypedDict):
"volume": "+0%",
"pitch": "+0Hz",
"timeout": 20,
"custom_headers": {},
},
"GSV TTS(Local)": {
"id": "gsv_tts",
Expand All @@ -1333,6 +1344,7 @@ class ChatProviderTemplate(TypedDict):
"gpt_weights_path": "",
"sovits_weights_path": "",
"timeout": 60,
"custom_headers": {},
"gsv_default_parms": {
"gsv_ref_audio_path": "",
"gsv_prompt_text": "",
Expand Down Expand Up @@ -1365,6 +1377,7 @@ class ChatProviderTemplate(TypedDict):
"emotion": "default",
"enable": False,
"timeout": 20,
"custom_headers": {},
},
"FishAudio TTS(API)": {
"id": "fishaudio_tts",
Expand All @@ -1378,6 +1391,7 @@ class ChatProviderTemplate(TypedDict):
"fishaudio-tts-reference-id": "",
"timeout": "20",
"proxy": "",
"custom_headers": {},
},
"阿里云百炼 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 @@ -1390,6 +1404,7 @@ class ChatProviderTemplate(TypedDict):
"model": "cosyvoice-v1",
"dashscope_tts_voice": "loongstella",
"timeout": "20",
"custom_headers": {},
},
"Azure TTS": {
"id": "azure_tts",
Expand All @@ -1405,6 +1420,7 @@ class ChatProviderTemplate(TypedDict):
"azure_tts_subscription_key": "",
"azure_tts_region": "eastus",
"proxy": "",
"custom_headers": {},
},
"MiniMax TTS(API)": {
"id": "minimax_tts",
Expand All @@ -1428,6 +1444,7 @@ class ChatProviderTemplate(TypedDict):
"minimax-voice-english-normalization": False,
"timeout": 20,
"proxy": "",
"custom_headers": {},
},
"火山引擎_TTS(API)": {
"id": "volcengine_tts",
Expand All @@ -1443,6 +1460,7 @@ class ChatProviderTemplate(TypedDict):
"api_base": "https://openspeech.bytedance.com/api/v1/tts",
"timeout": 20,
"proxy": "",
"custom_headers": {},
},
"Gemini TTS": {
"id": "gemini_tts",
Expand All @@ -1457,6 +1475,7 @@ class ChatProviderTemplate(TypedDict):
"gemini_tts_prefix": "",
"gemini_tts_voice_name": "Leda",
"proxy": "",
"custom_headers": {},
},
"OpenAI Embedding": {
"id": "openai_embedding",
Expand All @@ -1470,6 +1489,7 @@ class ChatProviderTemplate(TypedDict):
"embedding_dimensions": 1024,
"timeout": 20,
"proxy": "",
"custom_headers": {},
},
"Gemini Embedding": {
"id": "gemini_embedding",
Expand All @@ -1483,6 +1503,7 @@ class ChatProviderTemplate(TypedDict):
"embedding_dimensions": 768,
"timeout": 20,
"proxy": "",
"custom_headers": {},
},
"vLLM Rerank": {
"id": "vllm_rerank",
Expand All @@ -1494,6 +1515,7 @@ class ChatProviderTemplate(TypedDict):
"rerank_api_base": "http://127.0.0.1:8000",
"rerank_model": "BAAI/bge-reranker-base",
"timeout": 20,
"custom_headers": {},
},
"Xinference Rerank": {
"id": "xinference_rerank",
Expand All @@ -1506,6 +1528,7 @@ class ChatProviderTemplate(TypedDict):
"rerank_model": "BAAI/bge-reranker-base",
"timeout": 20,
"launch_model_if_not_running": False,
"custom_headers": {},
},
"阿里云百炼重排序": {
"id": "bailian_rerank",
Expand All @@ -1519,6 +1542,7 @@ class ChatProviderTemplate(TypedDict):
"timeout": 30,
"return_documents": False,
"instruct": "",
"custom_headers": {},
},
"Xinference STT": {
"id": "xinference_stt",
Expand All @@ -1531,6 +1555,7 @@ class ChatProviderTemplate(TypedDict):
"model": "whisper-large-v3",
"timeout": 180,
"launch_model_if_not_running": False,
"custom_headers": {},
},
},
"items": {
Expand Down Expand Up @@ -1597,6 +1622,29 @@ class ChatProviderTemplate(TypedDict):
"type": "dict",
"items": {},
"hint": "此处添加的键值对将被合并到 OpenAI SDK 的 default_headers 中,用于自定义 HTTP 请求头。值必须为字符串。",
"template_schema": {
"User-Agent": {
"name": "User-Agent",
"description": "User-Agent 请求头",
"hint": "用于覆盖默认客户端标识。",
"type": "string",
"default": "",
},
"Accept": {
"name": "Accept",
"description": "Accept 请求头",
"hint": "声明可接受的响应类型。默认留空以使用 SDK/服务端默认值,仅在需要时显式覆盖(例如指定 application/json)。",
"type": "string",
"default": "",
},
"Accept-Language": {
"name": "Accept-Language",
"description": "Accept-Language 请求头",
"hint": "声明偏好语言,例如 zh-CN,zh;q=0.9,en;q=0.8。",
"type": "string",
"default": "",
},
},
},
"custom_extra_body": {
"description": "自定义请求体参数",
Expand Down
31 changes: 29 additions & 2 deletions astrbot/dashboard/routes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,24 @@ def __init__(
}
self.register_routes()

@staticmethod
def _with_default_custom_headers(config: dict) -> dict:
normalized = dict(config) if isinstance(config, dict) else {}
headers = normalized.get("custom_headers")
if not isinstance(headers, dict):
normalized["custom_headers"] = {}
return normalized

# 在返回 provider_sources 和 provider 配置时,如果 custom_headers 字段不是 dict,则强制转换为 dict,避免前端使用时出错
def _normalize_custom_headers_configs(self, configs: list) -> list:
normalized = []
for config in configs:
if isinstance(config, dict):
normalized.append(self._with_default_custom_headers(config))
else:
normalized.append(config)
return normalized

async def delete_provider_source(self):
"""删除 provider_source,并更新关联的 providers"""
post_data = await request.json
Expand Down Expand Up @@ -345,6 +363,8 @@ async def update_provider_source(self):
if not isinstance(new_source_config, dict):
return Response().error("缺少或错误的配置数据").__dict__

new_source_config = self._with_default_custom_headers(new_source_config)

# 确保配置中有 id 字段
if not new_source_config.get("id"):
new_source_config["id"] = original_id
Expand Down Expand Up @@ -426,8 +446,12 @@ async def get_provider_template(self):
}
data = {
"config_schema": config_schema,
"providers": astrbot_config["provider"],
"provider_sources": astrbot_config["provider_sources"],
"providers": self._normalize_custom_headers_configs(
astrbot_config["provider"]
),
"provider_sources": self._normalize_custom_headers_configs(
astrbot_config["provider_sources"]
),
}
return Response().ok(data=data).__dict__

Expand Down Expand Up @@ -1136,6 +1160,7 @@ async def post_new_platform(self):

async def post_new_provider(self):
new_provider_config = await request.json
new_provider_config = self._with_default_custom_headers(new_provider_config)

try:
await self.core_lifecycle.provider_manager.create_provider(
Expand Down Expand Up @@ -1179,6 +1204,8 @@ async def post_update_provider(self):
if not origin_provider_id or not new_config:
return Response().error("参数错误").__dict__

new_config = self._with_default_custom_headers(new_config)

try:
await self.core_lifecycle.provider_manager.update_provider(
origin_provider_id, new_config
Expand Down
19 changes: 18 additions & 1 deletion dashboard/src/i18n/locales/en-US/features/config-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,24 @@
},
"custom_headers": {
"description": "Custom request headers",
"hint": "Key/value pairs added here are merged into the OpenAI SDK default_headers for custom HTTP headers. Values must be strings."
"hint": "Key/value pairs added here are merged into the OpenAI SDK default_headers for custom HTTP headers. Values must be strings.",
"template_schema": {
"User-Agent": {
"description": "User-Agent header",
"hint": "Override the default client identity.",
"name": "User-Agent"
},
"Accept": {
"description": "Accept header",
"hint": "Declares accepted response formats. Leave empty by default to use SDK/provider defaults and only override when needed (e.g. application/json).",
"name": "Accept"
},
"Accept-Language": {
"description": "Accept-Language header",
"hint": "Declares preferred languages, e.g. zh-CN,zh;q=0.9,en;q=0.8.",
"name": "Accept-Language"
}
}
},
"custom_extra_body": {
"description": "Custom request body parameters",
Expand Down
19 changes: 18 additions & 1 deletion dashboard/src/i18n/locales/zh-CN/features/config-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,24 @@
},
"custom_headers": {
"description": "自定义添加请求头",
"hint": "此处添加的键值对将被合并到 OpenAI SDK 的 default_headers 中,用于自定义 HTTP 请求头。值必须为字符串。"
"hint": "此处添加的键值对将被合并到 OpenAI SDK 的 default_headers 中,用于自定义 HTTP 请求头。值必须为字符串。",
"template_schema": {
"User-Agent": {
"description": "User-Agent 请求头",
"hint": "用于覆盖默认客户端标识。",
"name": "User-Agent"
},
"Accept": {
"description": "Accept 请求头",
"hint": "声明可接受的响应类型。默认留空以使用 SDK/服务端默认值,仅在需要时显式覆盖(例如指定 application/json)。",
"name": "Accept"
},
"Accept-Language": {
"description": "Accept-Language 请求头",
"hint": "声明偏好语言,例如 zh-CN,zh;q=0.9,en;q=0.8。",
"name": "Accept-Language"
}
}
},
"custom_extra_body": {
"description": "自定义请求体参数",
Expand Down