Spaces:
Paused
Paused
Upload 5 files
Browse files- config/__init__.py +88 -0
- config/constants.py +48 -0
- config/selectors.py +42 -0
- config/settings.py +54 -0
- config/timeouts.py +40 -0
config/__init__.py
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
配置模块统一入口
|
| 3 |
+
导出所有配置项,便于其他模块导入使用
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
# 从各个配置文件导入所有配置项
|
| 7 |
+
from .constants import *
|
| 8 |
+
from .timeouts import *
|
| 9 |
+
from .selectors import *
|
| 10 |
+
from .settings import *
|
| 11 |
+
|
| 12 |
+
# 显式导出主要配置项(用于IDE自动完成和类型检查)
|
| 13 |
+
__all__ = [
|
| 14 |
+
# 常量配置
|
| 15 |
+
'MODEL_NAME',
|
| 16 |
+
'CHAT_COMPLETION_ID_PREFIX',
|
| 17 |
+
'DEFAULT_FALLBACK_MODEL_ID',
|
| 18 |
+
'DEFAULT_TEMPERATURE',
|
| 19 |
+
'DEFAULT_MAX_OUTPUT_TOKENS',
|
| 20 |
+
'DEFAULT_TOP_P',
|
| 21 |
+
'DEFAULT_STOP_SEQUENCES',
|
| 22 |
+
'AI_STUDIO_URL_PATTERN',
|
| 23 |
+
'MODELS_ENDPOINT_URL_CONTAINS',
|
| 24 |
+
'USER_INPUT_START_MARKER_SERVER',
|
| 25 |
+
'USER_INPUT_END_MARKER_SERVER',
|
| 26 |
+
'EXCLUDED_MODELS_FILENAME',
|
| 27 |
+
'STREAM_TIMEOUT_LOG_STATE',
|
| 28 |
+
|
| 29 |
+
# 超时配置
|
| 30 |
+
'RESPONSE_COMPLETION_TIMEOUT',
|
| 31 |
+
'INITIAL_WAIT_MS_BEFORE_POLLING',
|
| 32 |
+
'POLLING_INTERVAL',
|
| 33 |
+
'POLLING_INTERVAL_STREAM',
|
| 34 |
+
'SILENCE_TIMEOUT_MS',
|
| 35 |
+
'POST_SPINNER_CHECK_DELAY_MS',
|
| 36 |
+
'FINAL_STATE_CHECK_TIMEOUT_MS',
|
| 37 |
+
'POST_COMPLETION_BUFFER',
|
| 38 |
+
'CLEAR_CHAT_VERIFY_TIMEOUT_MS',
|
| 39 |
+
'CLEAR_CHAT_VERIFY_INTERVAL_MS',
|
| 40 |
+
'CLICK_TIMEOUT_MS',
|
| 41 |
+
'CLIPBOARD_READ_TIMEOUT_MS',
|
| 42 |
+
'WAIT_FOR_ELEMENT_TIMEOUT_MS',
|
| 43 |
+
'PSEUDO_STREAM_DELAY',
|
| 44 |
+
|
| 45 |
+
# 选择器配置
|
| 46 |
+
'PROMPT_TEXTAREA_SELECTOR',
|
| 47 |
+
'INPUT_SELECTOR',
|
| 48 |
+
'INPUT_SELECTOR2',
|
| 49 |
+
'SUBMIT_BUTTON_SELECTOR',
|
| 50 |
+
'CLEAR_CHAT_BUTTON_SELECTOR',
|
| 51 |
+
'CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR',
|
| 52 |
+
'RESPONSE_CONTAINER_SELECTOR',
|
| 53 |
+
'RESPONSE_TEXT_SELECTOR',
|
| 54 |
+
'LOADING_SPINNER_SELECTOR',
|
| 55 |
+
'OVERLAY_SELECTOR',
|
| 56 |
+
'ERROR_TOAST_SELECTOR',
|
| 57 |
+
'EDIT_MESSAGE_BUTTON_SELECTOR',
|
| 58 |
+
'MESSAGE_TEXTAREA_SELECTOR',
|
| 59 |
+
'FINISH_EDIT_BUTTON_SELECTOR',
|
| 60 |
+
'MORE_OPTIONS_BUTTON_SELECTOR',
|
| 61 |
+
'COPY_MARKDOWN_BUTTON_SELECTOR',
|
| 62 |
+
'COPY_MARKDOWN_BUTTON_SELECTOR_ALT',
|
| 63 |
+
'MAX_OUTPUT_TOKENS_SELECTOR',
|
| 64 |
+
'STOP_SEQUENCE_INPUT_SELECTOR',
|
| 65 |
+
'MAT_CHIP_REMOVE_BUTTON_SELECTOR',
|
| 66 |
+
'TOP_P_INPUT_SELECTOR',
|
| 67 |
+
'TEMPERATURE_INPUT_SELECTOR',
|
| 68 |
+
|
| 69 |
+
# 设置配置
|
| 70 |
+
'DEBUG_LOGS_ENABLED',
|
| 71 |
+
'TRACE_LOGS_ENABLED',
|
| 72 |
+
'AUTO_SAVE_AUTH',
|
| 73 |
+
'AUTH_SAVE_TIMEOUT',
|
| 74 |
+
'AUTO_CONFIRM_LOGIN',
|
| 75 |
+
'AUTH_PROFILES_DIR',
|
| 76 |
+
'ACTIVE_AUTH_DIR',
|
| 77 |
+
'SAVED_AUTH_DIR',
|
| 78 |
+
'LOG_DIR',
|
| 79 |
+
'APP_LOG_FILE_PATH',
|
| 80 |
+
'NO_PROXY_ENV',
|
| 81 |
+
'ENABLE_SCRIPT_INJECTION',
|
| 82 |
+
'USERSCRIPT_PATH',
|
| 83 |
+
|
| 84 |
+
# 工具函数
|
| 85 |
+
'get_environment_variable',
|
| 86 |
+
'get_boolean_env',
|
| 87 |
+
'get_int_env',
|
| 88 |
+
]
|
config/constants.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
# 默认停止序列 - 支持 JSON 格式配置
|
| 24 |
+
try:
|
| 25 |
+
DEFAULT_STOP_SEQUENCES = json.loads(os.environ.get('DEFAULT_STOP_SEQUENCES', '["用户:"]'))
|
| 26 |
+
except (json.JSONDecodeError, TypeError):
|
| 27 |
+
DEFAULT_STOP_SEQUENCES = ["用户:"] # 回退到默认值
|
| 28 |
+
|
| 29 |
+
# --- URL模式 ---
|
| 30 |
+
AI_STUDIO_URL_PATTERN = os.environ.get('AI_STUDIO_URL_PATTERN', 'aistudio.google.com/')
|
| 31 |
+
MODELS_ENDPOINT_URL_CONTAINS = os.environ.get('MODELS_ENDPOINT_URL_CONTAINS', "MakerSuiteService/ListModels")
|
| 32 |
+
|
| 33 |
+
# --- 输入标记符 ---
|
| 34 |
+
USER_INPUT_START_MARKER_SERVER = os.environ.get('USER_INPUT_START_MARKER_SERVER', "__USER_INPUT_START__")
|
| 35 |
+
USER_INPUT_END_MARKER_SERVER = os.environ.get('USER_INPUT_END_MARKER_SERVER', "__USER_INPUT_END__")
|
| 36 |
+
|
| 37 |
+
# --- 文件名常量 ---
|
| 38 |
+
EXCLUDED_MODELS_FILENAME = os.environ.get('EXCLUDED_MODELS_FILENAME', "excluded_models.txt")
|
| 39 |
+
|
| 40 |
+
# --- 流状态配置 ---
|
| 41 |
+
STREAM_TIMEOUT_LOG_STATE = {
|
| 42 |
+
"consecutive_timeouts": 0,
|
| 43 |
+
"last_error_log_time": 0.0, # 使用 time.monotonic()
|
| 44 |
+
"suppress_until_time": 0.0, # 使用 time.monotonic()
|
| 45 |
+
"max_initial_errors": int(os.environ.get('STREAM_MAX_INITIAL_ERRORS', '3')),
|
| 46 |
+
"warning_interval_after_suppress": float(os.environ.get('STREAM_WARNING_INTERVAL_AFTER_SUPPRESS', '60.0')),
|
| 47 |
+
"suppress_duration_after_initial_burst": float(os.environ.get('STREAM_SUPPRESS_DURATION_AFTER_INITIAL_BURST', '400.0')),
|
| 48 |
+
}
|
config/selectors.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
CSS选择器配置模块
|
| 3 |
+
包含所有用于页面元素定位的CSS选择器
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
# --- 输入相关选择器 ---
|
| 7 |
+
PROMPT_TEXTAREA_SELECTOR = 'ms-prompt-input-wrapper ms-autosize-textarea textarea'
|
| 8 |
+
INPUT_SELECTOR = PROMPT_TEXTAREA_SELECTOR
|
| 9 |
+
INPUT_SELECTOR2 = PROMPT_TEXTAREA_SELECTOR
|
| 10 |
+
|
| 11 |
+
# --- 按钮选择器 ---
|
| 12 |
+
SUBMIT_BUTTON_SELECTOR = 'button[aria-label="Run"].run-button'
|
| 13 |
+
CLEAR_CHAT_BUTTON_SELECTOR = 'button[data-test-clear="outside"][aria-label="Clear chat"]'
|
| 14 |
+
CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR = 'button.mdc-button:has-text("Continue")'
|
| 15 |
+
|
| 16 |
+
# --- 响应相关选择器 ---
|
| 17 |
+
RESPONSE_CONTAINER_SELECTOR = 'ms-chat-turn .chat-turn-container.model'
|
| 18 |
+
RESPONSE_TEXT_SELECTOR = 'ms-cmark-node.cmark-node'
|
| 19 |
+
|
| 20 |
+
# --- 加载和状态选择器 ---
|
| 21 |
+
LOADING_SPINNER_SELECTOR = 'button[aria-label="Run"].run-button svg .stoppable-spinner'
|
| 22 |
+
OVERLAY_SELECTOR = 'div.cdk-overlay-backdrop'
|
| 23 |
+
|
| 24 |
+
# --- 错误提示选择器 ---
|
| 25 |
+
ERROR_TOAST_SELECTOR = 'div.toast.warning, div.toast.error'
|
| 26 |
+
|
| 27 |
+
# --- 编辑相关选择器 ---
|
| 28 |
+
EDIT_MESSAGE_BUTTON_SELECTOR = 'ms-chat-turn:last-child .actions-container button.toggle-edit-button'
|
| 29 |
+
MESSAGE_TEXTAREA_SELECTOR = 'ms-chat-turn:last-child ms-text-chunk ms-autosize-textarea'
|
| 30 |
+
FINISH_EDIT_BUTTON_SELECTOR = 'ms-chat-turn:last-child .actions-container button.toggle-edit-button[aria-label="Stop editing"]'
|
| 31 |
+
|
| 32 |
+
# --- 菜单和复制相关选择器 ---
|
| 33 |
+
MORE_OPTIONS_BUTTON_SELECTOR = 'div.actions-container div ms-chat-turn-options div > button'
|
| 34 |
+
COPY_MARKDOWN_BUTTON_SELECTOR = 'button.mat-mdc-menu-item:nth-child(4)'
|
| 35 |
+
COPY_MARKDOWN_BUTTON_SELECTOR_ALT = 'div[role="menu"] button:has-text("Copy Markdown")'
|
| 36 |
+
|
| 37 |
+
# --- 设置相关选择器 ---
|
| 38 |
+
MAX_OUTPUT_TOKENS_SELECTOR = 'input[aria-label="Maximum output tokens"]'
|
| 39 |
+
STOP_SEQUENCE_INPUT_SELECTOR = 'input[aria-label="Add stop token"]'
|
| 40 |
+
MAT_CHIP_REMOVE_BUTTON_SELECTOR = 'mat-chip-set mat-chip-row button[aria-label*="Remove"]'
|
| 41 |
+
TOP_P_INPUT_SELECTOR = 'div.settings-item-column:has(h3:text-is("Top P")) input[type="number"].slider-input'
|
| 42 |
+
TEMPERATURE_INPUT_SELECTOR = 'div[data-test-id="temperatureSliderContainer"] input[type="number"].slider-input'
|
config/settings.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
主要设置配置模块
|
| 3 |
+
包含环境变量配置、路径配置、代理配置等运行时设置
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
from dotenv import load_dotenv
|
| 8 |
+
|
| 9 |
+
# 加载 .env 文件
|
| 10 |
+
load_dotenv()
|
| 11 |
+
|
| 12 |
+
# --- 全局日志控制配置 ---
|
| 13 |
+
DEBUG_LOGS_ENABLED = os.environ.get('DEBUG_LOGS_ENABLED', 'false').lower() in ('true', '1', 'yes')
|
| 14 |
+
TRACE_LOGS_ENABLED = os.environ.get('TRACE_LOGS_ENABLED', 'false').lower() in ('true', '1', 'yes')
|
| 15 |
+
|
| 16 |
+
# --- 认证相关配置 ---
|
| 17 |
+
AUTO_SAVE_AUTH = os.environ.get('AUTO_SAVE_AUTH', '').lower() in ('1', 'true', 'yes')
|
| 18 |
+
AUTH_SAVE_TIMEOUT = int(os.environ.get('AUTH_SAVE_TIMEOUT', '30'))
|
| 19 |
+
AUTO_CONFIRM_LOGIN = os.environ.get('AUTO_CONFIRM_LOGIN', 'true').lower() in ('1', 'true', 'yes')
|
| 20 |
+
|
| 21 |
+
# --- 路径配置 ---
|
| 22 |
+
AUTH_PROFILES_DIR = os.path.join(os.path.dirname(__file__), '..', 'auth_profiles')
|
| 23 |
+
ACTIVE_AUTH_DIR = os.path.join(AUTH_PROFILES_DIR, 'active')
|
| 24 |
+
SAVED_AUTH_DIR = os.path.join(AUTH_PROFILES_DIR, 'saved')
|
| 25 |
+
LOG_DIR = os.path.join(os.path.dirname(__file__), '..', 'logs')
|
| 26 |
+
APP_LOG_FILE_PATH = os.path.join(LOG_DIR, 'app.log')
|
| 27 |
+
|
| 28 |
+
def get_environment_variable(key: str, default: str = '') -> str:
|
| 29 |
+
"""获取环境变量值"""
|
| 30 |
+
return os.environ.get(key, default)
|
| 31 |
+
|
| 32 |
+
def get_boolean_env(key: str, default: bool = False) -> bool:
|
| 33 |
+
"""获取布尔型环境变量"""
|
| 34 |
+
value = os.environ.get(key, '').lower()
|
| 35 |
+
if default:
|
| 36 |
+
return value not in ('false', '0', 'no', 'off')
|
| 37 |
+
else:
|
| 38 |
+
return value in ('true', '1', 'yes', 'on')
|
| 39 |
+
|
| 40 |
+
def get_int_env(key: str, default: int = 0) -> int:
|
| 41 |
+
"""获取整型环境变量"""
|
| 42 |
+
try:
|
| 43 |
+
return int(os.environ.get(key, str(default)))
|
| 44 |
+
except (ValueError, TypeError):
|
| 45 |
+
return default
|
| 46 |
+
|
| 47 |
+
# --- 代理配置 ---
|
| 48 |
+
# 注意:代理配置现在在 api_utils/app.py 中动态设置,根据 STREAM_PORT 环境变量决定
|
| 49 |
+
NO_PROXY_ENV = os.environ.get('NO_PROXY')
|
| 50 |
+
|
| 51 |
+
# --- 脚本注入配置 ---
|
| 52 |
+
ENABLE_SCRIPT_INJECTION = get_boolean_env('ENABLE_SCRIPT_INJECTION', True)
|
| 53 |
+
USERSCRIPT_PATH = get_environment_variable('USERSCRIPT_PATH', 'browser_utils/more_modles.js')
|
| 54 |
+
# 注意:MODEL_CONFIG_PATH 已废弃,现在直接从油猴脚本解析模型数据
|
config/timeouts.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
超时和时间配置模块
|
| 3 |
+
包含所有超时时间、轮询间隔等时间相关配置
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
from dotenv import load_dotenv
|
| 8 |
+
|
| 9 |
+
# 加载 .env 文件
|
| 10 |
+
load_dotenv()
|
| 11 |
+
|
| 12 |
+
# --- 响应等待配置 ---
|
| 13 |
+
RESPONSE_COMPLETION_TIMEOUT = int(os.environ.get('RESPONSE_COMPLETION_TIMEOUT', '300000')) # 5 minutes total timeout (in ms)
|
| 14 |
+
INITIAL_WAIT_MS_BEFORE_POLLING = int(os.environ.get('INITIAL_WAIT_MS_BEFORE_POLLING', '500')) # ms, initial wait before polling for response completion
|
| 15 |
+
|
| 16 |
+
# --- 轮询间隔配置 ---
|
| 17 |
+
POLLING_INTERVAL = int(os.environ.get('POLLING_INTERVAL', '300')) # ms
|
| 18 |
+
POLLING_INTERVAL_STREAM = int(os.environ.get('POLLING_INTERVAL_STREAM', '180')) # ms
|
| 19 |
+
|
| 20 |
+
# --- 静默超时配置 ---
|
| 21 |
+
SILENCE_TIMEOUT_MS = int(os.environ.get('SILENCE_TIMEOUT_MS', '60000')) # ms
|
| 22 |
+
|
| 23 |
+
# --- 页面操作超时配置 ---
|
| 24 |
+
POST_SPINNER_CHECK_DELAY_MS = int(os.environ.get('POST_SPINNER_CHECK_DELAY_MS', '500'))
|
| 25 |
+
FINAL_STATE_CHECK_TIMEOUT_MS = int(os.environ.get('FINAL_STATE_CHECK_TIMEOUT_MS', '1500'))
|
| 26 |
+
POST_COMPLETION_BUFFER = int(os.environ.get('POST_COMPLETION_BUFFER', '700'))
|
| 27 |
+
|
| 28 |
+
# --- 清理聊天相关超时 ---
|
| 29 |
+
CLEAR_CHAT_VERIFY_TIMEOUT_MS = int(os.environ.get('CLEAR_CHAT_VERIFY_TIMEOUT_MS', '5000'))
|
| 30 |
+
CLEAR_CHAT_VERIFY_INTERVAL_MS = int(os.environ.get('CLEAR_CHAT_VERIFY_INTERVAL_MS', '2000'))
|
| 31 |
+
|
| 32 |
+
# --- 点击和剪贴板操作超时 ---
|
| 33 |
+
CLICK_TIMEOUT_MS = int(os.environ.get('CLICK_TIMEOUT_MS', '3000'))
|
| 34 |
+
CLIPBOARD_READ_TIMEOUT_MS = int(os.environ.get('CLIPBOARD_READ_TIMEOUT_MS', '3000'))
|
| 35 |
+
|
| 36 |
+
# --- 元素等待超时 ---
|
| 37 |
+
WAIT_FOR_ELEMENT_TIMEOUT_MS = int(os.environ.get('WAIT_FOR_ELEMENT_TIMEOUT_MS', '10000')) # Timeout for waiting for elements like overlays
|
| 38 |
+
|
| 39 |
+
# --- 流相关配置 ---
|
| 40 |
+
PSEUDO_STREAM_DELAY = float(os.environ.get('PSEUDO_STREAM_DELAY', '0.01'))
|