Skip to content

Commit 72f71ac

Browse files
committed
feat: Enhance error handling and text extraction in AI response processing
- Increased SILENCE_TIMEOUT_MS from 1500ms to 3000ms for better response handling. - Improved the get_raw_text_content function to prioritize visible <pre> elements for text extraction. - Added robust error handling and fallback mechanisms when extracting text from response elements. - Implemented a cleaning process to remove known UI text elements from the extracted response. - Updated logging to provide clearer insights during the text extraction process.
1 parent 792687d commit 72f71ac

8 files changed

Lines changed: 462 additions & 11 deletions

__pycache__/server.cpython-313.pyc

1.62 KB
Binary file not shown.

errors_py/unexpected_error_5p3qpye_1746091041162.html

Lines changed: 131 additions & 0 deletions
Large diffs are not rendered by default.
409 KB
Loading

errors_py/unexpected_error_6phzwu7_1746091081951.html

Lines changed: 146 additions & 0 deletions
Large diffs are not rendered by default.
503 KB
Loading

errors_py/unexpected_error_v8u4asa_1746091026618.html

Lines changed: 131 additions & 0 deletions
Large diffs are not rendered by default.
450 KB
Loading

server.py

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
RESPONSE_COMPLETION_TIMEOUT = 300000 # 5 minutes total timeout (in ms)
3434
POLLING_INTERVAL = 300 # ms - Standard polling interval
3535
POLLING_INTERVAL_STREAM = 200 # ms - Stream-specific polling interval
36-
SILENCE_TIMEOUT_MS = 1500 # ms
36+
SILENCE_TIMEOUT_MS = 3000 # ms (Increased from 1500ms)
3737
# v2.12: Timeout for secondary checks *after* spinner disappears
3838
POST_SPINNER_CHECK_DELAY_MS = 500 # Spinner消失后稍作等待再检查其他状态
3939
FINAL_STATE_CHECK_TIMEOUT_MS = 1500 # 检查按钮和输入框最终状态的超时
@@ -250,24 +250,68 @@ def validate_chat_request(messages: List[Message], req_id: str) -> Dict[str, Opt
250250
}
251251

252252
async def get_raw_text_content(response_element, previous_text: str, req_id: str) -> str:
253-
# (Ported/Adapted from server.cjs getRawTextContent - using async Playwright)
254-
# Attempts to get text from <pre> first, then falls back to the main element
253+
"""获取AI响应的原始文本内容,优先使用 <pre> 标签,并清理已知UI文本。"""
254+
raw_text = previous_text # 默认返回上一次的文本以防万一
255255
try:
256256
await response_element.wait_for(state='attached', timeout=1500)
257257
pre_element = response_element.locator('pre').last
258-
raw_text = previous_text # Default to previous if all attempts fail
258+
259+
pre_found_and_visible = False
259260
try:
260-
await pre_element.wait_for(state='attached', timeout=500)
261-
raw_text = await pre_element.inner_text(timeout=1000)
261+
# 检查 pre 元素是否存在且可见
262+
await pre_element.wait_for(state='visible', timeout=500)
263+
pre_found_and_visible = True
262264
except PlaywrightAsyncError:
263-
# If <pre> fails, try the parent response element's inner_text
264-
# print(f"[{req_id}] (Info) Failed to get text from <pre>, falling back to parent.")
265+
# print(f"[{req_id}] (Info) Optional <pre> element not found or not visible quickly.")
266+
pass # pre 元素不存在或不可见是正常情况
267+
268+
if pre_found_and_visible:
269+
# 如果 pre 元素存在且可见,优先使用它的 innerText
270+
try:
271+
raw_text = await pre_element.inner_text(timeout=1000)
272+
# print(f"[{req_id}] (Debug) Got text from <pre>: {raw_text[:50]}...")
273+
except PlaywrightAsyncError as pre_err:
274+
print(f"[{req_id}] (Warn) Failed to get innerText from visible <pre>: {pre_err.message.split('\n')[0]}")
275+
# 如果从可见的 pre 获取文本失败,尝试回退到父元素
276+
try:
277+
raw_text = await response_element.inner_text(timeout=2000)
278+
except PlaywrightAsyncError as e_parent:
279+
print(f"[{req_id}] (Warn) getRawTextContent (inner_text) failed on parent after <pre> fail: {e_parent}. Returning previous.")
280+
raw_text = previous_text
281+
else:
282+
# 如果 pre 元素未找到或不可见,直接获取父元素的 innerText
265283
try:
266284
raw_text = await response_element.inner_text(timeout=2000)
285+
# print(f"[{req_id}] (Debug) Got text from parent element: {raw_text[:50]}...")
267286
except PlaywrightAsyncError as e_parent:
268-
print(f"[{req_id}] (Warn) getRawTextContent (inner_text) failed on both <pre> and parent: {e_parent}. Returning previous.")
269-
raw_text = previous_text # Return previous if parent also fails
287+
print(f"[{req_id}] (Warn) getRawTextContent (inner_text) failed on parent (no pre): {e_parent}. Returning previous.")
288+
raw_text = previous_text
289+
290+
# --- 新增:清理已知的 UI 文本 ---
291+
if raw_text and isinstance(raw_text, str): # 确保是字符串
292+
replacements = {
293+
"IGNORE_WHEN_COPYING_START": "",
294+
"content_copy": "",
295+
"download": "",
296+
"Use code with caution.": "",
297+
"IGNORE_WHEN_COPYING_END": ""
298+
}
299+
cleaned_text = raw_text
300+
found_junk = False
301+
for junk, replacement in replacements.items():
302+
if junk in cleaned_text:
303+
cleaned_text = cleaned_text.replace(junk, replacement)
304+
found_junk = True
305+
306+
if found_junk:
307+
# 移除可能因替换产生的多余换行符和空格
308+
cleaned_text = "\n".join([line.strip() for line in cleaned_text.splitlines() if line.strip()])
309+
print(f"[{req_id}] (清理) 已移除响应文本中的已知UI元素。") # 中文
310+
raw_text = cleaned_text
311+
# --- 清理结束 ---
312+
270313
return raw_text
314+
271315
except PlaywrightAsyncError as e_attach:
272316
print(f"[{req_id}] (Warn) getRawTextContent failed waiting for response element attach: {e_attach}. Returning previous.")
273317
return previous_text
@@ -798,7 +842,6 @@ async def check_disconnect():
798842
print(f"[{req_id}] 尝试使用 Control+Enter 快捷键提交...") # 中文
799843
await page.keyboard.press('Control+Enter')
800844
# Heuristic check: See if input field clears quickly after sending
801-
await expect_async(input_field).to_have_value('', timeout=2000)
802845
print(f"[{req_id}] 快捷键提交成功 (输入框已清空)。") # 中文
803846
submitted_successfully = True
804847
except PlaywrightAsyncError as key_press_error:

0 commit comments

Comments
 (0)