Skip to content

Commit 4aff65b

Browse files
MAX-TABMAX-TAB
authored andcommitted
使用新增的临时聊天模式
1 parent 56ee2eb commit 4aff65b

6 files changed

Lines changed: 131 additions & 15 deletions

File tree

api_utils/app.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
_initialize_page_logic,
3131
_close_page_logic,
3232
load_excluded_models,
33-
_handle_initial_model_state_and_storage
33+
_handle_initial_model_state_and_storage,
34+
enable_temporary_chat_mode
3435
)
3536

3637
import stream
@@ -141,6 +142,7 @@ async def _initialize_browser_and_page():
141142
server.page_instance, server.is_page_ready = await _initialize_page_logic(server.browser_instance)
142143
if server.is_page_ready:
143144
await _handle_initial_model_state_and_storage(server.page_instance)
145+
await enable_temporary_chat_mode(server.page_instance)
144146
server.logger.info("Page initialized successfully.")
145147
else:
146148
server.logger.error("Page initialization failed.")

browser_utils/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# --- browser_utils/__init__.py ---
22
# 浏览器操作工具模块
3-
from .initialization import _initialize_page_logic, _close_page_logic, signal_camoufox_shutdown
3+
from .initialization import _initialize_page_logic, _close_page_logic, signal_camoufox_shutdown, enable_temporary_chat_mode
44
from .operations import (
55
_handle_model_list_response,
66
detect_and_extract_page_error,
@@ -28,6 +28,7 @@
2828
'_initialize_page_logic',
2929
'_close_page_logic',
3030
'signal_camoufox_shutdown',
31+
'enable_temporary_chat_mode',
3132

3233
# 页面操作相关
3334
'_handle_model_list_response',

browser_utils/initialization.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,4 +596,34 @@ async def _handle_auth_file_save_auto(temp_context):
596596
logger.info(f" 自动保存认证状态成功: {auth_save_path}")
597597
except Exception as save_state_err:
598598
logger.error(f" ❌ 自动保存认证状态失败: {save_state_err}", exc_info=True)
599-
print(f" ❌ 自动保存认证状态失败: {save_state_err}", flush=True)
599+
print(f" ❌ 自动保存认证状态失败: {save_state_err}", flush=True)
600+
601+
async def enable_temporary_chat_mode(page: AsyncPage):
602+
"""
603+
检查并启用 AI Studio 界面的“临时聊天”模式。
604+
这是一个独立的UI操作,应该在页面完全稳定后调用。
605+
"""
606+
try:
607+
logger.info("-> (UI Op) 正在检查并启用 '临时聊天' 模式...")
608+
609+
incognito_button_locator = page.locator('button[aria-label="Temporary chat toggle"]')
610+
611+
await incognito_button_locator.wait_for(state="visible", timeout=10000)
612+
613+
button_classes = await incognito_button_locator.get_attribute("class")
614+
615+
if button_classes and 'ms-button-active' in button_classes:
616+
logger.info("-> (UI Op) '临时聊天' 模式已激活。")
617+
else:
618+
logger.info("-> (UI Op) '临时聊天' 模式未激活,正在点击...")
619+
await incognito_button_locator.click(timeout=5000, force=True)
620+
await asyncio.sleep(1)
621+
622+
updated_classes = await incognito_button_locator.get_attribute("class")
623+
if updated_classes and 'ms-button-active' in updated_classes:
624+
logger.info("✅ (UI Op) '临时聊天' 模式已成功启用。")
625+
else:
626+
logger.warning("⚠️ (UI Op) 点击后 '临时聊天' 模式状态验证失败。")
627+
628+
except Exception as e:
629+
logger.warning(f"⚠️ (UI Op) 启用 '临时聊天' 模式时出错: {e}")

browser_utils/model_management.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,29 @@ async def switch_ai_studio_model(page: AsyncPage, model_id: str, req_id: str) ->
294294
logger.warning(f"[{req_id}] 读取页面显示的当前模型ID时出错: {e_disp}。将无法验证页面显示。")
295295

296296
if page_display_match:
297+
try:
298+
logger.info(f"[{req_id}] 模型切换成功,重新启用 '临时聊天' 模式...")
299+
incognito_button_locator = page.locator('button[aria-label="Temporary chat toggle"]')
300+
301+
await incognito_button_locator.wait_for(state="visible", timeout=5000)
302+
303+
button_classes = await incognito_button_locator.get_attribute("class")
304+
305+
if button_classes and 'ms-button-active' in button_classes:
306+
logger.info(f"[{req_id}] '临时聊天' 模式已处于激活状态。")
307+
else:
308+
logger.info(f"[{req_id}] '临时聊天' 模式未激活,正在点击以开启...")
309+
await incognito_button_locator.click(timeout=3000)
310+
await asyncio.sleep(0.5)
311+
312+
updated_classes = await incognito_button_locator.get_attribute("class")
313+
if updated_classes and 'ms-button-active' in updated_classes:
314+
logger.info(f"[{req_id}] ✅ '临时聊天' 模式已成功重新启用。")
315+
else:
316+
logger.warning(f"[{req_id}] ⚠️ 点击后 '临时聊天' 模式状态验证失败,可能未成功重新开启。")
317+
318+
except Exception as e:
319+
logger.warning(f"[{req_id}] ⚠️ 模型切换后重新启用 '临时聊天' 模式失败: {e}")
297320
return True
298321
else:
299322
logger.error(f"[{req_id}] ❌ 模型切换失败,因为页面显示的模型与期望不符 (即使localStorage可能已更改)。")

browser_utils/page_controller.py

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
)
2424
from models import ClientDisconnectedError
2525
from .operations import save_error_snapshot, _wait_for_response_completion, _get_final_response_content
26+
from .initialization import enable_temporary_chat_mode
2627

2728
class PageController:
2829
"""封装了与AI Studio页面交互的所有操作。"""
@@ -572,6 +573,8 @@ async def clear_chat_history(self, check_client_disconnected: Callable):
572573
if can_attempt_clear:
573574
await self._execute_chat_clear(clear_chat_button_locator, confirm_button_locator, overlay_locator, check_client_disconnected)
574575
await self._verify_chat_cleared(check_client_disconnected)
576+
self.logger.info(f"[{self.req_id}] 聊天已清空,重新启用 '临时聊天' 模式...")
577+
await enable_temporary_chat_mode(self.page)
575578

576579
except Exception as e_clear:
577580
self.logger.error(f"[{self.req_id}] 清空聊天过程中发生错误: {e_clear}")
@@ -580,21 +583,78 @@ async def clear_chat_history(self, check_client_disconnected: Callable):
580583
raise
581584

582585
async def _execute_chat_clear(self, clear_chat_button_locator, confirm_button_locator, overlay_locator, check_client_disconnected: Callable):
583-
"""执行清空聊天操作 (适配新版UI,无确认对话框)"""
584-
self.logger.info(f"[{self.req_id}] 点击\"清空聊天\"按钮: {CLEAR_CHAT_BUTTON_SELECTOR}")
585-
586+
"""执行清空聊天操作"""
587+
overlay_initially_visible = False
586588
try:
589+
if await overlay_locator.is_visible(timeout=1000):
590+
overlay_initially_visible = True
591+
self.logger.info(f"[{self.req_id}] 清空聊天确认遮罩层已可见。直接点击\"继续\"。")
592+
except TimeoutError:
593+
self.logger.info(f"[{self.req_id}] 清空聊天确认遮罩层初始不可见 (检查超时或未找到)。")
594+
overlay_initially_visible = False
595+
except Exception as e_vis_check:
596+
self.logger.warning(f"[{self.req_id}] 检查遮罩层可见性时发生错误: {e_vis_check}。假定不可见。")
597+
overlay_initially_visible = False
598+
599+
await self._check_disconnect(check_client_disconnected, "清空聊天 - 初始遮罩层检查后")
600+
601+
if overlay_initially_visible:
602+
self.logger.info(f"[{self.req_id}] 点击\"继续\"按钮 (遮罩层已存在): {CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR}")
603+
await confirm_button_locator.click(timeout=CLICK_TIMEOUT_MS)
604+
else:
605+
self.logger.info(f"[{self.req_id}] 点击\"清空聊天\"按钮: {CLEAR_CHAT_BUTTON_SELECTOR}")
587606
await clear_chat_button_locator.click(timeout=CLICK_TIMEOUT_MS)
588607
await self._check_disconnect(check_client_disconnected, "清空聊天 - 点击\"清空聊天\"后")
589-
590-
await asyncio.sleep(0.5)
591-
592-
self.logger.info(f"[{self.req_id}] ✅ '清空聊天'按钮已点击。新版UI无确认步骤,操作完成。")
593608

594-
except Exception as e:
595-
self.logger.error(f"[{self.req_id}] 点击'清空聊天'按钮时发生错误: {e}")
596-
raise
597-
609+
try:
610+
self.logger.info(f"[{self.req_id}] 等待清空聊天确认遮罩层出现: {OVERLAY_SELECTOR}")
611+
await expect_async(overlay_locator).to_be_visible(timeout=WAIT_FOR_ELEMENT_TIMEOUT_MS)
612+
self.logger.info(f"[{self.req_id}] 清空聊天确认遮罩层已出现。")
613+
except TimeoutError:
614+
error_msg = f"等待清空聊天确认遮罩层超时 (点击清空按钮后)。请求 ID: {self.req_id}"
615+
self.logger.error(error_msg)
616+
await save_error_snapshot(f"clear_chat_overlay_timeout_{self.req_id}")
617+
raise Exception(error_msg)
618+
619+
await self._check_disconnect(check_client_disconnected, "清空聊天 - 遮罩层出现后")
620+
self.logger.info(f"[{self.req_id}] 点击\"继续\"按钮 (在对话框中): {CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR}")
621+
await confirm_button_locator.click(timeout=CLICK_TIMEOUT_MS)
622+
623+
await self._check_disconnect(check_client_disconnected, "清空聊天 - 点击\"继续\"后")
624+
625+
# 等待对话框消失
626+
max_retries_disappear = 3
627+
for attempt_disappear in range(max_retries_disappear):
628+
try:
629+
self.logger.info(f"[{self.req_id}] 等待清空聊天确认按钮/对话框消失 (尝试 {attempt_disappear + 1}/{max_retries_disappear})...")
630+
await expect_async(confirm_button_locator).to_be_hidden(timeout=CLEAR_CHAT_VERIFY_TIMEOUT_MS)
631+
await expect_async(overlay_locator).to_be_hidden(timeout=1000)
632+
self.logger.info(f"[{self.req_id}] ✅ 清空聊天确认对话框已成功消失。")
633+
break
634+
except TimeoutError:
635+
self.logger.warning(f"[{self.req_id}] ⚠️ 等待清空聊天确认对话框消失超时 (尝试 {attempt_disappear + 1}/{max_retries_disappear})。")
636+
if attempt_disappear < max_retries_disappear - 1:
637+
await asyncio.sleep(1.0)
638+
await self._check_disconnect(check_client_disconnected, f"清空聊天 - 重试消失检查 {attempt_disappear + 1} 前")
639+
continue
640+
else:
641+
error_msg = f"达到最大重试次数。清空聊天确认对话框未消失。请求 ID: {self.req_id}"
642+
self.logger.error(error_msg)
643+
await save_error_snapshot(f"clear_chat_dialog_disappear_timeout_{self.req_id}")
644+
raise Exception(error_msg)
645+
except ClientDisconnectedError:
646+
self.logger.info(f"[{self.req_id}] 客户端在等待清空确认对话框消失时断开连接。")
647+
raise
648+
except Exception as other_err:
649+
self.logger.warning(f"[{self.req_id}] 等待清空确认对话框消失时发生其他错误: {other_err}")
650+
if attempt_disappear < max_retries_disappear - 1:
651+
await asyncio.sleep(1.0)
652+
continue
653+
else:
654+
raise
655+
656+
await self._check_disconnect(check_client_disconnected, f"清空聊天 - 消失检查尝试 {attempt_disappear + 1} 后")
657+
598658
async def _verify_chat_cleared(self, check_client_disconnected: Callable):
599659
"""验证聊天已清空"""
600660
last_response_container = self.page.locator(RESPONSE_CONTAINER_SELECTOR).last

config/selectors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# --- 按钮选择器 ---
1212
SUBMIT_BUTTON_SELECTOR = 'button[aria-label="Run"].run-button'
1313
CLEAR_CHAT_BUTTON_SELECTOR = 'button[data-test-clear="outside"][aria-label="New chat"]'
14-
CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR = 'button.ms-button-primary:has-text("Continue")'
14+
CLEAR_CHAT_CONFIRM_BUTTON_SELECTOR = 'button.ms-button-primary:has-text("Discard and continue")'
1515
UPLOAD_BUTTON_SELECTOR = 'button[aria-label^="Insert assets"]'
1616

1717
# --- 响应相关选择器 ---

0 commit comments

Comments
 (0)