MeUtils 2025.3.14.8.43.3__py3-none-any.whl → 2025.3.19.19.13.35__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 (51) hide show
  1. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/METADATA +264 -264
  2. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/RECORD +43 -45
  3. apps/xfPPT_demo.py +251 -0
  4. examples/_openaisdk/4v.py +11 -6
  5. examples/_openaisdk/openai_chatfire.py +4 -3
  6. examples/_openaisdk/openai_embeddings.py +25 -7
  7. examples/_openaisdk/openai_siliconflow.py +1 -1
  8. examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +76 -13
  9. meutils/apis/jimeng/common.py +2 -0
  10. meutils/apis/jimeng/images.py +6 -6
  11. meutils/apis/jina/__init__.py +11 -0
  12. meutils/apis/jina/common.py +43 -0
  13. meutils/apis/oneapi/channel.py +3 -2
  14. meutils/apis/oneapi/user.py +1 -1
  15. meutils/apis/search/_web_search.py +87 -0
  16. meutils/apis/search/metaso.py +9 -2
  17. meutils/apis/search/web_search.py +132 -0
  18. meutils/apis/siliconflow/image_to_image.py +3 -3
  19. meutils/apis/siliconflow/images.py +4 -2
  20. meutils/apis/siliconflow/text_to_image.py +1 -1
  21. meutils/apis/siliconflow/utils.py +1 -1
  22. meutils/config_utils/lark_utils/common.py +6 -2
  23. meutils/data/VERSION +1 -1
  24. meutils/data/oneapi/index.html +9 -0
  25. meutils/io/files_utils.py +12 -1
  26. meutils/io/openai_files.py +26 -1
  27. meutils/llm/check_api.py +1 -1
  28. meutils/llm/check_utils.py +13 -4
  29. meutils/llm/clients.py +23 -0
  30. meutils/llm/completions/{oi.py → assistants/__init__.py} +2 -7
  31. meutils/llm/completions/assistants/ppt.py +11 -0
  32. meutils/llm/completions/chat_gemini.py +1 -0
  33. meutils/llm/completions/chat_plus.py +162 -49
  34. meutils/llm/completions/chat_spark.py +3 -10
  35. meutils/llm/completions/qwenllm.py +11 -6
  36. meutils/request_utils/crawler.py +11 -11
  37. meutils/schemas/oneapi/common.py +9 -1
  38. meutils/schemas/openai_types.py +26 -4
  39. meutils/schemas/siliconflow_types.py +1 -1
  40. meutils/apis/search/zhipu.py +0 -80
  41. meutils/llm/completions/qwen_demo.py +0 -26
  42. meutils/other/aiomultiprocess/__init__.py +0 -14
  43. meutils/other/aiomultiprocess/__version__.py +0 -1
  44. meutils/other/aiomultiprocess/core.py +0 -241
  45. meutils/other/aiomultiprocess/pool.py +0 -379
  46. meutils/other/aiomultiprocess/scheduler.py +0 -83
  47. meutils/other/aiomultiprocess/types.py +0 -48
  48. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/LICENSE +0 -0
  49. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/WHEEL +0 -0
  50. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/entry_points.txt +0 -0
  51. {MeUtils-2025.3.14.8.43.3.dist-info → MeUtils-2025.3.19.19.13.35.dist-info}/top_level.txt +0 -0
meutils/llm/check_api.py CHANGED
@@ -96,7 +96,7 @@ if __name__ == '__main__':
96
96
  #
97
97
  # api_keys = os.getenv("SILICONFLOW_API_KEY").split()
98
98
  # for api_key in api_keys:
99
- # arun(check(api_key, "https://api.siliconflow.com/v1/user/info"))
99
+ # arun(check(api_key, "https://api.siliconflow.cn/v1/user/info"))
100
100
 
101
101
  # api_keys = get_spreadsheet_values(feishu_url="https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=EOZuBW", to_dataframe=True)[0].tolist()
102
102
 
@@ -10,6 +10,8 @@
10
10
 
11
11
  from meutils.pipe import *
12
12
  from meutils.decorators.retry import retrying
13
+ from meutils.caches import rcache
14
+ from httpx import TimeoutException
13
15
 
14
16
  from openai import OpenAI, AsyncOpenAI
15
17
 
@@ -23,6 +25,7 @@ async def check_tokens(tokens, check_token: Callable):
23
25
 
24
26
 
25
27
  @retrying()
28
+ @rcache(ttl=1 * 3600)
26
29
  async def check_token_for_siliconflow(api_key, threshold: float = 0):
27
30
  if not isinstance(api_key, str):
28
31
  return await check_tokens(api_key, check_token_for_siliconflow)
@@ -33,7 +36,7 @@ async def check_token_for_siliconflow(api_key, threshold: float = 0):
33
36
  }
34
37
  try:
35
38
  async with httpx.AsyncClient(headers=headers, timeout=60) as client:
36
- response: httpx.Response = await client.get("https://api.siliconflow.com/v1/user/info")
39
+ response: httpx.Response = await client.get("https://api.siliconflow.cn/v1/user/info")
37
40
  response.raise_for_status()
38
41
 
39
42
  logger.debug(response.text)
@@ -43,6 +46,12 @@ async def check_token_for_siliconflow(api_key, threshold: float = 0):
43
46
  logger.debug(api_key)
44
47
  total_balance = response.json()['data']['totalBalance']
45
48
  return float(total_balance) >= threshold
49
+ except TimeoutException as e:
50
+ # logger.error(traceback.format_exc().strip())
51
+
52
+ logger.error("Timeout")
53
+
54
+ return True
46
55
 
47
56
  except Exception as e:
48
57
  logger.error(f"Error: {e}\n{api_key}")
@@ -50,7 +59,7 @@ async def check_token_for_siliconflow(api_key, threshold: float = 0):
50
59
 
51
60
 
52
61
  @retrying()
53
- async def check_token_for_openai(api_key, base_url="https://api.stepfun.com/v1"):
62
+ async def check_token_for_openai(api_key, base_url="https://api.stepfun.cn/v1"):
54
63
  try:
55
64
  client = AsyncOpenAI(
56
65
  base_url=base_url,
@@ -93,7 +102,7 @@ async def check_token_for_jina(api_key, threshold=1000):
93
102
 
94
103
 
95
104
  @retrying()
96
- async def check_token_for_moonshot(api_key, threshold: float=0):
105
+ async def check_token_for_moonshot(api_key, threshold: float = 0):
97
106
  if not isinstance(api_key, str):
98
107
  return await check_tokens(api_key, check_token_for_jina)
99
108
 
@@ -137,4 +146,4 @@ if __name__ == '__main__':
137
146
 
138
147
  # arun(check_token_for_jina(["jina_c8da77fed9704d558c8def39837960edplTLkNYrsPTJHBF1HcYg_RkRVh0X"]*10))
139
148
 
140
- arun(check_token_for_moonshot("sk-fWqLGmUtoGgoK9gx5IefO1mWrRF9QHaV7uVRrTcFv1lrJVvJ"))
149
+ arun(check_token_for_siliconflow("sk-zdsfykbjrdzobopoienanvlpqdsttbbmgpayctqokkrwqazg"))
meutils/llm/clients.py CHANGED
@@ -8,11 +8,13 @@
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
10
  from openai import Client, AsyncClient, AsyncStream, APIStatusError
11
+ from zhipuai import ZhipuAI
11
12
 
12
13
  from meutils.pipe import *
13
14
 
14
15
  OpenAI = lru_cache(Client)
15
16
  AsyncOpenAI = lru_cache(AsyncClient)
17
+ ZhipuAI = lru_cache(ZhipuAI)
16
18
 
17
19
  chatfire_client = AsyncOpenAI()
18
20
 
@@ -26,6 +28,11 @@ zhipuai_client = AsyncOpenAI(
26
28
  base_url=os.getenv("ZHIPUAI_BASE_URL")
27
29
  )
28
30
 
31
+ zhipuai_sdk_client = ZhipuAI(
32
+ api_key=os.getenv("ZHIPUAI_API_KEY"),
33
+ base_url=os.getenv("ZHIPUAI_BASE_URL")
34
+ )
35
+
29
36
  qwen_client = AsyncOpenAI(
30
37
  base_url="https://all.chatfire.cn/qwen/v1",
31
38
  api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMxMGNiZGFmLTM3NTQtNDYxYy1hM2ZmLTllYzgwMDUzMjljOSIsImV4cCI6MTc0MzAzNTk4OH0.GVAoSFtK94a9CgxqHCEnxzAnRi7gafIvYyH9mIJUh4s"
@@ -58,3 +65,19 @@ if __name__ == '__main__':
58
65
  # )
59
66
 
60
67
  # r.model_dump_json()
68
+
69
+ # f = zhipuai_client.chat.completions.create(
70
+ # messages=[{"role": "user", "content": "《哪吒之魔童闹海》现在的票房是多少"}],
71
+ # model='glm-4-flash',
72
+ # )
73
+ #
74
+ # arun(f)
75
+
76
+ response = zhipuai_client.images.generate(
77
+ model="cogview-3-flash", # 填写需要调用的模型编码
78
+ prompt="一只可爱的小猫咪",
79
+ n=2,
80
+ # size="1024x1024"
81
+ )
82
+
83
+ arun(response)
@@ -1,16 +1,11 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
  # @Project : AI. @by PyCharm
4
- # @File : oi
5
- # @Time : 2024/12/12 13:19
4
+ # @File : __init__.py
5
+ # @Time : 2025/3/19 09:05
6
6
  # @Author : betterme
7
7
  # @WeChat : meutils
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
10
 
11
11
  from meutils.pipe import *
12
-
13
-
14
- from openai import OpenAI
15
-
16
-
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : ppt
5
+ # @Time : 2025/3/19 09:05
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+ from meutils.pipe import *
@@ -47,6 +47,7 @@ class Completions(object):
47
47
 
48
48
  if __name__ == '__main__':
49
49
  url = "https://oss.ffire.cc/files/lipsync.mp3"
50
+ url = "https://lmdbk.com/5.mp4"
50
51
  content = [
51
52
  {"type": "text", "text": "总结下"},
52
53
  # {"type": "image_url", "image_url": {"url": url}},
@@ -14,65 +14,178 @@ from openai import AsyncOpenAI
14
14
  from meutils.pipe import *
15
15
  from meutils.decorators.retry import retrying
16
16
  from meutils.io.files_utils import to_bytes
17
- from meutils.io.openai_files import file_extract
17
+ from meutils.io.openai_files import file_extract, guess_mime_type
18
+ from meutils.str_utils.json_utils import json_path
19
+ from meutils.apis.search import metaso
20
+ # from meutils.apis.chatglm import glm_video_api
18
21
 
19
- from meutils.llm.clients import qwen_client, chatfire_client
22
+ from meutils.llm.clients import chatfire_client, zhipuai_client, AsyncOpenAI
20
23
  from meutils.llm.openai_utils import to_openai_params
21
24
 
22
- from meutils.config_utils.lark_utils import get_next_token_for_polling
23
- from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, CompletionUsage
24
-
25
- FEISHU_URL = "https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=PP1PGr"
26
-
27
- base_url = "https://chat.qwenlm.ai/api"
25
+ from meutils.schemas.openai_types import ChatCompletionRequest
26
+ from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, ImageRequest
28
27
 
29
28
  from fake_useragent import UserAgent
30
29
 
31
30
  ua = UserAgent()
32
31
 
33
- """
34
- # vision_model="doubao-1.5-vision-pro-32k"
35
- # glm-4v-flash
36
-
37
- 1. 文件解析
38
-
39
- """
40
-
41
32
 
42
33
  class Completions(object):
43
34
 
44
- def __init__(self,
45
- vision_model: str = "doubao-1.5-vision-pro-32k",
46
- base_url: Optional[str] = None,
47
- api_key: Optional[str] = None,
48
- ):
49
- self.vision_model = vision_model
50
- self.client = AsyncOpenAI(
51
- base_url=base_url,
52
- api_key=api_key,
53
- )
35
+ def __init__(self, api_key: Optional[str] = None):
36
+ self.api_key = api_key
37
+ self.client = AsyncOpenAI(api_key=api_key)
54
38
 
55
39
  async def create(self, request: CompletionRequest):
56
- """适配任意客户端"""
57
-
58
- last_message = request.last_message
59
- file_urls = request.last_urls.get("file_url", [])
60
- file_contents = await file_extract(file_urls)
61
-
62
-
63
- # if 'r1' in request.model: # vl
64
- # data = to_openai_params(request)
65
- # data['stream'] = False
66
- # data['model'] = self.vision_model
67
- #
68
- # data['messages'] = [
69
- # {"type": "text", "text": "图片描述:"}
70
- # ]
71
- #
72
- # # await chatfire_client.create(**data)
73
- #
74
- # return await chatfire_client.create(**data)
75
- #
76
- # request.last_message
77
-
78
- # "image_url": "http://ai.chatfire.cn/files/images/image-1725418399272-d7b71012f.png"
40
+ """
41
+ :param request:
42
+ :return:
43
+ """
44
+ if request.last_user_content.startswith(("画",)): # 画画
45
+ return await self.create_images(request) # str
46
+
47
+ # ppt 视频生成
48
+ # elif request.last_user_content.startswith(("联网", "搜索", "在线搜索", "在线查询")): # 画画
49
+ # return metaso.create(request)
50
+ # elif request.last_user_content.startswith(("视频",)): # 视频生成
51
+
52
+ elif request.last_user_content.startswith(("联网", "搜索", "在线搜索", "在线查询")): # 画画
53
+ return metaso.create(request)
54
+
55
+ elif request.last_user_content.startswith(("http",)):
56
+ file_url, text = request.last_user_content.split(maxsplit=1) # application/octet-stream
57
+
58
+ if guess_mime_type(file_url).startswith("image"): # 识图
59
+ request.model = "glm-4v-flash"
60
+ request.messages = [
61
+ {
62
+ 'role': 'user',
63
+ 'content': [
64
+ {
65
+ "type": "text",
66
+ "text": text
67
+ },
68
+
69
+ {
70
+ "type": "image_url",
71
+ "image_url": {
72
+ "url": file_url
73
+ }
74
+ }
75
+ ]
76
+ }
77
+ ]
78
+ data = to_openai_params(request)
79
+ return self.client.chat.completions.create(**data)
80
+
81
+ elif guess_mime_type(file_url).startswith(("video", "audio")): # 音频 视频
82
+ request.model = "gemini" # 果果
83
+ request.messages = [
84
+ {
85
+ 'role': 'user',
86
+ 'content': [
87
+ {
88
+ "type": "text",
89
+ "text": text
90
+ },
91
+ {
92
+ "type": "image_url",
93
+ "image_url": {
94
+ "url": file_url
95
+ }
96
+ }
97
+ ]
98
+ }
99
+ ]
100
+ data = to_openai_params(request)
101
+ return self.client.chat.completions.create(**data)
102
+
103
+ else:
104
+
105
+ file_content = await file_extract(file_url) # 文件问答-单轮
106
+
107
+ request.messages = [
108
+ {
109
+ 'role': 'user',
110
+ 'content': f"""{json.dumps(file_content, ensure_ascii=False)}\n\n{text}"""
111
+ }
112
+ ]
113
+ data = to_openai_params(request)
114
+ return self.client.chat.completions.create(**data)
115
+
116
+ if image_urls := request.last_urls.get("image_url"): # 识图
117
+ request.model = "glm-4v-flash"
118
+ data = to_openai_params(request)
119
+ return self.client.chat.completions.create(**data)
120
+
121
+ elif file_urls := request.last_urls.get("file_url"):
122
+ return self.chat_files(request)
123
+
124
+ data = to_openai_params(request)
125
+ return self.client.chat.completions.create(**data)
126
+
127
+ async def chat_files(self, request: CompletionRequest): # 多轮
128
+ for i, message in enumerate(request.messages[::-1], 1):
129
+ if message.get("role") == "user":
130
+ texts = json_path(message, expr='$..text') or [""]
131
+ file_urls = json_path(message, expr='$..file_url.url') or [""]
132
+
133
+ logger.debug(f"""{texts} \n\n {file_urls}""")
134
+
135
+ text, file_url = texts[-1], file_urls[-1]
136
+ if file_url in request.last_urls.get("file_url", []):
137
+ file_content = await file_extract(file_url)
138
+
139
+ message["content"] = f"""{json.dumps(file_content, ensure_ascii=False)}\n\n{text}"""
140
+
141
+ request.messages = request.messages[-i:]
142
+ break # 截断:从最新的文件开始
143
+
144
+ data = to_openai_params(request)
145
+ return self.client.chat.completions.create(**data)
146
+
147
+ async def create_images(self, request: CompletionRequest):
148
+
149
+ response = await zhipuai_client.images.generate(
150
+ model="cogview-3-flash",
151
+ prompt=request.last_user_content,
152
+ n=1
153
+ )
154
+ image_url = response.data[0].url
155
+ tool_desc = """> images.generate\n\n"""
156
+ return tool_desc + f"![{request.last_user_content}]({image_url})"
157
+
158
+ # async def create_videos(self, request: CompletionRequest):
159
+ #
160
+ # request = ImageRequest(prompt=request.last_user_content)
161
+ #
162
+ # response = await glm_video_api.generate(request)
163
+ # image_url = response.data[0].url
164
+ # tool_desc = """> images.generate\n\n"""
165
+ # return tool_desc + f"![{request.last_user_content}]({image_url})"
166
+
167
+
168
+ if __name__ == '__main__':
169
+ c = Completions()
170
+
171
+ request = CompletionRequest(
172
+ model="qwen-turbo-2024-11-01",
173
+ # model="claude-3-5-sonnet-20241022",
174
+ # model="gpt-4o-mini",
175
+
176
+ messages=[{
177
+ 'role': 'user',
178
+ 'content': [
179
+ {
180
+ "type": "text",
181
+ "text": "总结下"
182
+ },
183
+
184
+ # {
185
+ # "type": "image_url",
186
+ # "image_url": "https://oss.ffire.cc/files/招标文件备案表(第二次).pdf"
187
+ # }
188
+ ]
189
+ }])
190
+
191
+ arun(c.create(request))
@@ -6,18 +6,11 @@
6
6
  # @Author : betterme
7
7
  # @WeChat : meutils
8
8
  # @Software : PyCharm
9
- # @Description : 支持文档、图片、音频、视频问答
10
- """单一智能体
11
- 任意模型支持文档、图片、音频、视频问答
12
- api形式
13
- - /agents/v1
14
- - /v1 前缀区分 agents-{model}【底层调用 /agents/v1】
9
+ # @Description :
15
10
 
16
- todo: 记录上下文日志
17
- """
18
11
 
19
12
  from meutils.pipe import *
20
- from meutils.io.openai_files import file_extract
13
+ from meutils.io.openai_files import file_extract, guess_mime_type
21
14
  from meutils.str_utils.json_utils import json_path
22
15
 
23
16
  from meutils.llm.clients import AsyncOpenAI
@@ -45,7 +38,7 @@ class Completions(object):
45
38
  elif image_urls := request.last_urls.get("image_url"): # 长度为1
46
39
  url = image_urls[0]
47
40
 
48
- if url.endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp')): # 图片问答
41
+ if guess_mime_type(url).startswith("image"): # 图片问答
49
42
 
50
43
  request.model = "doubao-1.5-vision-pro-32k" # 6月过期
51
44
  for i, message in enumerate(request.messages):
@@ -127,12 +127,15 @@ async def create(request: CompletionRequest, token: Optional[str] = None): # Ch
127
127
 
128
128
  else:
129
129
  response = await client.chat.completions.create(**data)
130
- for i in range(3):
131
- if not isinstance(response, str): # 报错
132
- yield response.choices[0].message.content
133
- break
134
- else:
135
- logger.warning(f"重试 {i}\n{response}")
130
+ if not isinstance(response, str):
131
+ yield response.choices[0].message.content # isinstance(response, str)
132
+
133
+ # for i in range(3):
134
+ # if not isinstance(response, str): # 报错
135
+ # yield response.choices[0].message.content
136
+ # break
137
+ # else:
138
+ # logger.warning(f"重试 {i}\n{response}")
136
139
 
137
140
 
138
141
  if __name__ == '__main__':
@@ -186,6 +189,8 @@ if __name__ == '__main__':
186
189
 
187
190
  # model="qwen-plus-latest",
188
191
 
192
+ max_tokens=8000,
193
+
189
194
  messages=[
190
195
  {
191
196
  'role': 'user',
@@ -62,14 +62,14 @@ if __name__ == '__main__':
62
62
  html_content = httpx.get(url).text
63
63
 
64
64
 
65
- # 正则表达式匹配以 "/_next/static/chunks/7116-" 开头的 JS 文件
66
- pattern = r'(/_next/static/chunks/7116-[^"]+\.js)'
67
-
68
- # 使用 re.findall() 找到所有匹配项
69
- matches = re.findall(pattern, html_content)
70
-
71
- "/_next/static/chunks/7116-aed224a0caaab94c.js"
72
-
73
- # 打印结果
74
- for match in matches:
75
- print(match)
65
+ # # 正则表达式匹配以 "/_next/static/chunks/7116-" 开头的 JS 文件
66
+ # pattern = r'(/_next/static/chunks/7116-[^"]+\.js)'
67
+ #
68
+ # # 使用 re.findall() 找到所有匹配项
69
+ # matches = re.findall(pattern, html_content)
70
+ #
71
+ # "/_next/static/chunks/7116-aed224a0caaab94c.js"
72
+ #
73
+ # # 打印结果
74
+ # for match in matches:
75
+ # print(match)
@@ -28,6 +28,7 @@ MODEL_PRICE = {
28
28
  # rix
29
29
  "kling_image": 0.025,
30
30
  "kling_virtual_try_on": 1,
31
+ "kling_effects": 1,
31
32
 
32
33
  "kling_video": 1.2,
33
34
  "kling_extend": 1.2,
@@ -218,7 +219,7 @@ MODEL_PRICE = {
218
219
  "api-voice-clone": 0.01,
219
220
 
220
221
  # suno
221
- "suno_music": 0.3,
222
+ "suno_music": 0.36,
222
223
  "suno_lyrics": 0.01,
223
224
  "suno_uploads": 0.01,
224
225
  "suno_upload": 0.01,
@@ -646,6 +647,8 @@ MODEL_RATIO = {
646
647
  "gemini-2.0-flash-001": 0.0625,
647
648
  "gemini-2.0-flash-lite-preview-02-05": 0.0625,
648
649
  "gemini-2.0-flash-exp": 0.0625,
650
+ "gemini-2.0-flash-exp-image": 2.5,
651
+ "gemini-2.0-flash-exp-image-generation": 2.5,
649
652
 
650
653
  "gemini-2.0-pro": 1.25,
651
654
  "gemini-2.0-pro-exp-02-05": 1.25,
@@ -733,6 +736,7 @@ MODEL_RATIO = {
733
736
  # sili
734
737
  "gemma2-9b-it": 0.1,
735
738
  "gemma2-27b-it": 0.5,
739
+ "google/gemma-3-27b-it": 0.5,
736
740
 
737
741
  "internlm2_5-7b-chat": 0.01,
738
742
  'internlm2_5-20b-chat': 0.5,
@@ -845,6 +849,9 @@ COMPLETION_RATIO = {
845
849
  "gemini-2.0-flash-001": 4,
846
850
 
847
851
  "gemini-2.0-flash-exp": 5,
852
+ "gemini-2.0-flash-exp-image": 5,
853
+ "gemini-2.0-flash-exp-image-generation": 5,
854
+
848
855
  "gemini-2.0-flash-thinking-exp": 5,
849
856
  "gemini-2.0-flash-thinking-exp-1219": 5,
850
857
  "gemini-2.0-flash-thinking-exp-01-21": 5,
@@ -856,6 +863,7 @@ COMPLETION_RATIO = {
856
863
 
857
864
  "gemma2-9b-it": 4,
858
865
  "gemma2-27b-it": 4,
866
+ "google/gemma-3-27b-it": 4,
859
867
 
860
868
  "hunyuan-a52b-instruct": 5,
861
869
  "qwen2.5-coder-32b-instruct": 3,
@@ -55,7 +55,7 @@ class Choice(_Choice):
55
55
 
56
56
 
57
57
  class ChatCompletion(_ChatCompletion):
58
- id: str = Field(default_factory=shortuuid.random)
58
+ id: str = Field(default_factory=lambda: f"chatcmpl-{shortuuid.random()}")
59
59
  created: int = Field(default_factory=lambda: int(time.time()))
60
60
  model: str = ""
61
61
  object: str = "chat.completion"
@@ -67,7 +67,7 @@ class ChunkChoice(_ChunkChoice):
67
67
 
68
68
 
69
69
  class ChatCompletionChunk(_ChatCompletionChunk):
70
- id: str = Field(default_factory=shortuuid.random)
70
+ id: str = Field(default_factory=lambda: f"chatcmpl-{shortuuid.random()}")
71
71
  created: int = Field(default_factory=lambda: int(time.time()))
72
72
  model: str = ""
73
73
  object: str = "chat.completion.chunk"
@@ -161,6 +161,25 @@ class CompletionRequest(BaseModel):
161
161
  if data: return data
162
162
  return {}
163
163
 
164
+ # def create_message(self, text: str, content_type: Optional[str] = None):
165
+ # """
166
+ # 消息生成器
167
+ # :param text:
168
+ # :param content_type:
169
+ # :return:
170
+ # """
171
+ # message = {
172
+ # 'role': 'user',
173
+ # 'content': [
174
+ # {
175
+ # "type": "text",
176
+ # "text": text
177
+ # },
178
+ # ]
179
+ # }
180
+ #
181
+ # return message
182
+
164
183
 
165
184
  class ChatCompletionRequest(BaseModel):
166
185
  """
@@ -520,5 +539,8 @@ if __name__ == '__main__':
520
539
  # print(chat_completion)
521
540
  # print(chat_completion_chunk_stop)
522
541
 
523
- print(CompletionRequest(messages=messages).last_urls)
524
- print(CompletionRequest(messages=messages).last_user_content)
542
+ # print(CompletionRequest(messages=messages).last_urls)
543
+ # print(CompletionRequest(messages=messages).last_user_content)
544
+
545
+ print(chat_completion_chunk)
546
+ print(chat_completion)
@@ -11,7 +11,7 @@
11
11
 
12
12
  from meutils.pipe import *
13
13
 
14
- BASE_URL = "https://api.siliconflow.com/v1"
14
+ BASE_URL = "https://api.siliconflow.cn/v1"
15
15
 
16
16
  EXAMPLES = [
17
17
  {
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # @Project : AI. @by PyCharm
4
- # @File : zhipu
5
- # @Time : 2025/2/19 20:42
6
- # @Author : betterme
7
- # @WeChat : meutils
8
- # @Software : PyCharm
9
- # @Description :
10
-
11
- from meutils.pipe import *
12
- from meutils.str_utils.json_utils import json_path
13
- from meutils.llm.clients import AsyncOpenAI, chatfire_client, zhipuai_client, moonshot_client
14
- from meutils.llm.openai_utils import to_openai_params
15
- from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, ChatCompletionRequest, CompletionUsage
16
-
17
-
18
- class Completions(object):
19
-
20
- def __init__(self, api_key: Optional[str] = None):
21
- self.api_key = api_key
22
-
23
- async def create(self, request: ChatCompletionRequest, search_result2md: bool = False):
24
- request.stream = False
25
- request.model = "web-search-pro"
26
- request.messages = [{
27
- "role": "user",
28
- "content": request.last_content,
29
- }]
30
- data = to_openai_params(request)
31
-
32
- search_completion = await zhipuai_client.chat.completions.create(**data)
33
- logger.debug(search_completion.model_dump_json(indent=4))
34
-
35
- if results := json_path(search_completion, '$..[keywords,query,search_result]'):
36
- data = dict(zip(["keywords", "query", "search_result"], results))
37
- if search_result2md:
38
- global df
39
-
40
- df = pd.DataFrame(data["search_result"])
41
-
42
- df['title'] = [f"[{k}]({v})" for k, v in zip(df['title'], df['link'])]
43
- df['media'] = [f"![{k}]({v})" for k, v in zip(df['media'], df['icon'])]
44
-
45
- df = df[['title', 'media']]
46
- df.index += 1
47
- # {df_.to_markdown(index=False).replace('|:-', '|-').replace('-:|', '-|')}
48
- data["search_result"] = df.to_markdown()
49
- return data
50
-
51
- async def query(self, q: str):
52
- pass
53
-
54
- # {
55
- # "role": "user",
56
- # "content": search_completion.model_dump_json(indent=4),
57
- # }
58
-
59
-
60
- if __name__ == '__main__':
61
- model = "web-search-pro"
62
- # model = "tencent-search"
63
-
64
- request = ChatCompletionRequest(
65
- # model="baichuan4-turbo",
66
- # model="xx",
67
- # model="deepseek-r1",
68
- # model="deepseek-r1:1.5b",
69
- model=model,
70
-
71
- # model="moonshot-v1-8k",
72
- # model="doubao",
73
-
74
- messages=[
75
- {"role": "user", "content": "《哪吒之魔童闹海》现在的票房是多少"}
76
- ],
77
-
78
- stream=True
79
- )
80
- arun(Completions().create(request, search_result2md=True))