Skip to content

Commit 03d40b1

Browse files
authored
Merge pull request #213 from liucong2013/feature/disable-url-context-by-default
feat: 默认禁用URL上下文并更新注入模型
2 parents fcb73c3 + 727e462 commit 03d40b1

7 files changed

Lines changed: 300 additions & 286 deletions

File tree

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ DEFAULT_TOP_P=0.95
8686
DEFAULT_STOP_SEQUENCES=["用户:"]
8787

8888
# 是否在处理请求时自动打开并使用 "URL Context" 功能,此工具功能详情可参考:https://ai.google.dev/gemini-api/docs/url-context
89-
ENABLE_URL_CONTEXT=true
89+
ENABLE_URL_CONTEXT=false
9090

9191
# 是否默认启用 "指定思考预算" 功能 (true/false),不启用时模型一般将自行决定思考预算
9292
# 当 API 请求中未提供 reasoning_effort 参数时将使用此值。

browser_utils/more_modles.js

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,18 @@
2323
// 模型配置列表
2424
// 已按要求将 jfdksal98a 放到 blacktooth 的下面
2525
const MODELS_TO_INJECT = [
26-
// Blacktooth 模型 (原 Toothless)
27-
{
28-
name: 'models/blacktooth-ab-test', // 已改为 blacktooth-ab-test
29-
displayName: `🏴‍☠️ Blacktooth (脚本 ${SCRIPT_VERSION})`, // emoji 改为 🏴‍☠️,名称改为 Blacktooth
30-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
31-
},
32-
// --- jfdksal98a 模型已移动到此处 ---
33-
{
34-
name: 'models/jfdksal98a',
35-
displayName: `🪐 jfdksal98a (脚本 ${SCRIPT_VERSION})`,
36-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
37-
},
38-
// --- 其他模型 ---
39-
{
40-
name: 'models/gemini-2.5-pro-preview-03-25',
41-
displayName: `✨ Gemini 2.5 Pro 03-25 (脚本 ${SCRIPT_VERSION})`,
42-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
43-
},
44-
{
45-
name: 'models/goldmane-ab-test',
46-
displayName: `🦁 Goldmane (脚本 ${SCRIPT_VERSION})`,
47-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
48-
},
49-
{
50-
name: 'models/claybrook-ab-test',
51-
displayName: `💧 Claybrook (脚本 ${SCRIPT_VERSION})`,
52-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
53-
},
54-
{
55-
name: 'models/frostwind-ab-test',
56-
displayName: `❄️ Frostwind (脚本 ${SCRIPT_VERSION})`,
57-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
58-
},
59-
{
60-
name: 'models/calmriver-ab-test',
61-
displayName: `🌊 Calmriver (脚本 ${SCRIPT_VERSION})`,
62-
description: `由脚本 ${SCRIPT_VERSION} 注入的模型`
63-
}
26+
{ name: 'models/gemini-2.5-pro-preview-03-25', displayName: `✨ Gemini 2.5 Pro 03-25 (Script ${SCRIPT_VERSION})`, description: `Model injected by script ${SCRIPT_VERSION}` },
27+
{ name: 'models/gemini-2.5-pro-exp-03-25', displayName: `✨ Gemini 2.5 Pro 03-25 (Script ${SCRIPT_VERSION})`, description: `Model injected by script ${SCRIPT_VERSION}` },
28+
{ name: 'models/gemini-2.5-pro-preview-06-05', displayName: `✨ Gemini 2.5 Pro 03-25 (Script ${SCRIPT_VERSION})`, description: `Model injected by script ${SCRIPT_VERSION}` },
29+
30+
//下面模型已经失效,留下来怀念
31+
// { name: 'models/blacktooth-ab-test', displayName: `🏴‍☠️ Blacktooth (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
32+
// { name: 'models/jfdksal98a', displayName: `🪐 jfdksal98a (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
33+
// { name: 'models/gemini-2.5-pro-preview-03-25', displayName: `✨ Gemini 2.5 Pro 03-25 (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
34+
// { name: 'models/goldmane-ab-test', displayName: `🦁 Goldmane (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
35+
// { name: 'models/claybrook-ab-test', displayName: `💧 Claybrook (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
36+
// { name: 'models/frostwind-ab-test', displayName: `❄️ Frostwind (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` },
37+
// { name: 'models/calmriver-ab-test', displayName: `🌊 Calmriver (脚本 ${SCRIPT_VERSION})`, description: `由脚本 ${SCRIPT_VERSION} 注入的模型` }
6438
];
6539

6640
// JSON 结构中的字段索引

browser_utils/page_controller.py

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ async def adjust_parameters(self, request_params: Dict[str, Any], page_params_ca
6262
await self._adjust_top_p(top_p_to_set, check_client_disconnected)
6363
await self._check_disconnect(check_client_disconnected, "End Parameter Adjustment")
6464

65+
# 确保工具面板已展开,以便调整高级设置
66+
await self._ensure_tools_panel_expanded(check_client_disconnected)
67+
6568
# 调整URL CONTEXT
6669
if ENABLE_URL_CONTEXT:
6770
await self._open_url_content(check_client_disconnected)
@@ -77,9 +80,16 @@ async def adjust_parameters(self, request_params: Dict[str, Any], page_params_ca
7780
async def _handle_thinking_budget(self, request_params: Dict[str, Any], check_client_disconnected: Callable):
7881
"""处理思考预算的调整逻辑。"""
7982
reasoning_effort = request_params.get('reasoning_effort')
80-
if reasoning_effort is not None:
81-
# 用户指定了,则开启并设置
82-
self.logger.info(f"[{self.req_id}] 用户指定了 reasoning_effort: {reasoning_effort}。")
83+
84+
# 检查用户是否明确禁用了思考预算
85+
should_disable_budget = isinstance(reasoning_effort, str) and reasoning_effort.lower() == 'none'
86+
87+
if should_disable_budget:
88+
self.logger.info(f"[{self.req_id}] 用户通过 reasoning_effort='none' 明确禁用思考预算。")
89+
await self._control_thinking_budget_toggle(should_be_checked=False, check_client_disconnected=check_client_disconnected)
90+
elif reasoning_effort is not None:
91+
# 用户指定了非 'none' 的值,则开启并设置
92+
self.logger.info(f"[{self.req_id}] 用户指定了 reasoning_effort: {reasoning_effort},将启用并设置思考预算。")
8393
await self._control_thinking_budget_toggle(should_be_checked=True, check_client_disconnected=check_client_disconnected)
8494
await self._adjust_thinking_budget(reasoning_effort, check_client_disconnected)
8595
else:
@@ -209,27 +219,50 @@ async def _adjust_google_search(self, request_params: Dict[str, Any], check_clie
209219
if isinstance(e, ClientDisconnectedError):
210220
raise
211221

212-
async def _open_url_content(self,check_client_disconnected: Callable):
222+
async def _ensure_tools_panel_expanded(self, check_client_disconnected: Callable):
223+
"""确保包含高级工具(URL上下文、思考预算等)的面板是展开的。"""
224+
self.logger.info(f"[{self.req_id}] 检查并确保工具面板已展开...")
213225
try:
214226
collapse_tools_locator = self.page.locator('button[aria-label="Expand or collapse tools"]')
227+
await expect_async(collapse_tools_locator).to_be_visible(timeout=5000)
228+
215229
grandparent_locator = collapse_tools_locator.locator("xpath=../..")
230+
class_string = await grandparent_locator.get_attribute("class", timeout=3000)
216231

217-
# 3. 获取祖父级元素的 class 属性值
218-
# get_attribute 返回一个包含所有 class 的字符串,例如 "menu dropdown active"
219-
class_string = await grandparent_locator.get_attribute("class")
220-
221-
# 4. 在 Python 中进行判断
222-
# 确保 class_string 不是 None,并且 'expanded' 是一个独立的 class
223232
if class_string and "expanded" not in class_string.split():
233+
self.logger.info(f"[{self.req_id}] 工具面板未展开,正在点击以展开...")
224234
await collapse_tools_locator.click(timeout=CLICK_TIMEOUT_MS)
225-
await asyncio.sleep(0.5)
235+
await self._check_disconnect(check_client_disconnected, "展开工具面板后")
236+
# 等待展开动画完成
237+
await expect_async(grandparent_locator).to_have_class(re.compile(r'.*expanded.*'), timeout=5000)
238+
self.logger.info(f"[{self.req_id}] ✅ 工具面板已成功展开。")
239+
else:
240+
self.logger.info(f"[{self.req_id}] 工具面板已处于展开状态。")
241+
except Exception as e:
242+
self.logger.error(f"[{self.req_id}] ❌ 展开工具面板时发生错误: {e}")
243+
# 即使出错,也继续尝试执行后续操作,但记录错误
244+
if isinstance(e, ClientDisconnectedError):
245+
raise
246+
247+
async def _open_url_content(self,check_client_disconnected: Callable):
248+
"""仅负责打开 URL Context 开关,前提是面板已展开。"""
249+
try:
250+
self.logger.info(f"[{self.req_id}] 检查并启用 URL Context 开关...")
226251
use_url_content_selector = self.page.locator(USE_URL_CONTEXT_SELECTOR)
252+
await expect_async(use_url_content_selector).to_be_visible(timeout=5000)
253+
227254
is_checked = await use_url_content_selector.get_attribute("aria-checked")
228255
if "false" == is_checked:
256+
self.logger.info(f"[{self.req_id}] URL Context 开关未开启,正在点击以开启...")
229257
await use_url_content_selector.click(timeout=CLICK_TIMEOUT_MS)
230-
await self._check_disconnect(check_client_disconnected, "点击URLCONTEXT")
258+
await self._check_disconnect(check_client_disconnected, "点击URLCONTEXT后")
259+
self.logger.info(f"[{self.req_id}] ✅ URL Context 开关已点击。")
260+
else:
261+
self.logger.info(f"[{self.req_id}] URL Context 开关已处于开启状态。")
231262
except Exception as e:
232-
self.logger.error(f"[{self.req_id}] ❌ 操作USE_URL_CONTEXT_SELECTOR时发生错误:{e}。")
263+
self.logger.error(f"[{self.req_id}] ❌ 操作 USE_URL_CONTEXT_SELECTOR 时发生错误:{e}。")
264+
if isinstance(e, ClientDisconnectedError):
265+
raise
233266

234267
async def _control_thinking_budget_toggle(self, should_be_checked: bool, check_client_disconnected: Callable):
235268
"""

config/constants.py

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
1-
"""
2-
常量配置模块
3-
包含所有固定的常量定义,如模型名称、标记符、文件名等
4-
"""
5-
6-
import os
7-
import json
8-
from dotenv import load_dotenv
9-
10-
# 加载 .env 文件
11-
load_dotenv()
12-
13-
# --- 模型相关常量 ---
14-
MODEL_NAME = os.environ.get('MODEL_NAME', 'AI-Studio_Proxy_API')
15-
CHAT_COMPLETION_ID_PREFIX = os.environ.get('CHAT_COMPLETION_ID_PREFIX', 'chatcmpl-')
16-
DEFAULT_FALLBACK_MODEL_ID = os.environ.get('DEFAULT_FALLBACK_MODEL_ID', "no model list")
17-
18-
# --- 默认参数值 ---
19-
DEFAULT_TEMPERATURE = float(os.environ.get('DEFAULT_TEMPERATURE', '1.0'))
20-
DEFAULT_MAX_OUTPUT_TOKENS = int(os.environ.get('DEFAULT_MAX_OUTPUT_TOKENS', '65536'))
21-
DEFAULT_TOP_P = float(os.environ.get('DEFAULT_TOP_P', '0.95'))
22-
# --- 默认功能开关 ---
23-
ENABLE_URL_CONTEXT = os.environ.get('ENABLE_URL_CONTEXT', 'true').lower() in ('true', '1', 'yes')
24-
ENABLE_THINKING_BUDGET = os.environ.get('ENABLE_THINKING_BUDGET', 'false').lower() in ('true', '1', 'yes')
25-
DEFAULT_THINKING_BUDGET = int(os.environ.get('DEFAULT_THINKING_BUDGET', '8192'))
26-
ENABLE_GOOGLE_SEARCH = os.environ.get('ENABLE_GOOGLE_SEARCH', 'false').lower() in ('true', '1', 'yes')
27-
28-
# 默认停止序列 - 支持 JSON 格式配置
29-
try:
30-
DEFAULT_STOP_SEQUENCES = json.loads(os.environ.get('DEFAULT_STOP_SEQUENCES', '["用户:"]'))
31-
except (json.JSONDecodeError, TypeError):
32-
DEFAULT_STOP_SEQUENCES = ["用户:"] # 回退到默认值
33-
34-
# --- URL模式 ---
35-
AI_STUDIO_URL_PATTERN = os.environ.get('AI_STUDIO_URL_PATTERN', 'aistudio.google.com/')
36-
MODELS_ENDPOINT_URL_CONTAINS = os.environ.get('MODELS_ENDPOINT_URL_CONTAINS', "MakerSuiteService/ListModels")
37-
38-
# --- 输入标记符 ---
39-
USER_INPUT_START_MARKER_SERVER = os.environ.get('USER_INPUT_START_MARKER_SERVER', "__USER_INPUT_START__")
40-
USER_INPUT_END_MARKER_SERVER = os.environ.get('USER_INPUT_END_MARKER_SERVER', "__USER_INPUT_END__")
41-
42-
# --- 文件名常量 ---
43-
EXCLUDED_MODELS_FILENAME = os.environ.get('EXCLUDED_MODELS_FILENAME', "excluded_models.txt")
44-
45-
# --- 流状态配置 ---
46-
STREAM_TIMEOUT_LOG_STATE = {
47-
"consecutive_timeouts": 0,
48-
"last_error_log_time": 0.0, # 使用 time.monotonic()
49-
"suppress_until_time": 0.0, # 使用 time.monotonic()
50-
"max_initial_errors": int(os.environ.get('STREAM_MAX_INITIAL_ERRORS', '3')),
51-
"warning_interval_after_suppress": float(os.environ.get('STREAM_WARNING_INTERVAL_AFTER_SUPPRESS', '60.0')),
52-
"suppress_duration_after_initial_burst": float(os.environ.get('STREAM_SUPPRESS_DURATION_AFTER_INITIAL_BURST', '400.0')),
1+
"""
2+
常量配置模块
3+
包含所有固定的常量定义,如模型名称、标记符、文件名等
4+
"""
5+
6+
import os
7+
import json
8+
from dotenv import load_dotenv
9+
10+
# 加载 .env 文件
11+
load_dotenv()
12+
13+
# --- 模型相关常量 ---
14+
MODEL_NAME = os.environ.get('MODEL_NAME', 'AI-Studio_Proxy_API')
15+
CHAT_COMPLETION_ID_PREFIX = os.environ.get('CHAT_COMPLETION_ID_PREFIX', 'chatcmpl-')
16+
DEFAULT_FALLBACK_MODEL_ID = os.environ.get('DEFAULT_FALLBACK_MODEL_ID', "no model list")
17+
18+
# --- 默认参数值 ---
19+
DEFAULT_TEMPERATURE = float(os.environ.get('DEFAULT_TEMPERATURE', '1.0'))
20+
DEFAULT_MAX_OUTPUT_TOKENS = int(os.environ.get('DEFAULT_MAX_OUTPUT_TOKENS', '65536'))
21+
DEFAULT_TOP_P = float(os.environ.get('DEFAULT_TOP_P', '0.95'))
22+
# --- 默认功能开关 ---
23+
ENABLE_URL_CONTEXT = os.environ.get('ENABLE_URL_CONTEXT', 'false').lower() in ('true', '1', 'yes')
24+
ENABLE_THINKING_BUDGET = os.environ.get('ENABLE_THINKING_BUDGET', 'false').lower() in ('true', '1', 'yes')
25+
DEFAULT_THINKING_BUDGET = int(os.environ.get('DEFAULT_THINKING_BUDGET', '8192'))
26+
ENABLE_GOOGLE_SEARCH = os.environ.get('ENABLE_GOOGLE_SEARCH', 'false').lower() in ('true', '1', 'yes')
27+
28+
# 默认停止序列 - 支持 JSON 格式配置
29+
try:
30+
DEFAULT_STOP_SEQUENCES = json.loads(os.environ.get('DEFAULT_STOP_SEQUENCES', '["用户:"]'))
31+
except (json.JSONDecodeError, TypeError):
32+
DEFAULT_STOP_SEQUENCES = ["用户:"] # 回退到默认值
33+
34+
# --- URL模式 ---
35+
AI_STUDIO_URL_PATTERN = os.environ.get('AI_STUDIO_URL_PATTERN', 'aistudio.google.com/')
36+
MODELS_ENDPOINT_URL_CONTAINS = os.environ.get('MODELS_ENDPOINT_URL_CONTAINS', "MakerSuiteService/ListModels")
37+
38+
# --- 输入标记符 ---
39+
USER_INPUT_START_MARKER_SERVER = os.environ.get('USER_INPUT_START_MARKER_SERVER', "__USER_INPUT_START__")
40+
USER_INPUT_END_MARKER_SERVER = os.environ.get('USER_INPUT_END_MARKER_SERVER', "__USER_INPUT_END__")
41+
42+
# --- 文件名常量 ---
43+
EXCLUDED_MODELS_FILENAME = os.environ.get('EXCLUDED_MODELS_FILENAME', "excluded_models.txt")
44+
45+
# --- 流状态配置 ---
46+
STREAM_TIMEOUT_LOG_STATE = {
47+
"consecutive_timeouts": 0,
48+
"last_error_log_time": 0.0, # 使用 time.monotonic()
49+
"suppress_until_time": 0.0, # 使用 time.monotonic()
50+
"max_initial_errors": int(os.environ.get('STREAM_MAX_INITIAL_ERRORS', '3')),
51+
"warning_interval_after_suppress": float(os.environ.get('STREAM_WARNING_INTERVAL_AFTER_SUPPRESS', '60.0')),
52+
"suppress_duration_after_initial_burst": float(os.environ.get('STREAM_SUPPRESS_DURATION_AFTER_INITIAL_BURST', '400.0')),
5353
}

0 commit comments

Comments
 (0)