style: restrict line-length

This commit is contained in:
Junyan Qin
2025-05-10 18:04:58 +08:00
parent b30016ed08
commit 055b389353
134 changed files with 1096 additions and 2595 deletions

View File

@@ -43,16 +43,12 @@ class ModelManager:
self.requester_dict = {}
async def initialize(self):
self.requester_components = self.ap.discover.get_components_by_kind(
'LLMAPIRequester'
)
self.requester_components = self.ap.discover.get_components_by_kind('LLMAPIRequester')
# forge requester class dict
requester_dict: dict[str, type[requester.LLMAPIRequester]] = {}
for component in self.requester_components:
requester_dict[component.metadata.name] = (
component.get_python_component_class()
)
requester_dict[component.metadata.name] = component.get_python_component_class()
self.requester_dict = requester_dict
@@ -65,9 +61,7 @@ class ModelManager:
self.llm_models = []
# llm models
result = await self.ap.persistence_mgr.execute_async(
sqlalchemy.select(persistence_model.LLMModel)
)
result = await self.ap.persistence_mgr.execute_async(sqlalchemy.select(persistence_model.LLMModel))
llm_models = result.all()
@@ -77,9 +71,7 @@ class ModelManager:
async def load_llm_model(
self,
model_info: persistence_model.LLMModel
| sqlalchemy.Row[persistence_model.LLMModel]
| dict,
model_info: persistence_model.LLMModel | sqlalchemy.Row[persistence_model.LLMModel] | dict,
):
"""加载模型"""
@@ -88,9 +80,7 @@ class ModelManager:
elif isinstance(model_info, dict):
model_info = persistence_model.LLMModel(**model_info)
requester_inst = self.requester_dict[model_info.requester](
ap=self.ap, config=model_info.requester_config
)
requester_inst = self.requester_dict[model_info.requester](ap=self.ap, config=model_info.requester_config)
await requester_inst.initialize()
@@ -136,9 +126,7 @@ class ModelManager:
return component.to_plain_dict()
return None
def get_available_requester_manifest_by_name(
self, name: str
) -> engine.Component | None:
def get_available_requester_manifest_by_name(self, name: str) -> engine.Component | None:
"""通过名称获取请求器清单"""
for component in self.requester_components:
if component.metadata.name == name:

View File

@@ -73,9 +73,7 @@ class AnthropicMessages(requester.LLMAPIRequester):
if system_role_message:
messages.pop(i)
if isinstance(system_role_message, llm_entities.Message) and isinstance(
system_role_message.content, str
):
if isinstance(system_role_message, llm_entities.Message) and isinstance(system_role_message.content, str):
args['system'] = system_role_message.content
req_messages = []
@@ -106,9 +104,7 @@ class AnthropicMessages(requester.LLMAPIRequester):
elif isinstance(m.content, list):
for i, ce in enumerate(m.content):
if ce.type == 'image_base64':
image_b64, image_format = await image.extract_b64_and_format(
ce.image_base64
)
image_b64, image_format = await image.extract_b64_and_format(ce.image_base64)
alter_image_ele = {
'type': 'image',
@@ -156,9 +152,7 @@ class AnthropicMessages(requester.LLMAPIRequester):
for block in resp.content:
if block.type == 'thinking':
args['content'] = (
'<think>' + block.thinking + '</think>\n' + args['content']
)
args['content'] = '<think>' + block.thinking + '</think>\n' + args['content']
elif block.type == 'text':
args['content'] += block.text
elif block.type == 'tool_use':
@@ -166,9 +160,7 @@ class AnthropicMessages(requester.LLMAPIRequester):
tool_call = llm_entities.ToolCall(
id=block.id,
type='function',
function=llm_entities.FunctionCall(
name=block.name, arguments=json.dumps(block.input)
),
function=llm_entities.FunctionCall(name=block.name, arguments=json.dumps(block.input)),
)
if 'tool_calls' not in args:
args['tool_calls'] = []

View File

@@ -28,9 +28,7 @@ class OpenAIChatCompletions(requester.LLMAPIRequester):
api_key='',
base_url=self.requester_cfg['base_url'].replace(' ', ''),
timeout=self.requester_cfg['timeout'],
http_client=httpx.AsyncClient(
trust_env=True, timeout=self.requester_cfg['timeout']
),
http_client=httpx.AsyncClient(trust_env=True, timeout=self.requester_cfg['timeout']),
)
async def _req(
@@ -50,20 +48,11 @@ class OpenAIChatCompletions(requester.LLMAPIRequester):
if 'role' not in chatcmpl_message or chatcmpl_message['role'] is None:
chatcmpl_message['role'] = 'assistant'
reasoning_content = (
chatcmpl_message['reasoning_content']
if 'reasoning_content' in chatcmpl_message
else None
)
reasoning_content = chatcmpl_message['reasoning_content'] if 'reasoning_content' in chatcmpl_message else None
# deepseek的reasoner模型
if reasoning_content is not None:
chatcmpl_message['content'] = (
'<think>\n'
+ reasoning_content
+ '\n</think>\n'
+ chatcmpl_message['content']
)
chatcmpl_message['content'] = '<think>\n' + reasoning_content + '\n</think>\n' + chatcmpl_message['content']
message = llm_entities.Message(**chatcmpl_message)
@@ -124,10 +113,7 @@ class OpenAIChatCompletions(requester.LLMAPIRequester):
content = msg_dict.get('content')
if isinstance(content, list):
# 检查 content 列表中是否每个部分都是文本
if all(
isinstance(part, dict) and part.get('type') == 'text'
for part in content
):
if all(isinstance(part, dict) and part.get('type') == 'text' for part in content):
# 将所有文本部分合并为一个字符串
msg_dict['content'] = '\n'.join(part['text'] for part in content)
req_messages.append(msg_dict)

View File

@@ -1,23 +1,17 @@
from __future__ import annotations
import asyncio
import typing
import json
import base64
from typing import AsyncGenerator
import openai
import openai.types.chat.chat_completion as chat_completion
import openai.types.chat.chat_completion_message_tool_call as chat_completion_message_tool_call
import httpx
import aiohttp
import async_lru
from .. import entities, errors, requester
from ....core import entities as core_entities, app
from ... import entities as llm_entities
from ...tools import entities as tools_entities
from ....utils import image
class ModelScopeChatCompletions(requester.LLMAPIRequester):
@@ -33,26 +27,22 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
self.requester_cfg = self.ap.provider_cfg.data['requester']['modelscope-chat-completions']
async def initialize(self):
self.client = openai.AsyncClient(
api_key="",
api_key='',
base_url=self.requester_cfg['base-url'],
timeout=self.requester_cfg['timeout'],
http_client=httpx.AsyncClient(
trust_env=True,
timeout=self.requester_cfg['timeout']
)
http_client=httpx.AsyncClient(trust_env=True, timeout=self.requester_cfg['timeout']),
)
async def _req(
self,
args: dict,
) -> chat_completion.ChatCompletion:
args["stream"] = True
args['stream'] = True
chunk = None
pending_content = ""
pending_content = ''
tool_calls = []
@@ -74,7 +64,7 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
break
else:
tool_calls.append(tool_call)
if chunk.choices[0].finish_reason is not None:
break
@@ -82,36 +72,41 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
for tc in tool_calls:
function = chat_completion_message_tool_call.Function(
name=tc.function.name,
arguments=tc.function.arguments
name=tc.function.name, arguments=tc.function.arguments
)
real_tool_calls.append(chat_completion_message_tool_call.ChatCompletionMessageToolCall(
id=tc.id,
function=function,
type="function"
))
return chat_completion.ChatCompletion(
id=chunk.id,
object="chat.completion",
created=chunk.created,
choices=[
chat_completion.Choice(
index=0,
message=chat_completion.ChatCompletionMessage(
role="assistant",
content=pending_content,
tool_calls=real_tool_calls if len(real_tool_calls) > 0 else None
),
finish_reason=chunk.choices[0].finish_reason if hasattr(chunk.choices[0], 'finish_reason') and chunk.choices[0].finish_reason is not None else 'stop',
logprobs=chunk.choices[0].logprobs,
real_tool_calls.append(
chat_completion_message_tool_call.ChatCompletionMessageToolCall(
id=tc.id, function=function, type='function'
)
],
model=chunk.model,
service_tier=chunk.service_tier if hasattr(chunk, 'service_tier') else None,
system_fingerprint=chunk.system_fingerprint if hasattr(chunk, 'system_fingerprint') else None,
usage=chunk.usage if hasattr(chunk, 'usage') else None
) if chunk else None
)
return (
chat_completion.ChatCompletion(
id=chunk.id,
object='chat.completion',
created=chunk.created,
choices=[
chat_completion.Choice(
index=0,
message=chat_completion.ChatCompletionMessage(
role='assistant',
content=pending_content,
tool_calls=real_tool_calls if len(real_tool_calls) > 0 else None,
),
finish_reason=chunk.choices[0].finish_reason
if hasattr(chunk.choices[0], 'finish_reason') and chunk.choices[0].finish_reason is not None
else 'stop',
logprobs=chunk.choices[0].logprobs,
)
],
model=chunk.model,
service_tier=chunk.service_tier if hasattr(chunk, 'service_tier') else None,
system_fingerprint=chunk.system_fingerprint if hasattr(chunk, 'system_fingerprint') else None,
usage=chunk.usage if hasattr(chunk, 'usage') else None,
)
if chunk
else None
)
return await self.client.chat.completions.create(**args)
async def _make_msg(
@@ -138,29 +133,27 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
self.client.api_key = use_model.token_mgr.get_token()
args = self.requester_cfg['args'].copy()
args["model"] = use_model.name if use_model.model_name is None else use_model.model_name
args['model'] = use_model.name if use_model.model_name is None else use_model.model_name
if use_funcs:
tools = await self.ap.tool_mgr.generate_tools_for_openai(use_funcs)
if tools:
args["tools"] = tools
args['tools'] = tools
# 设置此次请求中的messages
messages = req_messages.copy()
# 检查vision
for msg in messages:
if 'content' in msg and isinstance(msg["content"], list):
for me in msg["content"]:
if me["type"] == "image_base64":
me["image_url"] = {
"url": me["image_base64"]
}
me["type"] = "image_url"
del me["image_base64"]
if 'content' in msg and isinstance(msg['content'], list):
for me in msg['content']:
if me['type'] == 'image_base64':
me['image_url'] = {'url': me['image_base64']}
me['type'] = 'image_url'
del me['image_base64']
args["messages"] = messages
args['messages'] = messages
# 发送请求
resp = await self._req(args)
@@ -180,12 +173,12 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
req_messages = [] # req_messages 仅用于类内,外部同步由 query.messages 进行
for m in messages:
msg_dict = m.dict(exclude_none=True)
content = msg_dict.get("content")
content = msg_dict.get('content')
if isinstance(content, list):
# 检查 content 列表中是否每个部分都是文本
if all(isinstance(part, dict) and part.get("type") == "text" for part in content):
if all(isinstance(part, dict) and part.get('type') == 'text' for part in content):
# 将所有文本部分合并为一个字符串
msg_dict["content"] = "\n".join(part["text"] for part in content)
msg_dict['content'] = '\n'.join(part['text'] for part in content)
req_messages.append(msg_dict)
try:
@@ -204,4 +197,4 @@ class ModelScopeChatCompletions(requester.LLMAPIRequester):
except openai.RateLimitError as e:
raise errors.RequesterError(f'请求过于频繁或余额不足: {e.message}')
except openai.APIError as e:
raise errors.RequesterError(f'请求错误: {e.message}')
raise errors.RequesterError(f'请求错误: {e.message}')

View File

@@ -61,13 +61,9 @@ class OllamaChatCompletions(requester.LLMAPIRequester):
msg['content'] = '\n'.join(text_content)
msg['images'] = [url.split(',')[1] for url in image_urls]
if (
'tool_calls' in msg
): # LangBot 内部以 str 存储 tool_calls 的参数,这里需要转换为 dict
if 'tool_calls' in msg: # LangBot 内部以 str 存储 tool_calls 的参数,这里需要转换为 dict
for tool_call in msg['tool_calls']:
tool_call['function']['arguments'] = json.loads(
tool_call['function']['arguments']
)
tool_call['function']['arguments'] = json.loads(tool_call['function']['arguments'])
args['messages'] = messages
args['tools'] = []
@@ -80,9 +76,7 @@ class OllamaChatCompletions(requester.LLMAPIRequester):
message: llm_entities.Message = await self._make_msg(resp)
return message
async def _make_msg(
self, chat_completions: ollama.ChatResponse
) -> llm_entities.Message:
async def _make_msg(self, chat_completions: ollama.ChatResponse) -> llm_entities.Message:
message: ollama.Message = chat_completions.message
if message is None:
raise ValueError("chat_completions must contain a 'message' field")
@@ -122,10 +116,7 @@ class OllamaChatCompletions(requester.LLMAPIRequester):
msg_dict: dict = m.dict(exclude_none=True)
content: Any = msg_dict.get('content')
if isinstance(content, list):
if all(
isinstance(part, dict) and part.get('type') == 'text'
for part in content
):
if all(isinstance(part, dict) and part.get('type') == 'text' for part in content):
msg_dict['content'] = '\n'.join(part['text'] for part in content)
req_messages.append(msg_dict)
try:

View File

@@ -1,12 +1,11 @@
from __future__ import annotations
import openai
from . import chatcmpl, modelscopechatcmpl
from .. import requester
from . import chatcmpl
from ....core import app
class PPIOChatCompletions(chatcmpl.OpenAIChatCompletions):
"""欧派云 ChatCompletion API 请求器"""
@@ -17,4 +16,4 @@ class PPIOChatCompletions(chatcmpl.OpenAIChatCompletions):
def __init__(self, ap: app.Application):
self.ap = ap
self.requester_cfg = self.ap.provider_cfg.data['requester']['ppio-chat-completions']
self.requester_cfg = self.ap.provider_cfg.data['requester']['ppio-chat-completions']