XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

perf(regex): pre-compile content reference patterns in OpenaiChat streaming hot path

1bfa43da
Anand Mall <anand@example.com>
提交于

代码差异

1 个文件 +70 -111
Modified g4f/Provider/needs_auth/OpenaiChat.py +70 -111
@@ -76,6 +76,26 @@ from ..openai.proofofwork import generate_proof_token
76 76 from ..openai.new import get_requirements_token, get_config
77 77 from ... import debug
78 78
79 _RE_FILE_SERVICE = re.compile(r"file-service://[\w-]+")
80 _RE_VIDEO = re.compile(r"video\n(.*?)\nturn[0-9]+")
81 _RE_CITATION = re.compile(
82 r"(?:cite\nturn[0-9]+|forecast\nturn[0-9]+|video\n.*?\nturn[0-9]+|i?\n?turn[0-9]+)(search|news|view|image|forecast)(\d+)"
83 )
84 _RE_PRODUCTS = re.compile(r"products\n(.*)")
85 _RE_PRODUCT_ENTITY = re.compile(r'product_entity\n\[".*","(.*)"\]')
86 _RE_SEQUENCE = re.compile(r"\ue200(.*?)\ue201", flags=re.DOTALL)
87
88 _RE_CONTENT_REF = re.compile(r"^/message/metadata/content_references/(\d+)$")
89 _RE_FALLBACK_ITEMS = re.compile(r"^/message/metadata/content_references/\d+/fallback_items$")
90 _RE_ITEMS = re.compile(r"^/message/metadata/content_references/\d+/items$")
91 _RE_REFS = re.compile(r"^/message/metadata/content_references/(\d+)/refs$")
92 _RE_ALT = re.compile(r"^/message/metadata/content_references/(\d+)/alt$")
93 _RE_PROMPT_TEXT = re.compile(r"^/message/metadata/content_references/(\d+)/prompt_text$")
94 _RE_REFS_IDX = re.compile(r"^/message/metadata/content_references/(\d+)/refs/(\d+)$")
95 _RE_IMAGES = re.compile(r"^/message/metadata/content_references/(\d+)/images$")
96 _RE_ACCESS_TOKEN = re.compile(r'"accessToken":"(.+?)"')
97 _RE_UTM_SOURCE = re.compile(r"[&?]utm_source=.+")
98
79 99 DEFAULT_HEADERS = {
80 100 "accept": "*/*",
81 101 "accept-encoding": "gzip, deflate, br, zstd",
@@ -719,8 +739,7 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
719 739 buffer = ""
720 740 matches = []
721 741 async for line in response.iter_lines():
722 pattern = re.compile(r"file-service://[\w-]+")
723 for match in pattern.finditer(line.decode(errors="ignore")):
742 for match in _RE_FILE_SERVICE.finditer(line.decode(errors="ignore")):
724 743 if match.group(0) in matches:
725 744 continue
726 745 matches.append(match.group(0))
@@ -793,13 +812,12 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
793 812 "thumbnail_url", ""
794 813 ):
795 814 return f"[![{reference.get('title', '')}]({reference['thumbnail_url']})]({reference['url']})"
796 video_match = re.match(
797 r"video\n(.*?)\nturn[0-9]+",
798 match.group(0),
815 video_match = _RE_VIDEO.match(
816 match.group(0)
799 817 )
800 818 if video_match:
801 819 return video_match.group(1)
802 return ""
820 return ""
803 821
804 822 source_index = sources.get_index(
805 823 {
@@ -860,29 +878,24 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
860 878 is_video_embedding = (
861 879 sequence_content.startswith("video\n")
862 880 )
863 sequence_content = re.sub(
864 r"(?:cite\nturn[0-9]+|forecast\nturn[0-9]+|video\n.*?\nturn[0-9]+|i?\n?turn[0-9]+)(search|news|view|image|forecast)(\d+)",
881 sequence_content = _RE_CITATION.sub(
865 882 citation_replacer,
866 883 sequence_content,
867 884 )
868 sequence_content = re.sub(
869 r"products\n(.*)",
885 sequence_content = _RE_PRODUCTS.sub(
870 886 products_replacer,
871 887 sequence_content,
872 888 )
873 sequence_content = re.sub(
874 r'product_entity\n\[".*","(.*)"\]',
889 sequence_content = _RE_PRODUCT_ENTITY.sub(
875 890 lambda x: x.group(1),
876 891 sequence_content,
877 892 )
878 893 return sequence_content
879 894
880 895 # process only completed sequences and do not touch start of next not completed sequence
881 buffer = re.sub(
882 r"\ue200(.*?)\ue201",
896 buffer = _RE_SEQUENCE.sub(
883 897 sequence_replacer,
884 898 buffer,
885 flags=re.DOTALL,
886 899 )
887 900
888 901 if (
@@ -1179,130 +1192,76 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
1179 1192 sources.add_source(link)
1180 1193 if m.get("o", None) == "append":
1181 1194 references.add_reference(entry)
1182 elif m.get("p") and re.match(
1183 r"^/message/metadata/content_references/\d+$", m.get("p")
1184 ):
1185 if "url" in m.get("v") or "link" in m.get("v"):
1186 sources.add_source(m.get("v"))
1187 for link in m.get("v").get("fallback_items", []) or []:
1188 sources.add_source(link)
1189
1190 match = re.match(
1191 r"^/message/metadata/content_references/(\d+)$", m.get("p")
1192 )
1193 if (
1194 match
1195 and m.get("o") == "append"
1196 and isinstance(m.get("v"), dict)
1197 ):
1198 idx = int(match.group(1))
1199 references.merge_reference(idx, m.get("v"))
1195 elif (m_p := m.get("p")) and (ref_match := _RE_CONTENT_REF.match(m_p)):
1196 v = m.get("v")
1197 if isinstance(v, dict):
1198 if "url" in v or "link" in v:
1199 sources.add_source(v)
1200 for link in v.get("fallback_items", []) or []:
1201 sources.add_source(link)
1202 if m.get("o") == "append":
1203 idx = int(ref_match.group(1))
1204 references.merge_reference(idx, v)
1200 1205 elif (
1201 m.get("p")
1202 and re.match(
1203 r"^/message/metadata/content_references/\d+/fallback_items$",
1204 m.get("p"),
1205 )
1206 (m_p := m.get("p"))
1207 and _RE_FALLBACK_ITEMS.match(m_p)
1206 1208 and isinstance(m.get("v"), list)
1207 1209 ):
1208 1210 for link in m.get("v", []) or []:
1209 1211 sources.add_source(link)
1210 1212 elif (
1211 m.get("p")
1212 and re.match(
1213 r"^/message/metadata/content_references/\d+/items$",
1214 m.get("p"),
1215 )
1213 (m_p := m.get("p"))
1214 and _RE_ITEMS.match(m_p)
1216 1215 and isinstance(m.get("v"), list)
1217 1216 ):
1218 1217 for link in m.get("v", []) or []:
1219 1218 sources.add_source(link)
1220 1219 elif (
1221 m.get("p")
1222 and re.match(
1223 r"^/message/metadata/content_references/\d+/refs$",
1224 m.get("p"),
1225 )
1220 (m_p := m.get("p"))
1221 and (ref_match := _RE_REFS.match(m_p))
1226 1222 and isinstance(m.get("v"), list)
1227 1223 ):
1228 match = re.match(
1229 r"^/message/metadata/content_references/(\d+)/refs$",
1230 m.get("p"),
1224 idx = int(ref_match.group(1))
1225 references.update_reference(
1226 idx, m.get("o"), "refs", m.get("v")
1231 1227 )
1232 if match:
1233 idx = int(match.group(1))
1234 references.update_reference(
1235 idx, m.get("o"), "refs", m.get("v")
1236 )
1237 1228 elif (
1238 m.get("p")
1239 and re.match(
1240 r"^/message/metadata/content_references/\d+/alt$",
1241 m.get("p"),
1242 )
1229 (m_p := m.get("p"))
1230 and (ref_match := _RE_ALT.match(m_p))
1243 1231 and isinstance(m.get("v"), list)
1244 1232 ):
1245 match = re.match(
1246 r"^/message/metadata/content_references/(\d+)/alt$",
1247 m.get("p"),
1233 idx = int(ref_match.group(1))
1234 references.update_reference(
1235 idx, m.get("o"), "alt", m.get("v")
1248 1236 )
1249 if match:
1250 idx = int(match.group(1))
1251 references.update_reference(
1252 idx, m.get("o"), "alt", m.get("v")
1253 )
1254 1237 elif (
1255 m.get("p")
1256 and re.match(
1257 r"^/message/metadata/content_references/\d+/prompt_text$",
1258 m.get("p"),
1259 )
1238 (m_p := m.get("p"))
1239 and (ref_match := _RE_PROMPT_TEXT.match(m_p))
1260 1240 and isinstance(m.get("v"), list)
1261 1241 ):
1262 match = re.match(
1263 r"^/message/metadata/content_references/(\d+)/prompt_text$",
1264 m.get("p"),
1242 idx = int(ref_match.group(1))
1243 references.update_reference(
1244 idx, m.get("o"), "prompt_text", m.get("v")
1265 1245 )
1266 if match:
1267 idx = int(match.group(1))
1268 references.update_reference(
1269 idx, m.get("o"), "prompt_text", m.get("v")
1270 )
1271 1246 elif (
1272 m.get("p")
1273 and re.match(
1274 r"^/message/metadata/content_references/\d+/refs/\d+$",
1275 m.get("p"),
1276 )
1247 (m_p := m.get("p"))
1248 and (ref_match := _RE_REFS_IDX.match(m_p))
1277 1249 and isinstance(m.get("v"), dict)
1278 1250 ):
1279 match = re.match(
1280 r"^/message/metadata/content_references/(\d+)/refs/(\d+)$",
1281 m.get("p"),
1251 reference_idx = int(ref_match.group(1))
1252 ref_idx = int(ref_match.group(2))
1253 references.update_reference(
1254 reference_idx, m.get("o"), "refs", m.get("v"), ref_idx
1282 1255 )
1283 if match:
1284 reference_idx = int(match.group(1))
1285 ref_idx = int(match.group(2))
1286 references.update_reference(
1287 reference_idx, m.get("o"), "refs", m.get("v"), ref_idx
1288 )
1289 1256 elif (
1290 m.get("p")
1291 and re.match(
1292 r"^/message/metadata/content_references/\d+/images$",
1293 m.get("p"),
1294 )
1257 (m_p := m.get("p"))
1258 and (ref_match := _RE_IMAGES.match(m_p))
1295 1259 and isinstance(m.get("v"), list)
1296 1260 ):
1297 match = re.match(
1298 r"^/message/metadata/content_references/(\d+)/images$",
1299 m.get("p"),
1261 idx = int(ref_match.group(1))
1262 references.update_reference(
1263 idx, m.get("o"), "images", m.get("v")
1300 1264 )
1301 if match:
1302 idx = int(match.group(1))
1303 references.update_reference(
1304 idx, m.get("o"), "images", m.get("v")
1305 )
1306 1265 elif m.get("p") == "/message/metadata/finished_text":
1307 1266 fields.is_thinking = False
1308 1267 if buffer:
@@ -1487,7 +1446,7 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
1487 1446 if hasattr(body, "value"):
1488 1447 body = body.value
1489 1448 if body:
1490 match = re.search(r'"accessToken":"(.+?)"', body)
1449 match = _RE_ACCESS_TOKEN.search(body)
1491 1450 if match:
1492 1451 cls._api_key = match.group(1)
1493 1452 break
@@ -1631,7 +1590,7 @@ class OpenAISources(ResponseType):
1631 1590 if not url:
1632 1591 return
1633 1592
1634 url = re.sub(r"[&?]utm_source=.+", "", url)
1593 url = _RE_UTM_SOURCE.sub("", url)
1635 1594 source["url"] = url
1636 1595
1637 1596 ref_info = self.get_ref_info(source)