44
55import uuid
66import orjson
7- from typing import Dict , List , Any , Optional
7+ from typing import Dict , List , Any
88from dataclasses import dataclass
99
1010from curl_cffi .requests import AsyncSession
1818 ErrorType
1919)
2020from app .services .grok .statsig import StatsigService
21- from app .services .grok .model import ModelService , Cost
21+ from app .services .grok .model import ModelService
2222from app .services .grok .assets import UploadService
2323from app .services .grok .processor import StreamProcessor , CollectProcessor
2424from app .services .grok .retry import retry_on_status
25- from app .services .token import get_token_manager , EffortType
25+ from app .services .token import get_token_manager
2626
2727
2828CHAT_API = "https://grok.com/rest/app-chat/conversations/new"
@@ -64,34 +64,38 @@ def extract(messages: List[Dict[str, Any]], is_video: bool = False) -> tuple[str
6464 """
6565 texts = []
6666 attachments = [] # 需要上传的附件 (URL 或 base64)
67-
67+
68+ # 先抽取每条消息的文本,保留角色信息用于合并
69+ extracted : List [Dict [str , str ]] = []
70+
6871 for msg in messages :
72+ role = msg .get ("role" , "" )
6973 content = msg .get ("content" , "" )
70-
74+ parts = []
75+
7176 # 简单字符串内容
7277 if isinstance (content , str ):
7378 if content .strip ():
74- texts .append (content )
75- continue
76-
79+ parts .append (content )
80+
7781 # 列表格式内容
78- if isinstance (content , list ):
82+ elif isinstance (content , list ):
7983 for item in content :
8084 item_type = item .get ("type" , "" )
81-
85+
8286 # 文本类型
8387 if item_type == "text" :
8488 text = item .get ("text" , "" )
8589 if text .strip ():
86- texts .append (text )
87-
90+ parts .append (text )
91+
8892 # 图片类型
8993 elif item_type == "image_url" :
9094 image_data = item .get ("image_url" , {})
9195 url = image_data .get ("url" , "" ) if isinstance (image_data , dict ) else str (image_data )
9296 if url :
9397 attachments .append (("image" , url ))
94-
98+
9599 # 音频类型
96100 elif item_type == "input_audio" :
97101 if is_video :
@@ -100,7 +104,7 @@ def extract(messages: List[Dict[str, Any]], is_video: bool = False) -> tuple[str
100104 data = audio_data .get ("data" , "" ) if isinstance (audio_data , dict ) else str (audio_data )
101105 if data :
102106 attachments .append (("audio" , data ))
103-
107+
104108 # 文件类型
105109 elif item_type == "file" :
106110 if is_video :
@@ -112,7 +116,25 @@ def extract(messages: List[Dict[str, Any]], is_video: bool = False) -> tuple[str
112116 url = file_data
113117 if url :
114118 attachments .append (("file" , url ))
115-
119+
120+ if parts :
121+ extracted .append ({"role" : role , "text" : "\n " .join (parts )})
122+
123+ # 合并文本
124+ last_user_index = None
125+ for i in range (len (extracted ) - 1 , - 1 , - 1 ):
126+ if extracted [i ]["role" ] == "user" :
127+ last_user_index = i
128+ break
129+
130+ for i , item in enumerate (extracted ):
131+ role = item ["role" ] or "user"
132+ text = item ["text" ]
133+ if i == last_user_index :
134+ texts .append (text )
135+ else :
136+ texts .append (f"{ role } : { text } " )
137+
116138 # 换行拼接文本
117139 message = "\n \n " .join (texts )
118140 return message , attachments
0 commit comments