@@ -776,6 +776,7 @@ async def _process_quote_message(
776776 quoted_message_settings : QuotedMessageParserSettings = DEFAULT_QUOTED_MESSAGE_SETTINGS ,
777777 config : MainAgentBuildConfig | None = None ,
778778 main_provider_supports_image : bool = False ,
779+ skip_quote_image_caption : bool = False ,
779780) -> None :
780781 quote = None
781782 for comp in event .message_obj .message :
@@ -805,54 +806,63 @@ async def _process_quote_message(
805806 image_seg = comp
806807 break
807808
808- if image_seg and main_provider_supports_image :
809- logger .debug (
810- "Skipping quote image captioning because the main provider supports image input."
811- )
812- elif image_seg and not img_cap_prov_id :
813- logger .debug (
814- "No dedicated image caption provider configured. "
815- "Skipping quote image captioning."
816- )
817- elif image_seg :
818- try :
819- prov = None
820- path = None
821- compress_path = None
822- prov = plugin_context .get_provider_by_id (img_cap_prov_id )
823- if prov is None :
824- prov = plugin_context .get_using_provider (event .unified_msg_origin )
825-
826- if prov and isinstance (prov , Provider ):
827- path = await image_seg .convert_to_file_path ()
828- compress_path = await _compress_image_for_provider (
829- path ,
830- config .provider_settings if config else None ,
831- )
832- if path and _is_generated_compressed_image_path (path , compress_path ):
833- event .track_temporary_local_file (compress_path )
834- llm_resp = await prov .text_chat (
835- prompt = "Please describe the image content." ,
836- image_urls = [compress_path ],
837- )
838- if llm_resp .completion_text :
839- content_parts .append (
840- f"[Image Caption in quoted message]: { llm_resp .completion_text } "
809+ if image_seg :
810+ if skip_quote_image_caption :
811+ logger .debug (
812+ "Skipping quote image captioning because image captioning already handled this request."
813+ )
814+ elif main_provider_supports_image :
815+ logger .debug (
816+ "Skipping quote image captioning because the main provider supports image input."
817+ )
818+ elif not img_cap_prov_id :
819+ logger .debug (
820+ "No dedicated image caption provider configured. "
821+ "Skipping quote image captioning."
822+ )
823+ else :
824+ try :
825+ prov = None
826+ path = None
827+ compress_path = None
828+ prov = plugin_context .get_provider_by_id (img_cap_prov_id )
829+ if prov is None :
830+ prov = plugin_context .get_using_provider (event .unified_msg_origin )
831+
832+ if prov and isinstance (prov , Provider ):
833+ path = await image_seg .convert_to_file_path ()
834+ compress_path = await _compress_image_for_provider (
835+ path ,
836+ config .provider_settings if config else None ,
841837 )
842- else :
843- logger .warning ("No provider found for image captioning in quote." )
844- except BaseException as exc :
845- logger .error ("处理引用图片失败: %s" , exc )
846- finally :
847- if (
848- compress_path
849- and compress_path != path
850- and os .path .exists (compress_path )
851- ):
852- try :
853- os .remove (compress_path )
854- except Exception as exc : # noqa: BLE001
855- logger .warning ("Fail to remove temporary compressed image: %s" , exc )
838+ if path and _is_generated_compressed_image_path (
839+ path , compress_path
840+ ):
841+ event .track_temporary_local_file (compress_path )
842+ llm_resp = await prov .text_chat (
843+ prompt = "Please describe the image content." ,
844+ image_urls = [compress_path ],
845+ )
846+ if llm_resp .completion_text :
847+ content_parts .append (
848+ f"[Image Caption in quoted message]: { llm_resp .completion_text } "
849+ )
850+ else :
851+ logger .warning ("No provider found for image captioning in quote." )
852+ except BaseException as exc :
853+ logger .error ("处理引用图片失败: %s" , exc )
854+ finally :
855+ if (
856+ compress_path
857+ and compress_path != path
858+ and os .path .exists (compress_path )
859+ ):
860+ try :
861+ os .remove (compress_path )
862+ except Exception as exc : # noqa: BLE001
863+ logger .warning (
864+ "Fail to remove temporary compressed image: %s" , exc
865+ )
856866
857867 quoted_content = "\n " .join (content_parts )
858868 quoted_text = f"<Quoted Message>\n { quoted_content } \n </Quoted Message>"
@@ -918,11 +928,12 @@ async def _decorate_llm_request(
918928 main_provider_supports_image = provider is not None and _provider_supports_modality (
919929 provider , "image"
920930 )
931+ img_cap_prov_id : str = cfg .get ("default_image_caption_provider_id" ) or ""
932+ quote_images_already_captioned = False
921933
922934 if req .conversation :
923935 await _ensure_persona_and_skills (req , cfg , plugin_context , event )
924936
925- img_cap_prov_id : str = cfg .get ("default_image_caption_provider_id" ) or ""
926937 if img_cap_prov_id and req .image_urls and not main_provider_supports_image :
927938 await _ensure_img_caption (
928939 event ,
@@ -931,8 +942,11 @@ async def _decorate_llm_request(
931942 plugin_context ,
932943 img_cap_prov_id ,
933944 )
945+ quote_images_already_captioned = any (
946+ "<image_caption>" in getattr (part , "text" , "" )
947+ for part in req .extra_user_content_parts
948+ )
934949
935- img_cap_prov_id = cfg .get ("default_image_caption_provider_id" ) or ""
936950 quoted_message_settings = _get_quoted_message_parser_settings (cfg )
937951 await _process_quote_message (
938952 event ,
@@ -942,6 +956,7 @@ async def _decorate_llm_request(
942956 quoted_message_settings ,
943957 config ,
944958 main_provider_supports_image = main_provider_supports_image ,
959+ skip_quote_image_caption = quote_images_already_captioned ,
945960 )
946961
947962 tz = config .timezone
0 commit comments