@@ -755,14 +755,11 @@ async def _robust_click_insert_assets(self, check_client_disconnected: Callable)
755755 return False
756756
757757 async def _upload_images_via_file_input (self , images : List [Dict [str , str ]], check_client_disconnected : Callable ) -> bool :
758- self .logger .info (f"[{ self .req_id } ] 尝试逐个上传 { len (images )} 张图片..." )
758+ self .logger .info (f"[{ self .req_id } ] 准备上传 { len (images )} 张图片..." )
759759 temp_files = []
760- uploaded_count = 0
761760
762761 try :
763762 for idx , img in enumerate (images ):
764- await self ._check_disconnect (check_client_disconnected , f'上传图片 { idx + 1 } /{ len (images )} ' )
765-
766763 mime = img ['mime' ]
767764 try :
768765 data = base64 .b64decode (img ['data' ])
@@ -777,32 +774,62 @@ async def _upload_images_via_file_input(self, images: List[Dict[str, str]], chec
777774 tf .write (data )
778775 tf .close ()
779776 temp_files .append (tf .name )
777+
778+ if not temp_files :
779+ return False
780+
781+ await self ._check_disconnect (check_client_disconnected , '上传图片前' )
782+ menu_opened = await self ._robust_click_insert_assets (check_client_disconnected )
783+ if not menu_opened :
784+ self .logger .warning (f"[{ self .req_id } ] 未能打开菜单,尝试直接查找 input..." )
785+
786+ from config import HIDDEN_FILE_INPUT_SELECTOR
787+ file_input = self .page .locator (HIDDEN_FILE_INPUT_SELECTOR )
788+ if await file_input .count () == 0 :
789+ file_input = self .page .locator ('input[type="file"]' ).first
790+
791+ if await file_input .count () == 0 :
792+ self .logger .warning (f"[{ self .req_id } ] 未找到文件输入框" )
793+ asyncio .create_task (self ._cleanup_temp_files (temp_files ))
794+ return False
795+
796+ try :
797+ self .logger .info (f"[{ self .req_id } ] 尝试批量上传 { len (temp_files )} 张图片..." )
798+ await file_input .set_input_files (temp_files )
799+ await asyncio .sleep (0.3 )
800+ await self .page .keyboard .press ('Escape' )
801+ self .logger .info (f"[{ self .req_id } ] ✅ 批量上传成功 ({ len (temp_files )} 张)" )
802+ asyncio .create_task (self ._cleanup_temp_files (temp_files ))
803+ return True
804+ except Exception as batch_err :
805+ self .logger .warning (f"[{ self .req_id } ] 批量上传失败: { batch_err } ,尝试逐个上传..." )
806+
807+ uploaded_count = 0
808+ for idx , tf_path in enumerate (temp_files ):
809+ await self ._check_disconnect (check_client_disconnected , f'上传图片 { idx + 1 } /{ len (temp_files )} ' )
780810
781- menu_opened = await self ._robust_click_insert_assets (check_client_disconnected )
782- if not menu_opened :
783- self .logger .warning (f"[{ self .req_id } ] 未能打开菜单,尝试直接查找 input..." )
784-
785- from config import HIDDEN_FILE_INPUT_SELECTOR
786- file_input = self .page .locator (HIDDEN_FILE_INPUT_SELECTOR )
787- if await file_input .count () == 0 :
788- file_input = self .page .locator ('input[type="file"]' ).first
789-
790- if await file_input .count () == 0 :
791- self .logger .warning (f"[{ self .req_id } ] 未找到文件输入框,跳过图片 { idx + 1 } " )
792- continue
793-
794- self .logger .info (f"[{ self .req_id } ] 上传图片 { idx + 1 } /{ len (images )} ..." )
795- await file_input .set_input_files (tf .name )
796- uploaded_count += 1
811+ if idx > 0 :
812+ menu_opened = await self ._robust_click_insert_assets (check_client_disconnected )
813+ if not menu_opened :
814+ continue
815+ file_input = self .page .locator (HIDDEN_FILE_INPUT_SELECTOR )
816+ if await file_input .count () == 0 :
817+ file_input = self .page .locator ('input[type="file"]' ).first
797818
798- await asyncio .sleep (0.2 )
799- await self .page .keyboard .press ('Escape' )
800- await asyncio .sleep (0.1 )
819+ try :
820+ self .logger .info (f"[{ self .req_id } ] 上传图片 { idx + 1 } /{ len (temp_files )} ..." )
821+ await file_input .set_input_files (tf_path )
822+ uploaded_count += 1
823+ await asyncio .sleep (0.2 )
824+ await self .page .keyboard .press ('Escape' )
825+ await asyncio .sleep (0.1 )
826+ except Exception as single_err :
827+ self .logger .warning (f"[{ self .req_id } ] 单张上传失败 { idx + 1 } : { single_err } " )
801828
802829 asyncio .create_task (self ._cleanup_temp_files (temp_files ))
803830
804831 if uploaded_count > 0 :
805- self .logger .info (f"[{ self .req_id } ] ✅ 成功上传 { uploaded_count } /{ len (images )} 张图片 " )
832+ self .logger .info (f"[{ self .req_id } ] ✅ 逐个上传完成 { uploaded_count } /{ len (temp_files )} 张 " )
806833 return True
807834 return False
808835
@@ -902,7 +929,13 @@ async def submit_prompt(self, prompt: str, image_list: List, check_client_discon
902929 prompt_textarea_locator = self .page .locator (PROMPT_TEXTAREA_SELECTOR )
903930 else :
904931 self .logger .info (f'[{ self .req_id } ] 找到输入框 (匹配: { matched_selector } )' )
905- autosize_wrapper_locator = self .page .locator ('ms-prompt-box .text-wrapper' )
932+ autosize_wrapper_selectors = ['ms-prompt-input-wrapper .text-wrapper' , 'ms-prompt-box .text-wrapper' , '.prompt-input-wrapper-container' ]
933+ autosize_wrapper_locator = None
934+ for ws in autosize_wrapper_selectors :
935+ loc = self .page .locator (ws )
936+ if await loc .count () > 0 :
937+ autosize_wrapper_locator = loc
938+ break
906939 submit_button_locator , submit_matched = await get_first_visible_locator (self .page , SUBMIT_BUTTON_SELECTORS , timeout = 3000 )
907940 if not submit_button_locator :
908941 submit_button_locator = self .page .locator (SUBMIT_BUTTON_SELECTOR )
@@ -933,33 +966,28 @@ async def submit_prompt(self, prompt: str, image_list: List, check_client_discon
933966 self .logger .info (f"[{ self .req_id } ] 回退到虚拟粘贴模式..." )
934967 await self ._paste_images_via_event (processed_images , prompt_textarea_locator )
935968
936- await asyncio .sleep (1 )
969+ await asyncio .sleep (0.5 )
937970
938- try :
939- self .logger .info (f"[{ self .req_id } ] 正在验证图片上传 (不阻塞主流程)..." )
940- await self ._verify_images_uploaded (len (processed_images ), check_client_disconnected )
941- except Exception as verify_err :
942- self .logger .warning (f"[{ self .req_id } ] 图片上传验证未完全通过,但继续提交文字: { verify_err } " )
943-
944971 except Exception as upload_err :
945972 self .logger .error (f"[{ self .req_id } ] 图片上传整体流程异常: { upload_err } 。继续提交文字。" )
946973
947974 self .logger .info (f"[{ self .req_id } ] 正在填充文字内容..." )
948975 await prompt_textarea_locator .evaluate ('(element, text) => { element.value = text; element.dispatchEvent(new Event("input", { bubbles: true })); }' , prompt )
949- await autosize_wrapper_locator .evaluate ('(element, text) => { element.setAttribute("data-value", text); }' , prompt )
976+ if autosize_wrapper_locator :
977+ try :
978+ await autosize_wrapper_locator .evaluate ('(element, text) => { element.setAttribute("data-value", text); }' , prompt )
979+ except Exception :
980+ pass
950981
951982 await self ._check_disconnect (check_client_disconnected , '输入框填充后' )
952- wait_timeout_ms_submit_enabled = 100000
983+ self . logger . info ( f'[ { self . req_id } ] 文字填充完成,等待发送按钮...' )
953984 try :
954- await self ._check_disconnect (check_client_disconnected , '等待发送按钮启用前' )
955- await expect_async (submit_button_locator ).to_be_enabled (timeout = wait_timeout_ms_submit_enabled )
985+ await expect_async (submit_button_locator ).to_be_enabled (timeout = 15000 )
956986 self .logger .info (f'[{ self .req_id } ] 发送按钮已启用。' )
957987 except Exception as e_pw_enabled :
958- self .logger .error (f'[{ self .req_id } ] 等待发送按钮启用超时或错误: { e_pw_enabled } ' )
959- await save_error_snapshot (f'submit_button_enable_timeout_{ self .req_id } ' )
960- raise
988+ self .logger .warning (f'[{ self .req_id } ] 等待发送按钮启用超时: { e_pw_enabled } ,尝试继续提交...' )
961989 await self ._check_disconnect (check_client_disconnected , '发送按钮启用后' )
962- await asyncio .sleep (0.3 )
990+ await asyncio .sleep (0.1 )
963991 submitted_successfully = await self ._try_shortcut_submit (prompt_textarea_locator , check_client_disconnected )
964992 if not submitted_successfully :
965993 self .logger .info (f'[{ self .req_id } ] 快捷键提交失败,尝试点击提交按钮...' )
0 commit comments