2024-01-26 15:51:49 +08:00
from __future__ import annotations
import os
import traceback
from . import strategy
2025-03-29 17:50:45 +08:00
from . . import stage , entities
2025-06-16 13:18:59 +08:00
import langbot_plugin . api . entities . builtin . platform . message as platform_message
2025-04-29 17:24:07 +08:00
from . . . utils import importutil
2025-06-15 22:04:31 +08:00
import langbot_plugin . api . entities . builtin . pipeline . query as pipeline_query
2025-04-29 17:24:07 +08:00
from . import strategies
2024-01-26 15:51:49 +08:00
2025-04-29 17:24:07 +08:00
importutil . import_modules_in_pkg ( strategies )
@stage.stage_class ( ' LongTextProcessStage ' )
2024-01-26 15:51:49 +08:00
class LongTextProcessStage ( stage . PipelineStage ) :
2025-07-10 11:09:33 +08:00
""" Long message processing stage
2024-05-14 22:20:31 +08:00
2025-07-10 11:09:33 +08:00
Rewrite :
2024-05-14 22:20:31 +08:00
- resp_message_chain
2024-03-03 16:34:59 +08:00
"""
2024-01-26 15:51:49 +08:00
2025-09-17 17:09:12 +08:00
strategy_impl : strategy . LongTextStrategy | None
2024-01-26 15:51:49 +08:00
2025-03-29 17:50:45 +08:00
async def initialize ( self , pipeline_config : dict ) :
config = pipeline_config [ ' output ' ] [ ' long-text-processing ' ]
2025-09-17 17:09:12 +08:00
if config [ ' strategy ' ] == ' none ' :
self . strategy_impl = None
return
2024-02-06 21:26:03 +08:00
if config [ ' strategy ' ] == ' image ' :
use_font = config [ ' font-path ' ]
2024-01-26 15:51:49 +08:00
try :
# 检查是否存在
if not os . path . exists ( use_font ) :
# 若是windows系统, 使用微软雅黑
2025-04-29 17:24:07 +08:00
if os . name == ' nt ' :
use_font = ' C:/Windows/Fonts/msyh.ttc '
2024-01-26 15:51:49 +08:00
if not os . path . exists ( use_font ) :
2025-04-29 17:24:07 +08:00
self . ap . logger . warn (
2025-07-10 11:09:33 +08:00
' Font file not found, and Windows system font cannot be used, switch to forward message component to send long messages, you can adjust the related settings in the configuration file. '
2025-04-29 17:24:07 +08:00
)
config [ ' blob_message_strategy ' ] = ' forward '
2024-01-26 15:51:49 +08:00
else :
2025-07-10 11:09:33 +08:00
self . ap . logger . info ( ' Using Windows system font: ' + use_font )
2024-02-06 21:26:03 +08:00
config [ ' font-path ' ] = use_font
2024-01-26 15:51:49 +08:00
else :
2025-04-29 17:24:07 +08:00
self . ap . logger . warn (
2025-07-10 11:09:33 +08:00
' Font file not found, and system font cannot be used, switch to forward message component to send long messages, you can adjust the related settings in the configuration file. '
2025-04-29 17:24:07 +08:00
)
2024-02-06 21:26:03 +08:00
2025-05-10 18:04:58 +08:00
pipeline_config [ ' output ' ] [ ' long-text-processing ' ] [ ' strategy ' ] = ' forward '
2025-04-29 17:24:07 +08:00
except Exception :
2024-01-26 15:51:49 +08:00
traceback . print_exc ( )
2025-04-29 17:24:07 +08:00
self . ap . logger . error (
2025-07-10 11:09:33 +08:00
' Failed to load font file ( {} ), switch to forward message component to send long messages, you can adjust the related settings in the configuration file. ' . format (
2025-04-29 17:24:07 +08:00
use_font
)
)
2024-02-06 21:26:03 +08:00
2025-05-10 18:04:58 +08:00
pipeline_config [ ' output ' ] [ ' long-text-processing ' ] [ ' strategy ' ] = ' forward '
2024-03-08 20:31:22 +08:00
for strategy_cls in strategy . preregistered_strategies :
if strategy_cls . name == config [ ' strategy ' ] :
self . strategy_impl = strategy_cls ( self . ap )
break
else :
2025-07-10 11:09:33 +08:00
raise ValueError ( f ' Long message processing strategy not found: { config [ " strategy " ] } ' )
2024-03-08 20:31:22 +08:00
2024-01-26 15:51:49 +08:00
await self . strategy_impl . initialize ( )
2025-04-29 17:24:07 +08:00
2025-06-15 22:04:31 +08:00
async def process ( self , query : pipeline_query . Query , stage_inst_name : str ) - > entities . StageProcessResult :
2025-09-17 17:09:12 +08:00
if self . strategy_impl is None :
self . ap . logger . debug ( ' Long message processing strategy is not set, skip long message processing. ' )
return entities . StageProcessResult ( result_type = entities . ResultType . CONTINUE , new_query = query )
2024-03-31 14:38:15 +08:00
# 检查是否包含非 Plain 组件
contains_non_plain = False
2024-05-14 23:08:49 +08:00
for msg in query . resp_message_chain [ - 1 ] :
2024-09-26 00:23:03 +08:00
if not isinstance ( msg , platform_message . Plain ) :
2024-03-31 14:38:15 +08:00
contains_non_plain = True
break
2025-04-29 17:24:07 +08:00
2024-03-31 14:38:15 +08:00
if contains_non_plain :
2025-07-10 11:09:33 +08:00
self . ap . logger . debug ( ' Message contains non-Plain components, skip long message processing. ' )
2025-04-29 17:24:07 +08:00
elif (
len ( str ( query . resp_message_chain [ - 1 ] ) )
> query . pipeline_config [ ' output ' ] [ ' long-text-processing ' ] [ ' threshold ' ]
) :
query . resp_message_chain [ - 1 ] = platform_message . MessageChain (
2025-05-10 18:04:58 +08:00
await self . strategy_impl . process ( str ( query . resp_message_chain [ - 1 ] ) , query )
2025-04-29 17:24:07 +08:00
)
2024-03-31 14:38:15 +08:00
2025-05-10 18:04:58 +08:00
return entities . StageProcessResult ( result_type = entities . ResultType . CONTINUE , new_query = query )