MeUtils 2025.9.7.1.36.27__py3-none-any.whl → 2025.9.9.15.11.11__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.
@@ -14,8 +14,10 @@ from openai import OpenAI
14
14
  from openai import OpenAI, APIStatusError
15
15
 
16
16
  client = OpenAI(
17
- # base_url=os.getenv("FFIRE_BASE_URL"),
18
- # api_key=os.getenv("FFIRE_API_KEY") #+"-29463"
17
+ base_url=os.getenv("FFIRE_BASE_URL"),
18
+ # api_key=os.getenv("FFIRE_API_KEY") +"-29487"
19
+ api_key=os.getenv("FFIRE_API_KEY") + "-29492",
20
+
19
21
  # base_url=os.getenv("ONEAPIS_BASE_URL"),
20
22
  # api_key=os.getenv("ONEAPIS_API_KEY") + "-3"
21
23
 
@@ -30,18 +32,23 @@ for i in range(1):
30
32
  # model="qwen3-235b-a22b-instruct-2507",
31
33
  # model="qwen-image",
32
34
  # model="glm-4.5",
33
- model="deepseek-v3-1-think",
35
+ # model="deepseek-v3-1-think",
36
+ # model="kimi-k2-0905-preview",
37
+ # model="kimi-k2-0711-preview",
38
+
39
+ model="glm-4.5-air",
40
+
34
41
  #
35
42
  messages=[
36
43
  {"role": "user", "content": 'are you ok?'}
37
44
  ],
38
45
  stream=True,
39
- # max_tokens=1000,
46
+ max_tokens=10,
40
47
  # extra_body={"xx": "xxxxxxxx"}
41
48
  extra_body={
42
49
  "thinking": {"type": "enabled"},
43
50
 
44
- "enable_thinking": True # parameter.enable_thinking only support stream
51
+ "enable_thinking": True # parameter.enable_thinking only support stream
45
52
  }
46
53
  )
47
54
  print(completion)
@@ -18,7 +18,7 @@ client = OpenAI(
18
18
  # base_url="http://ppu.chatfire.cc/v1"
19
19
  )
20
20
 
21
- print(client.models.list())
21
+ # print(client.models.list())
22
22
 
23
23
  # completion = client.chat.completions.create(
24
24
  # model="moonshot-v1-8k",
@@ -49,11 +49,11 @@ if __name__ == '__main__':
49
49
 
50
50
  from meutils.pipe import timer
51
51
 
52
- # with timer():
53
- # completion = client.chat.completions.create(
54
- # model="moonshot-v1-128k",
55
- # messages=[
56
- # {"role": "user", "content": ""*50000 + "一共有多少个字"},
57
- # ],
58
- # # temperature=0.3, extra_body={"refs": ["cn0bmk198onv4v01aafg"]}
59
- # )
52
+ with timer():
53
+ completion = client.chat.completions.create(
54
+ model="kimi-k2-0905-preview",
55
+ messages=[
56
+ {"role": "user", "content": "你好"*100000 + "\n\n上文一共有多少个字"},
57
+ ],
58
+ # temperature=0.3, extra_body={"refs": ["cn0bmk198onv4v01aafg"]}
59
+ )
@@ -17,15 +17,15 @@ from meutils.str_utils import parse_base64
17
17
  # gets API Key from environment variable OPENAI_API_KEY
18
18
  client = OpenAI(
19
19
  # base_url="https://openrouter.ai/api/v1",
20
- # base_url="https://all.chatfire.cn/openrouter/v1",
21
- # api_key=os.getenv("OPENROUTER_API_KEY"),
20
+ base_url="https://all.chatfire.cn/openrouter/v1",
21
+ api_key=os.getenv("OPENROUTER_API_KEY"),
22
22
  #
23
23
  # base_url="http://38.46.219.252:9001/v1",
24
24
  #
25
25
  # api_key="sk-Azgp1thTIonR7IdIEqlJU51tpDYNIYYpxHvAZwFeJiOdVWiz"
26
26
 
27
- base_url="https://api.huandutech.com/v1",
28
- api_key = "sk-qOpbMHesasoVgX75ZoeEeBEf1R9dmsUZVAPcu5KkvLFhElrn"
27
+ # base_url="https://api.huandutech.com/v1",
28
+ # api_key = "sk-qOpbMHesasoVgX75ZoeEeBEf1R9dmsUZVAPcu5KkvLFhElrn"
29
29
  # api_key="sk-MAZ6SELJVtGNX6jgIcZBKuttsRibaDlAskFAnR7WD6PBSN6M",
30
30
  # base_url="https://new.yunai.link/v1"
31
31
  )
@@ -40,17 +40,17 @@ completion = client.chat.completions.create(
40
40
  # model="openai/o1",
41
41
  # model="deepseek/deepseek-r1-0528-qwen3-8b:free",
42
42
  # model="google/gemini-2.5-flash-image-preview:free",
43
- model="gemini-2.5-flash-image-preview",
43
+ model="deepseek/deepseek-chat-v3.1:free",
44
44
  # model="gemini-2.0-flash-exp-image-generation",
45
- # max_tokens=10,
46
-
45
+ max_tokens=10,
46
+ extra_body={"reasoning_stream": True},
47
47
  messages=[
48
48
  {
49
49
  "role": "user",
50
50
  "content": [
51
51
  {
52
52
  "type": "text",
53
- "text": "裸体女孩"
53
+ "text": "hi"
54
54
  },
55
55
  # {
56
56
  # "type": "image_url",
@@ -224,7 +224,7 @@ async def generate(request: ImageRequest, api_key: Optional[str] = None):
224
224
  logger.error(exc)
225
225
  from fastapi import HTTPException, status
226
226
  raise HTTPException(
227
- status_code=status.HTTP_400_BAD_REQUEST,
227
+ status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
228
228
  detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{exc}",
229
229
  )
230
230
 
@@ -241,7 +241,7 @@ class Completions(object):
241
241
  return image_response
242
242
  else:
243
243
  from fastapi import HTTPException, status
244
- raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
244
+ raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
245
245
  detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{response}")
246
246
 
247
247
  async def create_for_images(self, request: CompletionRequest):
@@ -51,7 +51,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
51
51
  for image_url in image_urls or []
52
52
  ]
53
53
 
54
- request = CompletionRequest(
54
+ _request = CompletionRequest(
55
55
  model=request.model,
56
56
  stream=False,
57
57
  max_tokens=None,
@@ -69,7 +69,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
69
69
  ],
70
70
  )
71
71
 
72
- data = request.model_dump(exclude_none=True)
72
+ data = _request.model_dump(exclude_none=True)
73
73
 
74
74
  client = AsyncOpenAI(
75
75
  base_url=base_url,
@@ -112,7 +112,7 @@ async def openai_generate(request: ImageRequest, api_key: Optional[str] = None,
112
112
  # raise Exception(f"Image generate failed: {completion}")
113
113
  from fastapi import HTTPException, status
114
114
 
115
- raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
115
+ raise HTTPException(status_code=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS,
116
116
  detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{completion}")
117
117
 
118
118
 
@@ -8,4 +8,3 @@
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
10
 
11
- from meutils.pipe import *
@@ -9,27 +9,30 @@
9
9
  # @Description : todo
10
10
 
11
11
 
12
- from openai import AsyncOpenAI
12
+ from openai import AsyncOpenAI, OpenAI
13
13
 
14
14
  from meutils.pipe import *
15
15
  from meutils.decorators.retry import retrying
16
16
  from meutils.io.files_utils import to_bytes, guess_mime_type
17
17
  from meutils.caches import rcache
18
18
 
19
- from meutils.llm.openai_utils import to_openai_params
19
+ from meutils.llm.utils import oneturn2multiturn
20
20
 
21
21
  from meutils.config_utils.lark_utils import get_next_token_for_polling
22
22
  from meutils.schemas.openai_types import chat_completion, chat_completion_chunk, CompletionRequest, CompletionUsage, \
23
- ChatCompletion
23
+ ChatCompletion, ChatCompletionChunk
24
+ from openai._streaming import AsyncStream, Stream
24
25
 
25
26
  base_url = "https://longcat.chat/api/v1/chat-completion"
26
27
  base_url = "https://longcat.chat/api/v1/chat-completion-oversea"
27
28
  base_url = "https://longcat.chat/api/v1"
28
29
 
30
+ cookie = "_lxsdk_cuid=1990e1e8790c8-0b2a66e23040a48-16525636-1fa400-1990e1e8790c8; passport_token_key=AgEGIygg22VuoMYTPonur9FA_-EVg9UXLu3LYOzJ4kIHSjQZeSNhwpytTU_cZFP6V1Juhk0CHMrAgwAAAABYLAAA9vXtnciaZBu2V99EMRJYRHTDSraV_OPLemUuVpi2WLsaa6RqC0PAKAOm6W_hIpbV"
31
+
29
32
 
30
33
  class Completions(object):
31
34
  def __init__(self, api_key: Optional[str] = None):
32
- self.api_key = api_key
35
+ self.api_key = api_key or cookie
33
36
 
34
37
  async def create(self, request: CompletionRequest, **kwargs):
35
38
  payload = self.requset2payload(request)
@@ -47,28 +50,38 @@ class Completions(object):
47
50
  response.raise_for_status()
48
51
 
49
52
  async for chunk in response.aiter_lines():
50
- logger.debug(chunk)
53
+ if chunk := chunk.removeprefix("data:"):
54
+ _chunk = json.loads(chunk)
55
+
56
+ chat_completion_chunk = ChatCompletionChunk.model_validate(_chunk)
57
+ # logger.debug(chunk)
58
+
59
+ yield chat_completion_chunk
60
+
61
+ if not request.stream:
62
+ # logger.debug(_chunk)
63
+ model = _chunk.get("model", "LongCat-Flash")
64
+ content = _chunk.get("content", "")
65
+ reason_content = _chunk.get("reasonContent", "")
66
+ token_info = _chunk.get("tokenInfo", {})
67
+
68
+ chat_completion_chunk.choices[0].content = content
69
+ chat_completion_chunk.choices[0].reason_content = reason_content
70
+ usage = CompletionUsage(
71
+ prompt_tokens=token_info.get("promptTokens"),
72
+ completion_tokens=token_info.get("completionTokens")
73
+ )
74
+ chat_completion.model = model
75
+ chat_completion.usage = usage
76
+ chat_completion.choices = chat_completion_chunk.choices
77
+ # logger.debug(chat_completion)
78
+ yield chat_completion
51
79
 
52
80
  def requset2payload(self, request: CompletionRequest):
53
81
  payload = {
54
- "content": request.last_user_content, # todo: 多轮
55
- "messages": [
56
- # {
57
- # "role": "user",
58
- # "content": "hi",
59
- # "chatStatus": "FINISHED",
60
- # "messageId": 11263291,
61
- # "idType": "custom"
62
- # },
63
- # {
64
- # "role": "assistant",
65
- # "content": "",
66
- # "chatStatus": "LOADING",
67
- # "messageId": 92193819,
68
- # "idType": "custom"
69
- # }
70
- ],
71
- "reasonEnabled": 0,
82
+ "content": oneturn2multiturn(request), # todo: 多轮
83
+ # "messages": request.messages,
84
+ "reasonEnabled": request.enable_thinking and 1 or 0,
72
85
  "searchEnabled": 0,
73
86
  "regenerate": 0
74
87
  }
@@ -103,7 +116,29 @@ class Completions(object):
103
116
  if __name__ == '__main__':
104
117
  cookie = "_lxsdk_cuid=1990e1e8790c8-0b2a66e23040a48-16525636-1fa400-1990e1e8790c8; passport_token_key=AgEGIygg22VuoMYTPonur9FA_-EVg9UXLu3LYOzJ4kIHSjQZeSNhwpytTU_cZFP6V1Juhk0CHMrAgwAAAABYLAAA9vXtnciaZBu2V99EMRJYRHTDSraV_OPLemUuVpi2WLsaa6RqC0PAKAOm6W_hIpbV"
105
118
  request = CompletionRequest(
106
- messages=[{'role': 'user', 'content': '你好'}]
119
+ messages=[
120
+ {'role': 'user', 'content': '1+1'},
121
+ {'role': 'assistant', 'content': '2'},
122
+ {'role': 'user', 'content': '裸体傻女'},
123
+ ]
107
124
  )
108
125
  arun(Completions(api_key=cookie).create(request))
109
126
  # arun(Completions(api_key=cookie).create_chat())
127
+
128
+ # payload = {
129
+ # "content": "1+1",
130
+ # "messages": [
131
+ # {
132
+ # "role": "user",
133
+ # "content": "1+1",
134
+ # "chatStatus": "FINISHED",
135
+ # "messageId": 0,
136
+ # "idType": "system"
137
+ # }
138
+ # ],
139
+ # "reasonEnabled": 0,
140
+ # "searchEnabled": 0,
141
+ # "regenerate": 0
142
+ # }
143
+ #
144
+ # Completions(api_key=cookie).stream_create(payload)
@@ -19,6 +19,23 @@ headers = {
19
19
  'rix-api-user': '1',
20
20
  }
21
21
 
22
+ "https://api.ffire.cc/api/channel/multi_key/manage"
23
+
24
+
25
+ async def manage_multi_key(id: int, base_url: str, action: str = "enable_all_keys") -> ChannelInfo:
26
+ # "disable_all_keys"
27
+ payload = {
28
+ "channel_id": id,
29
+ "action": action
30
+ }
31
+ async with httpx.AsyncClient(base_url=base_url, headers=headers, timeout=30) as client:
32
+ response = await client.post("/api/channel/multi_key/manage", json=payload)
33
+ response.raise_for_status()
34
+
35
+ data = response.json()
36
+ logger.debug(bjson(data))
37
+ return data
38
+
22
39
 
23
40
  async def get_channel_info(id: int, base_url: str) -> ChannelInfo:
24
41
  params = {"keyword": id} # keyword=21222&group=&model=&id_sort=true&tag_mode=false&p=1&page_size=100
@@ -28,7 +45,7 @@ async def get_channel_info(id: int, base_url: str) -> ChannelInfo:
28
45
  response.raise_for_status()
29
46
 
30
47
  data = response.json()
31
- # logger.debug(bjson(data))
48
+ logger.debug(bjson(data))
32
49
  if (items := data.get("data", {}).get("items", [])) and (item := items[0]):
33
50
  return item['status'] # status==1 是正常
34
51
 
@@ -176,7 +193,12 @@ async def create_or_update_channel(
176
193
  logger.debug(response.text)
177
194
 
178
195
  response.raise_for_status()
179
- logger.debug(response.json())
196
+
197
+ data = response.json()
198
+ logger.debug(bjson(data))
199
+ if (data := data.get("data")) and data['channel_info']['is_multi_key']:
200
+ await manage_multi_key(data['id'], base_url=base_url)
201
+
180
202
  return response.json()
181
203
 
182
204
 
@@ -268,15 +290,20 @@ if __name__ == '__main__':
268
290
  # arun(create_or_update_channel(tokens, base_url))
269
291
  # arun(create_or_update_channel(tokens))
270
292
  # # arun(delete_channel(range(10000, 20000)))
271
- key = "KEY"
272
- request = ChannelInfo(name='', key=key)
273
- request = ChannelInfo(id=21223, key=key, used_quota=0.001)
274
-
275
- # arun(create_or_update_channel(request, base_url=base_url))
293
+ key = "KEY\nKEY2"
294
+ # request = ChannelInfo(id = 1, name='xx', key=key)
295
+ # request = ChannelInfo(id=21223, key=key, used_quota=0.001)
296
+ request = ChannelInfo(id=29483, key=key, used_quota=0.001,
297
+ # key_mode="append"
298
+ )
299
+
300
+ arun(create_or_update_channel(request, base_url=base_url))
276
301
  #
277
302
  # arun(exist_channel(request, base_url=base_url))
278
303
 
279
- arun(get_channel_info(21222, base_url=base_url))
280
- # arun(get_channel_info(21223, base_url=base_url))
304
+ # arun(get_channel_info(21222, base_url=base_url))
305
+ # arun(get_channel_info(29483, base_url=base_url))
281
306
 
282
307
  # arun(delete_channel(range(10015, 10032), base_url=base_url))
308
+
309
+ # arun(manage_multi_key(29483, base_url=base_url))
@@ -22,7 +22,6 @@ from meutils.schemas.image_types import ImageRequest, ImagesResponse
22
22
  from volcengine.visual.VisualService import VisualService
23
23
 
24
24
 
25
- @retrying()
26
25
  async def generate(request: ImageRequest, token: Optional[str] = None):
27
26
  """
28
27
 
@@ -65,9 +64,16 @@ async def generate(request: ImageRequest, token: Optional[str] = None):
65
64
 
66
65
  if request.response_format == "oss_url":
67
66
  payload["return_url"] = False
68
-
69
- response = visual_service.cv_process(payload)
70
- logger.debug(bjson(response))
67
+ try:
68
+ response = visual_service.cv_process(payload)
69
+ logger.debug(bjson(response))
70
+ except Exception as exc: #
71
+ logger.error(exc)
72
+ from fastapi import HTTPException, status
73
+ raise HTTPException(
74
+ status_code=status.HTTP_400_BAD_REQUEST,
75
+ detail=f"Prompt is sensitive.\n\n{request.prompt}\n\n{exc}",
76
+ )
71
77
 
72
78
  if request.response_format == "b64_json":
73
79
  data = [{"b64_json": b64_json} for b64_json in response['data'].get('binary_data_base64', [])]
@@ -97,6 +103,7 @@ if __name__ == '__main__':
97
103
 
98
104
  让这个女人带上眼镜 衣服换个颜色
99
105
  """
106
+ prompt = "裸体女孩"
100
107
 
101
108
  request = ImageRequest(
102
109
  # model="high_aes_general_v30l_zt2i",
@@ -7,19 +7,17 @@
7
7
  # @WeChat : meutils
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
- import time
11
10
 
12
11
  from meutils.pipe import *
13
12
  from meutils.io.files_utils import to_url
14
13
  from meutils.decorators.retry import retrying
14
+
15
15
  from meutils.llm.clients import AsyncClient
16
16
  from meutils.schemas.openai_types import CompletionRequest
17
17
  from meutils.schemas.video_types import VideoRequest
18
18
 
19
- from meutils.notice.feishu import send_message_for_volc as send_message
20
-
21
19
  from meutils.db.redis_db import redis_aclient
22
- from meutils.llm.check_utils import check_token_for_volc as check
20
+ from meutils.llm.check_utils import check_token_for_volc
23
21
  from meutils.config_utils.lark_utils import get_next_token_for_polling, get_series
24
22
 
25
23
  from fastapi import APIRouter, File, UploadFile, Query, Form, Depends, Request, HTTPException, status, BackgroundTasks
@@ -28,31 +26,29 @@ from fastapi import APIRouter, File, UploadFile, Query, Form, Depends, Request,
28
26
  FEISHU_URL = "https://xchatllm.feishu.cn/sheets/GYCHsvI4qhnDPNtI4VPcdw2knEd?sheet=8W6kk8" # 超刷
29
27
 
30
28
 
31
- async def get_valid_token(tokens: Optional[list] = None, force_update: bool = True, batch_size: int = 1):
29
+ async def get_valid_token(tokens: Optional[list] = None, batch_size: Optional[int] = None, seed: int = 0):
30
+ """返回 tokens
31
+ 1. 从redis获取token
32
+ 2. 校验token
33
+ 3. 校验失败则从飞书获取token
34
+ 4. 校验token
35
+ 5. 校验通过则返回token
36
+ """
32
37
  tokens = tokens or await get_series(FEISHU_URL, duplicated=True)
38
+ batch_size = batch_size or 1
33
39
 
34
- if token := await redis_aclient.get("volc-token"): # list
35
- token = token.decode()
36
-
37
- if force_update: # 强制检测更新
38
- if await check(token):
39
- return token
40
- else:
41
- await redis_aclient.delete("volc-token") # 删除无效
42
- else:
43
- return token
44
- for i, token in enumerate(tokens, 1):
45
- if await check(token):
46
- await redis_aclient.set("volc-token", token, ex=2 * 3600 - 10 * 60)
47
-
48
- return token
49
- if batch_size == i:
50
- break
40
+ if seed == 0 and (volc_tokens := await redis_aclient.get(f"volc_tokens")):
41
+ return volc_tokens.decode()
51
42
 
52
- logger.debug(f"无效 {token}")
53
- _ = f"{time.ctime()}\n\n{FEISHU_URL}\n\n所有token无效\n\n{token}"
54
- logger.error(_)
55
- send_message(_, n=3)
43
+ valid_tokens = []
44
+ for token in tokens:
45
+ if token := await check_token_for_volc([token]):
46
+ valid_tokens += token
47
+ logger.debug(valid_tokens)
48
+ if len(valid_tokens) == batch_size:
49
+ _ = '\n'.join(valid_tokens)
50
+ await redis_aclient.set(f"volc_tokens", _, ex=2 * 3600)
51
+ return _
56
52
 
57
53
 
58
54
  # check_image_and_video = partial(check, purpose='video and image')
@@ -61,7 +57,9 @@ async def get_valid_token(tokens: Optional[list] = None, force_update: bool = Tr
61
57
  @retrying()
62
58
  async def create_task(request: Union[CompletionRequest, VideoRequest], api_key: Optional[str] = None):
63
59
  # api_key = api_key or await get_next_token_for_polling(feishu_url=FEISHU_URL, check_token=check)
64
- api_key = api_key or await get_valid_token(force_update=False)
60
+ api_key = api_key or await get_valid_token()
61
+
62
+ api_key = np.random.choice(api_key.split('\n'))
65
63
 
66
64
  # feishu_url = "https://xchatllm.feishu.cn/sheets/Z59Js10DbhT8wdt72LachSDlnlf?sheet=rcoDg7"
67
65
  # api_key = api_key or await get_next_token_for_polling(
@@ -267,7 +265,8 @@ c4356b58-4aa3-4a52-b907-b40c4dd2e502
267
265
  # arun(get_task_from_feishu(ids, tokens))
268
266
  # arun(get_task_from_feishu(ids, ))
269
267
 
270
- arun(get_valid_token())
268
+ # arun(get_valid_token(['a93ea9a5-3831-47b8-863a-57e10233f922']))
269
+ arun(get_valid_token(batch_size=2, seed=3))
271
270
 
272
271
  """
273
272
  {'id': 'cgt-20250613160030-2dvd7',
meutils/data/VERSION CHANGED
@@ -1 +1 @@
1
- 2025.09.07.01.36.27
1
+ 2025.09.09.15.11.11
@@ -176,7 +176,7 @@ async def check_token_for_ppinfra(api_key, threshold: float = 1): # 1块钱 100
176
176
  if not isinstance(api_key, str):
177
177
  return await check_tokens(api_key, partial(check_token_for_ppinfra, threshold=threshold))
178
178
  try:
179
- client = AsyncOpenAI(base_url="https://api.ppinfra.com/v3/user", api_key=api_key)
179
+ client = AsyncOpenAI(base_url="https://api.ppinfra.com/v3/user", api_key=api_key.strip())
180
180
  data = await client.get("", cast_to=object)
181
181
  logger.debug(data) # credit_balance
182
182
  return data["credit_balance"] >= threshold
@@ -214,7 +214,7 @@ async def check_token_for_sophnet(api_key, threshold: float = 1):
214
214
 
215
215
  #
216
216
  @retrying()
217
- # @rcache(ttl=7 * 24 * 3600, skip_cache_func=skip_cache_func)
217
+ @rcache(ttl=7 * 24 * 3600, skip_cache_func=skip_cache_func)
218
218
  async def check_token_for_volc(api_key, threshold: float = 1, purpose: Optional[str] = None):
219
219
  if not isinstance(api_key, str):
220
220
  return await check_tokens(api_key, check_token_for_volc)
meutils/llm/utils.py CHANGED
@@ -8,16 +8,13 @@
8
8
  # @Software : PyCharm
9
9
  # @Description :
10
10
 
11
- from contextlib import asynccontextmanager
12
11
 
13
12
  from meutils.pipe import *
14
- from meutils.llm.clients import AsyncOpenAI, OpenAI, AsyncStream
15
- from meutils.schemas.oneapi import MODEL_PRICE
16
- from meutils.notice.feishu import send_message
17
- from meutils.apis.oneapi.utils import get_user_quota
13
+ from meutils.schemas.openai_types import CompletionRequest
18
14
 
19
15
 
20
- def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: bool = True):
16
+
17
+ def oneturn2multiturn(messages: Union[dict, CompletionRequest], template: Optional[str] = None, ignore_system: bool = True):
21
18
  """todo: https://github.com/hiyouga/LLaMA-Factory/blob/e898fabbe3efcd8b44d0e119e7afaed4542a9f39/src/llmtuner/data/template.py#L423-L427
22
19
 
23
20
  _register_template(
@@ -45,6 +42,10 @@ def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: b
45
42
  # role, content = message.get("role"), message.get("content")
46
43
  # context += f"<|im_start|>{role}\n{content}<|im_end|>\n"
47
44
  # context += "<|im_start|>assistant\n"
45
+ if isinstance(messages, CompletionRequest):
46
+ messages = messages.messages
47
+
48
+
48
49
  if len(messages) == 1:
49
50
  content = messages[0].get("content")
50
51
  if isinstance(content, list):
@@ -53,6 +54,7 @@ def oneturn2multiturn(messages, template: Optional[str] = None, ignore_system: b
53
54
 
54
55
  context = "\n"
55
56
  for message in messages:
57
+ logger.info(message)
56
58
  role = message.get("role")
57
59
  content = message.get("content")
58
60
 
@@ -91,9 +91,9 @@ class ChannelInfo(BaseModel):
91
91
  # new
92
92
  max_input_tokens: int = 0
93
93
 
94
- mode:Optional[Literal["multi_to_single"]] = None
94
+ mode: Optional[Literal["multi_to_single"]] = None
95
95
  multi_key_mode: Literal['random', 'polling'] = "polling"
96
- key_mode: Optional[Literal['append', 'replace']] = None
96
+ key_mode: Optional[Literal['append', 'replace']] = None # none是覆盖
97
97
 
98
98
  def __init__(self, /, **data: Any):
99
99
  super().__init__(**data)
@@ -29,6 +29,7 @@ FAL_MODELS = {
29
29
  "fal-ai/clarity-upscaler": 1, # Your request will cost $0.03 per upscaled megapixel.
30
30
 
31
31
  'fal-kling-video-lipsync-audio-to-video': 0.5,
32
+ 'fal-ai/kling-video/lipsync/text-to-video': 0.14 * FAL,
32
33
 
33
34
  'fal-pixverse-v4.5-effects': 1,
34
35
  'fal-pixverse-v4.5-text-to-video': 0.9,