yibaiba commited on
Commit ·
efae661
1
Parent(s): 7fc098b
优化ultra用户生成视频与不同的账号使用不同的 ua
Browse files
src/services/flow_client.py
CHANGED
|
@@ -17,6 +17,80 @@ class FlowClient:
|
|
| 17 |
self.labs_base_url = config.flow_labs_base_url # https://labs.google/fx/api
|
| 18 |
self.api_base_url = config.flow_api_base_url # https://aisandbox-pa.googleapis.com/v1
|
| 19 |
self.timeout = config.flow_timeout
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
async def _make_request(
|
| 22 |
self,
|
|
@@ -54,10 +128,17 @@ class FlowClient:
|
|
| 54 |
if use_at and at_token:
|
| 55 |
headers["authorization"] = f"Bearer {at_token}"
|
| 56 |
|
| 57 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
headers.update({
|
| 59 |
"Content-Type": "application/json",
|
| 60 |
-
"User-Agent":
|
| 61 |
})
|
| 62 |
|
| 63 |
# Log request
|
|
|
|
| 17 |
self.labs_base_url = config.flow_labs_base_url # https://labs.google/fx/api
|
| 18 |
self.api_base_url = config.flow_api_base_url # https://aisandbox-pa.googleapis.com/v1
|
| 19 |
self.timeout = config.flow_timeout
|
| 20 |
+
# 缓存每个账号的 User-Agent
|
| 21 |
+
self._user_agent_cache = {}
|
| 22 |
+
|
| 23 |
+
def _generate_user_agent(self, account_id: str = None) -> str:
|
| 24 |
+
"""基于账号ID生成固定的 User-Agent
|
| 25 |
+
|
| 26 |
+
Args:
|
| 27 |
+
account_id: 账号标识(如 email 或 token_id),相同账号返回相同 UA
|
| 28 |
+
|
| 29 |
+
Returns:
|
| 30 |
+
User-Agent 字符串
|
| 31 |
+
"""
|
| 32 |
+
# 如果没有提供账号ID,生成随机UA
|
| 33 |
+
if not account_id:
|
| 34 |
+
account_id = f"random_{random.randint(1, 999999)}"
|
| 35 |
+
|
| 36 |
+
# 如果已缓存,直接返回
|
| 37 |
+
if account_id in self._user_agent_cache:
|
| 38 |
+
return self._user_agent_cache[account_id]
|
| 39 |
+
|
| 40 |
+
# 使用账号ID作为随机种子,确保同一账号生成相同的UA
|
| 41 |
+
import hashlib
|
| 42 |
+
seed = int(hashlib.md5(account_id.encode()).hexdigest()[:8], 16)
|
| 43 |
+
rng = random.Random(seed)
|
| 44 |
+
|
| 45 |
+
# Chrome 版本池
|
| 46 |
+
chrome_versions = ["130.0.0.0", "131.0.0.0", "132.0.0.0", "129.0.0.0"]
|
| 47 |
+
# Firefox 版本池
|
| 48 |
+
firefox_versions = ["133.0", "132.0", "131.0", "134.0"]
|
| 49 |
+
# Safari 版本池
|
| 50 |
+
safari_versions = ["18.2", "18.1", "18.0", "17.6"]
|
| 51 |
+
# Edge 版本池
|
| 52 |
+
edge_versions = ["130.0.0.0", "131.0.0.0", "132.0.0.0"]
|
| 53 |
+
|
| 54 |
+
# 操作系统配置
|
| 55 |
+
os_configs = [
|
| 56 |
+
# Windows
|
| 57 |
+
{
|
| 58 |
+
"platform": "Windows NT 10.0; Win64; x64",
|
| 59 |
+
"browsers": [
|
| 60 |
+
lambda r: f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{r.choice(chrome_versions)} Safari/537.36",
|
| 61 |
+
lambda r: f"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:{r.choice(firefox_versions).split('.')[0]}.0) Gecko/20100101 Firefox/{r.choice(firefox_versions)}",
|
| 62 |
+
lambda r: f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{r.choice(chrome_versions)} Safari/537.36 Edg/{r.choice(edge_versions)}",
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
# macOS
|
| 66 |
+
{
|
| 67 |
+
"platform": "Macintosh; Intel Mac OS X 10_15_7",
|
| 68 |
+
"browsers": [
|
| 69 |
+
lambda r: f"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{r.choice(chrome_versions)} Safari/537.36",
|
| 70 |
+
lambda r: f"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/{r.choice(safari_versions)} Safari/605.1.15",
|
| 71 |
+
lambda r: f"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.{r.randint(0, 7)}; rv:{r.choice(firefox_versions).split('.')[0]}.0) Gecko/20100101 Firefox/{r.choice(firefox_versions)}",
|
| 72 |
+
]
|
| 73 |
+
},
|
| 74 |
+
# Linux
|
| 75 |
+
{
|
| 76 |
+
"platform": "X11; Linux x86_64",
|
| 77 |
+
"browsers": [
|
| 78 |
+
lambda r: f"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{r.choice(chrome_versions)} Safari/537.36",
|
| 79 |
+
lambda r: f"Mozilla/5.0 (X11; Linux x86_64; rv:{r.choice(firefox_versions).split('.')[0]}.0) Gecko/20100101 Firefox/{r.choice(firefox_versions)}",
|
| 80 |
+
lambda r: f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{r.choice(firefox_versions).split('.')[0]}.0) Gecko/20100101 Firefox/{r.choice(firefox_versions)}",
|
| 81 |
+
]
|
| 82 |
+
}
|
| 83 |
+
]
|
| 84 |
+
|
| 85 |
+
# 使用固定种子随机选择操作系统和浏览器
|
| 86 |
+
os_config = rng.choice(os_configs)
|
| 87 |
+
browser_generator = rng.choice(os_config["browsers"])
|
| 88 |
+
user_agent = browser_generator(rng)
|
| 89 |
+
|
| 90 |
+
# 缓存结果
|
| 91 |
+
self._user_agent_cache[account_id] = user_agent
|
| 92 |
+
|
| 93 |
+
return user_agent
|
| 94 |
|
| 95 |
async def _make_request(
|
| 96 |
self,
|
|
|
|
| 128 |
if use_at and at_token:
|
| 129 |
headers["authorization"] = f"Bearer {at_token}"
|
| 130 |
|
| 131 |
+
# 确定账号标识(优先使用 token 的前16个字符作为标识)
|
| 132 |
+
account_id = None
|
| 133 |
+
if st_token:
|
| 134 |
+
account_id = st_token[:16] # 使用 ST 的前16个字符
|
| 135 |
+
elif at_token:
|
| 136 |
+
account_id = at_token[:16] # 使用 AT 的前16个字符
|
| 137 |
+
|
| 138 |
+
# 通用请求头 - 基于账号生成固定的 User-Agent
|
| 139 |
headers.update({
|
| 140 |
"Content-Type": "application/json",
|
| 141 |
+
"User-Agent": self._generate_user_agent(account_id)
|
| 142 |
})
|
| 143 |
|
| 144 |
# Log request
|
src/services/generation_handler.py
CHANGED
|
@@ -644,6 +644,44 @@ class GenerationHandler:
|
|
| 644 |
min_images = model_config.get("min_images", 0)
|
| 645 |
max_images = model_config.get("max_images", 0)
|
| 646 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
# 图片数量
|
| 648 |
image_count = len(images) if images else 0
|
| 649 |
|
|
|
|
| 644 |
min_images = model_config.get("min_images", 0)
|
| 645 |
max_images = model_config.get("max_images", 0)
|
| 646 |
|
| 647 |
+
# 根据账号tier自动调整模型 key
|
| 648 |
+
model_key = model_config["model_key"]
|
| 649 |
+
user_tier = token.user_paygate_tier or "PAYGATE_TIER_ONE"
|
| 650 |
+
|
| 651 |
+
# TIER_TWO 账号需要使用 ultra 版本的模型
|
| 652 |
+
if user_tier == "PAYGATE_TIER_TWO":
|
| 653 |
+
# 如果模型 key 不包含 ultra,自动添加
|
| 654 |
+
if "ultra" not in model_key:
|
| 655 |
+
# veo_3_1_i2v_s_fast_fl -> veo_3_1_i2v_s_fast_ultra_fl
|
| 656 |
+
# veo_3_1_t2v_fast -> veo_3_1_t2v_fast_ultra
|
| 657 |
+
# veo_3_0_r2v_fast -> veo_3_0_r2v_fast_ultra
|
| 658 |
+
if "_fl" in model_key:
|
| 659 |
+
model_key = model_key.replace("_fl", "_ultra_fl")
|
| 660 |
+
elif model_key.endswith("_fast"):
|
| 661 |
+
model_key = model_key + "_ultra"
|
| 662 |
+
elif "_fast_" in model_key:
|
| 663 |
+
model_key = model_key.replace("_fast_", "_fast_ultra_")
|
| 664 |
+
|
| 665 |
+
if stream:
|
| 666 |
+
yield self._create_stream_chunk(f"TIER_TWO 账号自动切换到 ultra 模型: {model_key}\n")
|
| 667 |
+
debug_logger.log_info(f"[VIDEO] TIER_TWO 账号,模型自动调整: {model_config['model_key']} -> {model_key}")
|
| 668 |
+
|
| 669 |
+
# TIER_ONE 账号需要使用非 ultra 版本
|
| 670 |
+
elif user_tier == "PAYGATE_TIER_ONE":
|
| 671 |
+
# 如果模型 key 包含 ultra,需要移除(避免用户误用)
|
| 672 |
+
if "ultra" in model_key:
|
| 673 |
+
# veo_3_1_i2v_s_fast_ultra_fl -> veo_3_1_i2v_s_fast_fl
|
| 674 |
+
# veo_3_1_t2v_fast_ultra -> veo_3_1_t2v_fast
|
| 675 |
+
model_key = model_key.replace("_ultra_fl", "_fl").replace("_ultra", "")
|
| 676 |
+
|
| 677 |
+
if stream:
|
| 678 |
+
yield self._create_stream_chunk(f"TIER_ONE 账号自动切换到标准模型: {model_key}\n")
|
| 679 |
+
debug_logger.log_info(f"[VIDEO] TIER_ONE 账号,模型自动调整: {model_config['model_key']} -> {model_key}")
|
| 680 |
+
|
| 681 |
+
# 更新 model_config 中的 model_key
|
| 682 |
+
model_config = dict(model_config) # 创建副本避免修改原配置
|
| 683 |
+
model_config["model_key"] = model_key
|
| 684 |
+
|
| 685 |
# 图片数量
|
| 686 |
image_count = len(images) if images else 0
|
| 687 |
|