From 3aef4347d74984585b6420197c66e49e540f4aeb Mon Sep 17 00:00:00 2001
From: Chenyme <118253778+chenyme@users.noreply.github.com>
Date: Tue, 16 Dec 2025 16:40:32 +0800
Subject: [PATCH] fix: automatically disable token expiration
---
app/services/grok/processer.py | 42 +++++++++++++++++-----------------
app/services/grok/token.py | 9 ++++++--
2 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/app/services/grok/processer.py b/app/services/grok/processer.py
index d8de920..2c51c69 100644
--- a/app/services/grok/processer.py
+++ b/app/services/grok/processer.py
@@ -210,12 +210,12 @@ class GrokResponseProcessor:
last_video_progress = progress
if show_thinking:
if not video_progress_started:
- content = f"视频已生成{progress}%\\n"
+ content = f"视频已生成{progress}%\n"
video_progress_started = True
elif progress < 100:
- content = f"视频已生成{progress}%\\n"
+ content = f"视频已生成{progress}%\n"
else:
- content = f"视频已生成{progress}%\\n"
+ content = f"视频已生成{progress}%\n"
yield make_chunk(content)
# 视频URL
@@ -252,23 +252,23 @@ class GrokResponseProcessor:
# 8KB分块
for i in range(0, len(parts[1]), 8192):
yield make_chunk(parts[1][i:i+8192])
- yield make_chunk(")\\n")
+ yield make_chunk(")\n")
else:
- yield make_chunk(f"\\n")
+ yield make_chunk(f"\n")
else:
- yield make_chunk(f"\\n")
+ yield make_chunk(f"\n")
else:
- yield make_chunk(f"\\n")
+ yield make_chunk(f"\n")
else:
# URL模式
await image_cache_service.download_image(f"/{img}", auth_token)
img_path = img.replace('/', '-')
base_url = setting.global_config.get("base_url", "")
img_url = f"{base_url}/images/{img_path}" if base_url else f"/images/{img_path}"
- content += f"\\n"
+ content += f"\n"
except Exception as e:
logger.warning(f"[Processor] 处理图片失败: {e}")
- content += f"\\n"
+ content += f"\n"
yield make_chunk(content.strip(), "stop")
return
@@ -298,9 +298,9 @@ class GrokResponseProcessor:
title = result.get("title", "")
url = result.get("url", "")
preview = result.get("preview", "")
- preview_clean = preview.replace("\\n", "") if isinstance(preview, str) else ""
- token += f'\\n- [{title}]({url} "{preview_clean}")'
- token += "\\n"
+ preview_clean = preview.replace("\n", "") if isinstance(preview, str) else ""
+ token += f'\n- [{title}]({url} "{preview_clean}")'
+ token += "\n"
else:
continue
else:
@@ -318,12 +318,12 @@ class GrokResponseProcessor:
should_skip = False
if not is_thinking and current_is_thinking:
if show_thinking:
- content = f"\\n{content}"
+ content = f"\n{content}"
else:
should_skip = True
elif is_thinking and not current_is_thinking:
if show_thinking:
- content = f"\\n\\n{content}"
+ content = f"\n\n{content}"
thinking_finished = True
elif current_is_thinking:
if not show_thinking:
@@ -369,11 +369,11 @@ class GrokResponseProcessor:
video_path = video_url.replace('/', '-')
base_url = setting.global_config.get("base_url", "")
local_url = f"{base_url}/images/{video_path}" if base_url else f"/images/{video_path}"
- return f'\\n'
+ return f'\n'
except Exception as e:
logger.warning(f"[Processor] 缓存视频失败: {e}")
- return f'\\n'
+ return f'\n'
@staticmethod
async def _append_images(content: str, images: list, auth_token: str) -> str:
@@ -385,21 +385,21 @@ class GrokResponseProcessor:
if image_mode == "base64":
base64_str = await image_cache_service.download_base64(f"/{img}", auth_token)
if base64_str:
- content += f"\\n"
+ content += f"\n"
else:
- content += f"\\n"
+ content += f"\n"
else:
cache_path = await image_cache_service.download_image(f"/{img}", auth_token)
if cache_path:
img_path = img.replace('/', '-')
base_url = setting.global_config.get("base_url", "")
img_url = f"{base_url}/images/{img_path}" if base_url else f"/images/{img_path}"
- content += f"\\n"
+ content += f"\n"
else:
- content += f"\\n"
+ content += f"\n"
except Exception as e:
logger.warning(f"[Processor] 处理图片失败: {e}")
- content += f"\\n"
+ content += f"\n"
return content
diff --git a/app/services/grok/token.py b/app/services/grok/token.py
index 1e58008..95aee40 100644
--- a/app/services/grok/token.py
+++ b/app/services/grok/token.py
@@ -169,8 +169,13 @@ class GrokTokenManager:
unused, used = [], []
for key, data in tokens.items():
+ # 跳过已失效的token
if data.get("status") == "expired":
continue
+
+ # 跳过失败次数过多的token(任何错误状态码)
+ if data.get("failedCount", 0) >= MAX_FAILURES:
+ continue
remaining = int(data.get(field, -1))
if remaining == 0:
@@ -312,9 +317,9 @@ class GrokTokenManager:
f"次数: {data['failedCount']}/{MAX_FAILURES}, 原因: {msg}"
)
- if status == TOKEN_INVALID and data["failedCount"] >= MAX_FAILURES:
+ if 400 <= status < 500 and data["failedCount"] >= MAX_FAILURES:
data["status"] = "expired"
- logger.error(f"[Token] 标记失效: {sso[:10]}... (连续401错误{data['failedCount']}次)")
+ logger.error(f"[Token] 标记失效: {sso[:10]}... (连续{status}错误{data['failedCount']}次)")
await self._save_data()