mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-07-04 14:21:27 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebfa1d247c | ||
|
|
cdb85ef9b7 | ||
|
|
7006522c13 | ||
|
|
530c958afc | ||
|
|
57d861b578 | ||
|
|
99664298b9 | ||
|
|
a6fe5a7022 |
@@ -20,6 +20,9 @@ THINKING_BUDGET_MAP={"gemini-2.5-flash-preview-04-17": 4000}
|
|||||||
IMAGE_MODELS=["gemini-2.0-flash-exp"]
|
IMAGE_MODELS=["gemini-2.0-flash-exp"]
|
||||||
SEARCH_MODELS=["gemini-2.0-flash-exp","gemini-2.0-pro-exp"]
|
SEARCH_MODELS=["gemini-2.0-flash-exp","gemini-2.0-pro-exp"]
|
||||||
FILTERED_MODELS=["gemini-1.0-pro-vision-latest", "gemini-pro-vision", "chat-bison-001", "text-bison-001", "embedding-gecko-001"]
|
FILTERED_MODELS=["gemini-1.0-pro-vision-latest", "gemini-pro-vision", "chat-bison-001", "text-bison-001", "embedding-gecko-001"]
|
||||||
|
# 是否启用网址上下文,默认启用
|
||||||
|
URL_CONTEXT_ENABLED=true
|
||||||
|
URL_CONTEXT_MODELS=["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash","gemini-2.0-flash-live-001"]
|
||||||
TOOLS_CODE_EXECUTION_ENABLED=false
|
TOOLS_CODE_EXECUTION_ENABLED=false
|
||||||
SHOW_SEARCH_LINK=true
|
SHOW_SEARCH_LINK=true
|
||||||
SHOW_THINKING_PROCESS=true
|
SHOW_THINKING_PROCESS=true
|
||||||
|
|||||||
@@ -192,6 +192,8 @@ If you want to run the source code directly locally for development or testing,
|
|||||||
| `THINKING_MODELS` | Optional, list of models that support thinking functions | `[]` |
|
| `THINKING_MODELS` | Optional, list of models that support thinking functions | `[]` |
|
||||||
| `THINKING_BUDGET_MAP` | Optional, thinking function budget mapping (model_name:budget_value) | `{}` |
|
| `THINKING_BUDGET_MAP` | Optional, thinking function budget mapping (model_name:budget_value) | `{}` |
|
||||||
| `URL_NORMALIZATION_ENABLED` | Optional, whether to enable intelligent URL routing mapping | `false` |
|
| `URL_NORMALIZATION_ENABLED` | Optional, whether to enable intelligent URL routing mapping | `false` |
|
||||||
|
| `URL_CONTEXT_ENABLED` | Optional, whether to enable URL context understanding | `false` |
|
||||||
|
| `URL_CONTEXT_MODELS` | Optional, list of models that support URL context understanding | `[]` |
|
||||||
| `BASE_URL` | Optional, Gemini API base URL, no modification needed by default | `https://generativelanguage.googleapis.com/v1beta` |
|
| `BASE_URL` | Optional, Gemini API base URL, no modification needed by default | `https://generativelanguage.googleapis.com/v1beta` |
|
||||||
| `MAX_FAILURES` | Optional, number of times a single key is allowed to fail | `3` |
|
| `MAX_FAILURES` | Optional, number of times a single key is allowed to fail | `3` |
|
||||||
| `MAX_RETRIES` | Optional, maximum number of retries for failed API requests | `3` |
|
| `MAX_RETRIES` | Optional, maximum number of retries for failed API requests | `3` |
|
||||||
|
|||||||
@@ -185,6 +185,8 @@ app/
|
|||||||
| `THINKING_MODELS` | 可选,支持思考功能的模型列表 | `[]` |
|
| `THINKING_MODELS` | 可选,支持思考功能的模型列表 | `[]` |
|
||||||
| `THINKING_BUDGET_MAP` | 可选,思考功能预算映射 (模型名:预算值) | `{}` |
|
| `THINKING_BUDGET_MAP` | 可选,思考功能预算映射 (模型名:预算值) | `{}` |
|
||||||
| `URL_NORMALIZATION_ENABLED` | 可选,是否启用智能路由映射功能 | `false` |
|
| `URL_NORMALIZATION_ENABLED` | 可选,是否启用智能路由映射功能 | `false` |
|
||||||
|
| `URL_CONTEXT_ENABLED` | 可选,是否启用URL上下文理解功能 | `false` |
|
||||||
|
| `URL_CONTEXT_MODELS` | 可选,支持URL上下文理解功能的模型列表 | `[]` |
|
||||||
| `BASE_URL` | 可选,Gemini API 基础 URL,默认无需修改 | `https://generativelanguage.googleapis.com/v1beta` |
|
| `BASE_URL` | 可选,Gemini API 基础 URL,默认无需修改 | `https://generativelanguage.googleapis.com/v1beta` |
|
||||||
| `MAX_FAILURES` | 可选,允许单个key失败的次数 | `3` |
|
| `MAX_FAILURES` | 可选,允许单个key失败的次数 | `3` |
|
||||||
| `MAX_RETRIES` | 可选,API 请求失败时的最大重试次数 | `3` |
|
| `MAX_RETRIES` | 可选,API 请求失败时的最大重试次数 | `3` |
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ class Settings(BaseSettings):
|
|||||||
IMAGE_MODELS: List[str] = ["gemini-2.0-flash-exp"]
|
IMAGE_MODELS: List[str] = ["gemini-2.0-flash-exp"]
|
||||||
FILTERED_MODELS: List[str] = DEFAULT_FILTER_MODELS
|
FILTERED_MODELS: List[str] = DEFAULT_FILTER_MODELS
|
||||||
TOOLS_CODE_EXECUTION_ENABLED: bool = False
|
TOOLS_CODE_EXECUTION_ENABLED: bool = False
|
||||||
|
# 是否启用网址上下文
|
||||||
|
URL_CONTEXT_ENABLED: bool = True
|
||||||
|
URL_CONTEXT_MODELS: List[str] = ["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash","gemini-2.0-flash-live-001"]
|
||||||
SHOW_SEARCH_LINK: bool = True
|
SHOW_SEARCH_LINK: bool = True
|
||||||
SHOW_THINKING_PROCESS: bool = True
|
SHOW_THINKING_PROCESS: bool = True
|
||||||
THINKING_MODELS: List[str] = []
|
THINKING_MODELS: List[str] = []
|
||||||
|
|||||||
@@ -80,6 +80,21 @@ def _clean_json_schema_properties(obj: Any) -> Any:
|
|||||||
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||||
"""构建工具"""
|
"""构建工具"""
|
||||||
|
|
||||||
|
def _has_function_call(contents: List[Dict[str, Any]]) -> bool:
|
||||||
|
"""检查内容中是否包含 functionCall"""
|
||||||
|
if not contents or not isinstance(contents, list):
|
||||||
|
return False
|
||||||
|
for content in contents:
|
||||||
|
if not content or not isinstance(content, dict) or "parts" not in content:
|
||||||
|
continue
|
||||||
|
parts = content.get("parts", [])
|
||||||
|
if not parts or not isinstance(parts, list):
|
||||||
|
continue
|
||||||
|
for part in parts:
|
||||||
|
if isinstance(part, dict) and "functionCall" in part:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _merge_tools(tools: List[Dict[str, Any]]) -> Dict[str, Any]:
|
def _merge_tools(tools: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||||
record = dict()
|
record = dict()
|
||||||
for item in tools:
|
for item in tools:
|
||||||
@@ -119,15 +134,32 @@ def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|||||||
tool["codeExecution"] = {}
|
tool["codeExecution"] = {}
|
||||||
if model.endswith("-search"):
|
if model.endswith("-search"):
|
||||||
tool["googleSearch"] = {}
|
tool["googleSearch"] = {}
|
||||||
|
|
||||||
|
real_model = _get_real_model(model)
|
||||||
|
if real_model in settings.URL_CONTEXT_MODELS and settings.URL_CONTEXT_ENABLED:
|
||||||
|
tool["urlContext"] = {}
|
||||||
|
|
||||||
# 解决 "Tool use with function calling is unsupported" 问题
|
# 解决 "Tool use with function calling is unsupported" 问题
|
||||||
if tool.get("functionDeclarations"):
|
if tool.get("functionDeclarations") or _has_function_call(payload.get("contents", [])):
|
||||||
tool.pop("googleSearch", None)
|
tool.pop("googleSearch", None)
|
||||||
tool.pop("codeExecution", None)
|
tool.pop("codeExecution", None)
|
||||||
|
tool.pop("urlContext", None)
|
||||||
|
|
||||||
return [tool] if tool else []
|
return [tool] if tool else []
|
||||||
|
|
||||||
|
|
||||||
|
def _get_real_model(model: str) -> str:
|
||||||
|
if model.endswith("-search"):
|
||||||
|
model = model[:-7]
|
||||||
|
if model.endswith("-image"):
|
||||||
|
model = model[:-6]
|
||||||
|
if model.endswith("-non-thinking"):
|
||||||
|
model = model[:-13]
|
||||||
|
if "-search" in model and "-non-thinking" in model:
|
||||||
|
model = model[:-20]
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
||||||
"""获取安全设置"""
|
"""获取安全设置"""
|
||||||
if model == "gemini-2.0-flash-exp":
|
if model == "gemini-2.0-flash-exp":
|
||||||
@@ -206,8 +238,11 @@ def _build_payload(model: str, request: GeminiRequest) -> Dict[str, Any]:
|
|||||||
else:
|
else:
|
||||||
# 客户端没有提供思考配置,使用默认配置
|
# 客户端没有提供思考配置,使用默认配置
|
||||||
if model.endswith("-non-thinking"):
|
if model.endswith("-non-thinking"):
|
||||||
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
if "gemini-2.5-pro" in model:
|
||||||
elif model in settings.THINKING_BUDGET_MAP:
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 128}
|
||||||
|
else:
|
||||||
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
||||||
|
elif _get_real_model(model) in settings.THINKING_BUDGET_MAP:
|
||||||
if settings.SHOW_THINKING_PROCESS:
|
if settings.SHOW_THINKING_PROCESS:
|
||||||
payload["generationConfig"]["thinkingConfig"] = {
|
payload["generationConfig"]["thinkingConfig"] = {
|
||||||
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(model,1000),
|
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(model,1000),
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ def _build_tools(
|
|||||||
|
|
||||||
if model.endswith("-search"):
|
if model.endswith("-search"):
|
||||||
tool["googleSearch"] = {}
|
tool["googleSearch"] = {}
|
||||||
|
|
||||||
|
real_model = _get_real_model(model)
|
||||||
|
if real_model in settings.URL_CONTEXT_MODELS and settings.URL_CONTEXT_ENABLED:
|
||||||
|
tool["urlContext"] = {}
|
||||||
|
|
||||||
# 将 request 中的 tools 合并到 tools 中
|
# 将 request 中的 tools 合并到 tools 中
|
||||||
if request.tools:
|
if request.tools:
|
||||||
@@ -126,10 +130,23 @@ def _build_tools(
|
|||||||
if tool.get("functionDeclarations"):
|
if tool.get("functionDeclarations"):
|
||||||
tool.pop("googleSearch", None)
|
tool.pop("googleSearch", None)
|
||||||
tool.pop("codeExecution", None)
|
tool.pop("codeExecution", None)
|
||||||
|
tool.pop("urlContext",None)
|
||||||
|
|
||||||
return [tool] if tool else []
|
return [tool] if tool else []
|
||||||
|
|
||||||
|
|
||||||
|
def _get_real_model(model: str) -> str:
|
||||||
|
if model.endswith("-search"):
|
||||||
|
model = model[:-7]
|
||||||
|
if model.endswith("-image"):
|
||||||
|
model = model[:-6]
|
||||||
|
if model.endswith("-non-thinking"):
|
||||||
|
model = model[:-13]
|
||||||
|
if "-search" in model and "-non-thinking" in model:
|
||||||
|
model = model[:-20]
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
||||||
"""获取安全设置"""
|
"""获取安全设置"""
|
||||||
# if (
|
# if (
|
||||||
@@ -184,9 +201,12 @@ def _build_payload(
|
|||||||
payload["generationConfig"]["responseModalities"] = ["Text", "Image"]
|
payload["generationConfig"]["responseModalities"] = ["Text", "Image"]
|
||||||
|
|
||||||
if request.model.endswith("-non-thinking"):
|
if request.model.endswith("-non-thinking"):
|
||||||
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
if "gemini-2.5-pro" in request.model:
|
||||||
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 128}
|
||||||
|
else:
|
||||||
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
||||||
|
|
||||||
if request.model in settings.THINKING_BUDGET_MAP:
|
if _get_real_model(request.model) in settings.THINKING_BUDGET_MAP:
|
||||||
if settings.SHOW_THINKING_PROCESS:
|
if settings.SHOW_THINKING_PROCESS:
|
||||||
payload["generationConfig"]["thinkingConfig"] = {
|
payload["generationConfig"]["thinkingConfig"] = {
|
||||||
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(request.model, 1000),
|
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(request.model, 1000),
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ def _clean_json_schema_properties(obj: Any) -> Any:
|
|||||||
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||||
"""构建工具"""
|
"""构建工具"""
|
||||||
|
|
||||||
|
def _has_function_call(contents: List[Dict[str, Any]]) -> bool:
|
||||||
|
"""检查内容中是否包含 functionCall"""
|
||||||
|
if not contents or not isinstance(contents, list):
|
||||||
|
return False
|
||||||
|
for content in contents:
|
||||||
|
if not content or not isinstance(content, dict) or "parts" not in content:
|
||||||
|
continue
|
||||||
|
parts = content.get("parts", [])
|
||||||
|
if not parts or not isinstance(parts, list):
|
||||||
|
continue
|
||||||
|
for part in parts:
|
||||||
|
if isinstance(part, dict) and "functionCall" in part:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _merge_tools(tools: List[Dict[str, Any]]) -> Dict[str, Any]:
|
def _merge_tools(tools: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||||
record = dict()
|
record = dict()
|
||||||
for item in tools:
|
for item in tools:
|
||||||
@@ -97,15 +112,32 @@ def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|||||||
tool["codeExecution"] = {}
|
tool["codeExecution"] = {}
|
||||||
if model.endswith("-search"):
|
if model.endswith("-search"):
|
||||||
tool["googleSearch"] = {}
|
tool["googleSearch"] = {}
|
||||||
|
|
||||||
|
real_model = _get_real_model(model)
|
||||||
|
if real_model in settings.URL_CONTEXT_MODELS and settings.URL_CONTEXT_ENABLED:
|
||||||
|
tool["urlContext"] = {}
|
||||||
|
|
||||||
# 解决 "Tool use with function calling is unsupported" 问题
|
# 解决 "Tool use with function calling is unsupported" 问题
|
||||||
if tool.get("functionDeclarations"):
|
if tool.get("functionDeclarations") or _has_function_call(payload.get("contents", [])):
|
||||||
tool.pop("googleSearch", None)
|
tool.pop("googleSearch", None)
|
||||||
tool.pop("codeExecution", None)
|
tool.pop("codeExecution", None)
|
||||||
|
tool.pop("urlContext", None)
|
||||||
|
|
||||||
return [tool] if tool else []
|
return [tool] if tool else []
|
||||||
|
|
||||||
|
|
||||||
|
def _get_real_model(model: str) -> str:
|
||||||
|
if model.endswith("-search"):
|
||||||
|
model = model[:-7]
|
||||||
|
if model.endswith("-image"):
|
||||||
|
model = model[:-6]
|
||||||
|
if model.endswith("-non-thinking"):
|
||||||
|
model = model[:-13]
|
||||||
|
if "-search" in model and "-non-thinking" in model:
|
||||||
|
model = model[:-20]
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
def _get_safety_settings(model: str) -> List[Dict[str, str]]:
|
||||||
"""获取安全设置"""
|
"""获取安全设置"""
|
||||||
if model == "gemini-2.0-flash-exp":
|
if model == "gemini-2.0-flash-exp":
|
||||||
@@ -144,8 +176,11 @@ def _build_payload(model: str, request: GeminiRequest) -> Dict[str, Any]:
|
|||||||
else:
|
else:
|
||||||
# 客户端没有提供思考配置,使用默认配置
|
# 客户端没有提供思考配置,使用默认配置
|
||||||
if model.endswith("-non-thinking"):
|
if model.endswith("-non-thinking"):
|
||||||
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
if "gemini-2.5-pro" in model:
|
||||||
elif model in settings.THINKING_BUDGET_MAP:
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 128}
|
||||||
|
else:
|
||||||
|
payload["generationConfig"]["thinkingConfig"] = {"thinkingBudget": 0}
|
||||||
|
elif _get_real_model(model) in settings.THINKING_BUDGET_MAP:
|
||||||
if settings.SHOW_THINKING_PROCESS:
|
if settings.SHOW_THINKING_PROCESS:
|
||||||
payload["generationConfig"]["thinkingConfig"] = {
|
payload["generationConfig"]["thinkingConfig"] = {
|
||||||
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(model,1000),
|
"thinkingBudget": settings.THINKING_BUDGET_MAP.get(model,1000),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const SHOW_CLASS = "show"; // For modals
|
|||||||
const API_KEY_REGEX = /AIzaSy\S{33}/g;
|
const API_KEY_REGEX = /AIzaSy\S{33}/g;
|
||||||
const PROXY_REGEX =
|
const PROXY_REGEX =
|
||||||
/(?:https?|socks5):\/\/(?:[^:@\/]+(?::[^@\/]+)?@)?(?:[^:\/\s]+)(?::\d+)?/g;
|
/(?:https?|socks5):\/\/(?:[^:@\/]+(?::[^@\/]+)?@)?(?:[^:\/\s]+)(?::\d+)?/g;
|
||||||
const VERTEX_API_KEY_REGEX = /AQ\.[a-zA-Z0-9_]{50}/g; // 新增 Vertex Express API Key 正则
|
const VERTEX_API_KEY_REGEX = /AQ\.[a-zA-Z0-9_\-]{50}/g; // 新增 Vertex Express API Key 正则
|
||||||
const MASKED_VALUE = "••••••••";
|
const MASKED_VALUE = "••••••••";
|
||||||
|
|
||||||
// DOM Elements - Global Scope for frequently accessed elements
|
// DOM Elements - Global Scope for frequently accessed elements
|
||||||
@@ -713,7 +713,13 @@ async function initConfig() {
|
|||||||
config.SAFETY_SETTINGS = []; // 默认为空数组
|
config.SAFETY_SETTINGS = []; // 默认为空数组
|
||||||
}
|
}
|
||||||
// --- 结束:处理 SAFETY_SETTINGS 默认值 ---
|
// --- 结束:处理 SAFETY_SETTINGS 默认值 ---
|
||||||
|
if (typeof config.URL_CONTEXT_ENABLED === "undefined") {
|
||||||
|
config.URL_CONTEXT_ENABLED = true;
|
||||||
|
}
|
||||||
|
if (!config.URL_CONTEXT_MODELS || !Array.isArray(config.URL_CONTEXT_MODELS)) {
|
||||||
|
config.URL_CONTEXT_MODELS = [];
|
||||||
|
}
|
||||||
|
|
||||||
// --- 新增:处理自动删除错误日志配置的默认值 ---
|
// --- 新增:处理自动删除错误日志配置的默认值 ---
|
||||||
if (typeof config.AUTO_DELETE_ERROR_LOGS_ENABLED === "undefined") {
|
if (typeof config.AUTO_DELETE_ERROR_LOGS_ENABLED === "undefined") {
|
||||||
config.AUTO_DELETE_ERROR_LOGS_ENABLED = false;
|
config.AUTO_DELETE_ERROR_LOGS_ENABLED = false;
|
||||||
@@ -1462,7 +1468,7 @@ function addArrayItem(key) {
|
|||||||
const modelId = addArrayItemWithValue(key, newItemValue); // This adds the DOM element
|
const modelId = addArrayItemWithValue(key, newItemValue); // This adds the DOM element
|
||||||
|
|
||||||
if (key === "THINKING_MODELS" && modelId) {
|
if (key === "THINKING_MODELS" && modelId) {
|
||||||
createAndAppendBudgetMapItem(newItemValue, 0, modelId); // Default budget 0
|
createAndAppendBudgetMapItem(newItemValue, -1, modelId); // Default budget -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,7 +1578,7 @@ function createAndAppendBudgetMapItem(mapKey, mapValue, modelId) {
|
|||||||
const valueInput = document.createElement("input");
|
const valueInput = document.createElement("input");
|
||||||
valueInput.type = "number";
|
valueInput.type = "number";
|
||||||
const intValue = parseInt(mapValue, 10);
|
const intValue = parseInt(mapValue, 10);
|
||||||
valueInput.value = isNaN(intValue) ? 0 : intValue;
|
valueInput.value = isNaN(intValue) ? -1 : intValue;
|
||||||
valueInput.placeholder = "预算 (整数)";
|
valueInput.placeholder = "预算 (整数)";
|
||||||
valueInput.className = `${MAP_VALUE_INPUT_CLASS} w-24 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50`;
|
valueInput.className = `${MAP_VALUE_INPUT_CLASS} w-24 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50`;
|
||||||
valueInput.min = -1;
|
valueInput.min = -1;
|
||||||
@@ -1733,7 +1739,7 @@ function collectFormData() {
|
|||||||
formData["THINKING_BUDGET_MAP"][keyInput.value.trim()] = isNaN(
|
formData["THINKING_BUDGET_MAP"][keyInput.value.trim()] = isNaN(
|
||||||
budgetValue
|
budgetValue
|
||||||
)
|
)
|
||||||
? 0
|
? -1
|
||||||
: budgetValue;
|
: budgetValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2284,7 +2290,7 @@ function handleModelSelection(selectedModelId) {
|
|||||||
);
|
);
|
||||||
if (currentModelHelperTarget.targetKey === "THINKING_MODELS" && modelId) {
|
if (currentModelHelperTarget.targetKey === "THINKING_MODELS" && modelId) {
|
||||||
// Automatically add corresponding budget map item with default budget 0
|
// Automatically add corresponding budget map item with default budget 0
|
||||||
createAndAppendBudgetMapItem(selectedModelId, 0, modelId);
|
createAndAppendBudgetMapItem(selectedModelId, -1, modelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1421,6 +1421,59 @@ endblock %} {% block head_extra_styles %}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 启用网址上下文 -->
|
||||||
|
<div class="mb-6 flex items-center justify-between">
|
||||||
|
<label for="URL_CONTEXT_ENABLED" class="font-semibold text-gray-700"
|
||||||
|
>启用网址上下文</label
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="URL_CONTEXT_ENABLED"
|
||||||
|
id="URL_CONTEXT_ENABLED"
|
||||||
|
class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="URL_CONTEXT_ENABLED"
|
||||||
|
class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 网址上下文模型列表 -->
|
||||||
|
<div class="mb-6">
|
||||||
|
<label
|
||||||
|
for="URL_CONTEXT_MODELS"
|
||||||
|
class="block font-semibold mb-2 text-gray-700"
|
||||||
|
>网址上下文模型列表</label
|
||||||
|
>
|
||||||
|
<div class="array-container" id="URL_CONTEXT_MODELS_container">
|
||||||
|
<!-- 数组项将在这里动态添加 -->
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end gap-2 mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="从列表选择模型添加到下方"
|
||||||
|
class="model-helper-trigger-btn p-2 rounded-md text-violet-300 hover:bg-violet-700 transition-colors"
|
||||||
|
data-target-array-key="URL_CONTEXT_MODELS"
|
||||||
|
>
|
||||||
|
<i class="fas fa-list-ul"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center gap-2"
|
||||||
|
onclick="addArrayItem('URL_CONTEXT_MODELS')"
|
||||||
|
>
|
||||||
|
<i class="fas fa-plus"></i> 添加模型
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<small class="text-gray-500 mt-1 block"
|
||||||
|
>支持网址上下文功能的模型列表</small
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 显示搜索链接 -->
|
<!-- 显示搜索链接 -->
|
||||||
<div class="mb-6 flex items-center justify-between">
|
<div class="mb-6 flex items-center justify-between">
|
||||||
<label for="SHOW_SEARCH_LINK" class="font-semibold text-gray-700"
|
<label for="SHOW_SEARCH_LINK" class="font-semibold text-gray-700"
|
||||||
@@ -1523,7 +1576,7 @@ endblock %} {% block head_extra_styles %}
|
|||||||
</button>
|
</button>
|
||||||
</div> -->
|
</div> -->
|
||||||
<small class="text-gray-500 mt-1 block"
|
<small class="text-gray-500 mt-1 block"
|
||||||
>为每个思考模型设置预算(整数,最大值
|
>为每个思考模型设置预算(-1为auto,最大值
|
||||||
32767),此项与上方模型列表自动关联。</small
|
32767),此项与上方模型列表自动关联。</small
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user