MeUtils 2025.3.31.19.40.39__py3-none-any.whl → 2025.4.8.18.11.44__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/METADATA +264 -264
  2. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/RECORD +41 -27
  3. examples/_openaisdk/openai_ark_bots.py +64 -0
  4. examples/_openaisdk/openai_audio_gpt.py +67 -0
  5. examples/_openaisdk/openai_google.py +129 -77
  6. examples/_openaisdk/openai_kindo.py +1 -1
  7. examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +5 -2
  8. meutils/ai_audio/tts/minimax.py +34 -0
  9. meutils/apis/google_apis/__init__.py +11 -0
  10. meutils/apis/google_apis/audios.py +115 -0
  11. meutils/apis/google_apis/common.py +251 -0
  12. meutils/apis/google_apis/files.py +19 -0
  13. meutils/apis/google_apis/gemini_sdk.py +170 -0
  14. meutils/apis/google_apis/google2openai.py +89 -0
  15. meutils/apis/google_apis/images.py +11 -0
  16. meutils/apis/google_apis/search.py +46 -0
  17. meutils/apis/hailuoai/videos.py +1 -1
  18. meutils/apis/images/google/__init__.py +11 -0
  19. meutils/apis/images/google/images.py +32 -0
  20. meutils/apis/jimeng/images.py +2 -1
  21. meutils/apis/search/ark_web_search.py +69 -0
  22. meutils/apis/search/{web_search.py → zhipu_web_search.py} +21 -30
  23. meutils/apis/textin_apis/common.py +1 -1
  24. meutils/apis/tripo3d/images.py +1 -1
  25. meutils/caches/common.py +4 -2
  26. meutils/data/VERSION +1 -1
  27. meutils/io/files_utils.py +27 -22
  28. meutils/llm/clients.py +6 -5
  29. meutils/llm/completions/assistants/ppt.py +17 -13
  30. meutils/llm/completions/chat_gemini.py +1 -1
  31. meutils/llm/completions/qwenllm.py +8 -2
  32. meutils/llm/openai_utils/common.py +5 -0
  33. meutils/oss/minio_oss.py +38 -8
  34. meutils/oss/minio_utils.py +2 -2
  35. meutils/schemas/oneapi/common.py +23 -6
  36. meutils/schemas/openai_types.py +70 -40
  37. meutils/str_utils/regular_expression.py +6 -3
  38. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/LICENSE +0 -0
  39. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/WHEEL +0 -0
  40. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/entry_points.txt +0 -0
  41. {MeUtils-2025.3.31.19.40.39.dist-info → MeUtils-2025.4.8.18.11.44.dist-info}/top_level.txt +0 -0
@@ -633,6 +633,7 @@ MODEL_RATIO = {
633
633
  "anthropic/claude-3.5-sonnet:beta": 4, # 1022
634
634
 
635
635
  "claude-3-7-sonnet-thinking": 1.5,
636
+ "claude-3-7-sonnet-20250219-thinking": 1.5,
636
637
  "claude-3-7-sonnet-latest": 1.5,
637
638
  "claude-3-7-sonnet-20250219": 1.5,
638
639
 
@@ -719,9 +720,12 @@ MODEL_RATIO = {
719
720
  "chatgpt-4o-latest": 2.5,
720
721
  "gpt-4o-realtime-preview": 2.5,
721
722
  "gpt-4o-realtime-preview-2024-10-01": 2.5,
722
- "gpt-4o-audio-preview": 2.5 / 2,
723
+
723
724
  "gpt-4o-mini-audio-preview": 0.15 / 2,
725
+
726
+ "gpt-4o-audio-preview": 2.5 / 2,
724
727
  "gpt-4o-audio-preview-2024-12-17": 2.5 / 2,
728
+ "gemini-2.0-flash-audio": 0.15 / 2,
725
729
 
726
730
  "gpt-4o": 1.25,
727
731
  "gpt-4o-all": 2.5, # 逆向
@@ -735,9 +739,10 @@ MODEL_RATIO = {
735
739
  "o1": 7.5,
736
740
  "o1-2024-12-17": 7.5,
737
741
 
738
- "o1-mini": 1.5,
742
+ "o1-mini": 0.55,
743
+ "o1-mini-2024-09-12": 0.55,
744
+
739
745
  "o1-preview": 7.5,
740
- "o1-mini-2024-09-12": 1.5,
741
746
  "o1-preview-2024-09-12": 7.5,
742
747
  "o3-mini": 0.55,
743
748
 
@@ -752,7 +757,8 @@ MODEL_RATIO = {
752
757
  "meta-llama/Llama-3.3-70B-Instruct": 2,
753
758
  "llama-3.3-70b-instruct": 2,
754
759
 
755
- "hunyuan-a52b-instruct": 2.5, # 10.5
760
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct": 0.1,
761
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": 0.2,
756
762
 
757
763
  # groq https://console.groq.com/docs/models
758
764
  "llama3-8b-8192": 0.01,
@@ -828,6 +834,12 @@ COMPLETION_RATIO = {
828
834
  "gpt-4o-realtime-preview-2024-10-01": 4,
829
835
  "gpt-4o-2024-11-20": 4,
830
836
 
837
+ "gpt-4o-mini-audio-preview": 4,
838
+
839
+ "gpt-4o-audio-preview": 4,
840
+ "gpt-4o-audio-preview-2024-12-17": 4,
841
+ "gemini-2.0-flash-audio": 4,
842
+
831
843
  # claude
832
844
  "claude-3-opus-20240229": 5,
833
845
  "anthropic/claude-3-opus:beta": 5, # openrouter
@@ -845,6 +857,9 @@ COMPLETION_RATIO = {
845
857
  "llama-3.1-405b-instruct": 6,
846
858
  "meta-llama/Meta-Llama-3.1-405B-Instruct": 6,
847
859
 
860
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct": 3,
861
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": 3,
862
+
848
863
  "llama-3.3-70b-instruct": 4,
849
864
 
850
865
  "command": 4,
@@ -1212,5 +1227,7 @@ if __name__ == '__main__':
1212
1227
  from meutils.apis.oneapi import option, channel
1213
1228
 
1214
1229
  option()
1215
- #
1216
- arun(channel.edit_channel(MODEL_PRICE))
1230
+ # #
1231
+ # arun(channel.edit_channel(MODEL_PRICE))
1232
+
1233
+ print(bjson({k: v * 6 for k, v in MODEL_RATIO.items() if k.startswith('claude')}))
@@ -127,30 +127,43 @@ class CompletionRequest(BaseModel):
127
127
 
128
128
  @cached_property
129
129
  def last_user_content(self) -> str:
130
+ """text"""
130
131
  for i, message in enumerate(self.messages[::-1], 1):
131
132
  if message.get("role") == "user":
132
133
  contents = message.get("content")
133
134
  if isinstance(contents, list):
134
135
  for content in contents:
135
- return content.get('text', "")
136
+ if content.get("type") == "text":
137
+ return content.get('text', "")
138
+
136
139
  else:
137
140
  return str(contents)
141
+ return ""
138
142
 
139
143
  @cached_property
140
144
  def last_assistant_content(self) -> str:
145
+ """text"""
141
146
  for i, message in enumerate(self.messages[::-1], 1):
142
147
  if message.get("role") == "assistant":
143
148
  contents = message.get("content")
144
149
  if isinstance(contents, list):
145
150
  for content in contents:
146
- return content.get('text', "")
151
+ if content.get("type") == "text":
152
+ return content.get('text', "")
147
153
  else:
148
154
  return str(contents)
155
+ return ""
149
156
 
150
157
  @cached_property
151
158
  def last_urls(self): # file_url 多轮对话需要 sum(request.last_urls.values(), [])
152
159
  """最新一轮的 user url 列表"""
153
- content_types = {"image_url", "file", "file_url", "video_url", "audio_url"}
160
+ content_types = {
161
+ "image_url",
162
+ "file", "file_url",
163
+ "audio_url", "input_audio",
164
+
165
+ "video_url",
166
+ }
154
167
  for i, message in enumerate(self.messages[::-1], 1):
155
168
  data = {}
156
169
  if message.get("role") == "user": # 每一轮还要处理
@@ -159,11 +172,12 @@ class CompletionRequest(BaseModel):
159
172
  for content in user_contents:
160
173
  content_type = content.get("type")
161
174
  if content_type in content_types:
175
+ # logger.debug(content)
162
176
  if _url := content.get(content_type, {}): # {"type": "file", "file": fileid}
163
177
  if isinstance(_url, str): # 兼容了spark qwenai
164
178
  url = _url
165
179
  else:
166
- url = _url.get("url")
180
+ url = _url.get("url") or _url.get("data")
167
181
  url and data.setdefault(content_type, []).append(url)
168
182
 
169
183
  if data: return data
@@ -523,39 +537,52 @@ if __name__ == '__main__':
523
537
  {},
524
538
  {'role': 'user', 'content': '总结'}]
525
539
 
526
- mesages = [{'role': 'system',
527
- 'content': 'undefined\n Current date: 2025-03-13'},
528
- {'role': 'user',
529
- 'content': [{'type': 'text', 'text': '一句话总结'},
530
- {'type': 'image_url',
531
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
532
- {},
533
- {'role': 'user',
534
- 'content': [{'type': 'text', 'text': '一句话总结'},
535
- {'type': 'image_url',
536
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
537
- {},
538
- {'role': 'user',
539
- 'content': [{'type': 'text', 'text': '一句话总结'},
540
- {'type': 'image_url',
541
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
542
- {},
543
- {'role': 'user',
544
- 'content': [{'type': 'text', 'text': '一句话总结'},
545
- {'type': 'image_url',
546
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
547
- {},
548
- {'role': 'user',
549
- 'content': [{'type': 'text', 'text': '一句话总结'},
550
- {'type': 'image_url',
551
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
552
- {},
553
- {'role': 'user',
554
- 'content': [{'type': 'text', 'text': '一句话总结'},
555
- {'type': 'image_url',
556
- 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
557
- {},
558
- {'role': 'user', 'content': '总结'}]
540
+ messages = [{'role': 'system',
541
+ 'content': 'undefined\n Current date: 2025-03-13'},
542
+ {'role': 'user',
543
+ 'content': [{'type': 'text', 'text': '一句话总结'},
544
+ {'type': 'image_url',
545
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
546
+ {},
547
+ {'role': 'user',
548
+ 'content': [{'type': 'text', 'text': '一句话总结'},
549
+ {'type': 'image_url',
550
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
551
+ {},
552
+ {'role': 'assistant',
553
+ 'content': [{'type': 'text', 'text': '一句话总结'},
554
+ {'type': 'image_url',
555
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
556
+ {},
557
+ {'role': 'user',
558
+ 'content': [{'type': 'text', 'text': '一句话总结'},
559
+ {'type': 'image_url',
560
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
561
+ {},
562
+ {'role': 'user',
563
+ 'content': [{'type': 'text', 'text': '一句话总结'},
564
+ {'type': 'image_url',
565
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'}]},
566
+ {},
567
+ {'role': 'user',
568
+ 'content': [
569
+ {'type': 'image_url',
570
+ 'image_url': 'https://ai.chatfire.cn/files/images/uniacess删除-1741853464016-b176842ad.txt'},
571
+ {
572
+ "type": "input_audio",
573
+ "input_audio": {
574
+ "data": "base64_audio",
575
+ "format": "wav"
576
+ }
577
+ },
578
+ {'type': 'text', 'text': '一句话总结'},
579
+
580
+ ],
581
+
582
+ },
583
+ {},
584
+ # {'role': 'user', 'content': '总结'}
585
+ ]
559
586
  #
560
587
  # r = ChatCompletionRequest(model="gpt-3.5-turbo", messages=messages)
561
588
  # r.messages[-1]['content'] = [{"type": "image_url", "image_url": {"url": r.urls[-1]}}]
@@ -566,7 +593,10 @@ if __name__ == '__main__':
566
593
  # print(chat_completion_chunk_stop)
567
594
 
568
595
  # print(CompletionRequest(messages=messages).last_urls)
569
- # print(CompletionRequest(messages=messages).last_user_content)
596
+ # print(CompletionRequest(messages=messages).last_urls)
570
597
 
571
- print(chat_completion_chunk)
572
- print(chat_completion)
598
+ # print(mesages)
599
+ print(CompletionRequest(messages=messages).last_assistant_content)
600
+
601
+ # print(chat_completion_chunk)
602
+ # print(chat_completion)
@@ -21,7 +21,6 @@ HTML_PARSER = re.compile(r'```html(.*?)```', re.DOTALL)
21
21
  # re.sub(r'=(.+)', r'=123','s=xxxxx')
22
22
 
23
23
 
24
-
25
24
  @lru_cache()
26
25
  def remove_date_suffix(filename):
27
26
  """
@@ -61,7 +60,9 @@ def get_parse_and_index(text, pattern):
61
60
 
62
61
 
63
62
  @lru_cache()
64
- def parse_url(text: str, for_image=False):
63
+ def parse_url(text: str, for_image=False, fn: Optional[Callable] = None):
64
+ fn = fn or (lambda x: x.removesuffix(")"))
65
+
65
66
  # url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
66
67
  url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+|#]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
67
68
 
@@ -92,6 +93,9 @@ def parse_url(text: str, for_image=False):
92
93
  valid_urls = []
93
94
  for url in urls:
94
95
  url = url.strip(r"\n")
96
+ if fn:
97
+ url = fn(url) # lambda x: x.removesuffix(")")
98
+
95
99
  valid_urls.append(url)
96
100
 
97
101
  return valid_urls
@@ -149,7 +153,6 @@ if __name__ == '__main__':
149
153
  d = {"url": "https://mj101-1317487292.cos.ap-shanghai.myqcloud.com/ai/test.pdf\n\n总结下"}
150
154
  # print(parse_url(str(d)))
151
155
 
152
-
153
156
  text = "https://sc-maas.oss-cn-shanghai.aliyuncs.com/outputs/bb305b60-d258-4542-8b07-5ced549e9896_0.png?OSSAccessKeyId=LTAI5tQnPSzwAnR8NmMzoQq4&Expires=1739948468&Signature=NAswPSXj4AGghDuoNX5rVFIidcs%3D 笑起来"
154
157
 
155
158
  print(parse_url(text))