mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-01 12:56:34 +08:00
refactor(types): align openai with typed route contracts
This commit is contained in:
@@ -42,7 +42,7 @@ from app.schemas.openai import OpenAIResponsesResponse as _SchemaOpenAIResponses
|
||||
from app.schemas.openai import OpenAIUsage as _SchemaOpenAIUsage
|
||||
from app.schemas.types import NotificationChannel
|
||||
|
||||
OPENAI_ERROR_RESPONSES = {
|
||||
OPENAI_ERROR_RESPONSES: dict[int | str, dict[str, object]] = {
|
||||
400: {"model": _SchemaOpenAIErrorResponse, "description": "请求格式错误"},
|
||||
401: {"model": _SchemaOpenAIErrorResponse, "description": "认证失败"},
|
||||
422: {"model": _SchemaOpenAIErrorResponse, "description": "请求参数校验失败"},
|
||||
@@ -62,6 +62,7 @@ class _CollectingMoviePilotAgentMixin:
|
||||
"""
|
||||
|
||||
def __init__(self, *args, stream_mode: bool = False, **kwargs):
|
||||
"""初始化协议 Agent 的消息收集与流式模式。"""
|
||||
super().__init__(*args, **kwargs)
|
||||
self.collected_messages: List[str] = []
|
||||
self.stream_mode = stream_mode
|
||||
@@ -69,6 +70,7 @@ class _CollectingMoviePilotAgentMixin:
|
||||
self.stream_handler = _get_openai_streaming_handler_type()()
|
||||
|
||||
def _should_stream(self) -> bool:
|
||||
"""返回当前请求是否启用流式输出。"""
|
||||
return self.stream_mode
|
||||
|
||||
def configure_protocol_request(
|
||||
@@ -99,6 +101,7 @@ class _CollectingMoviePilotAgentMixin:
|
||||
self.stream_handler.unbind_queue(event_queue)
|
||||
|
||||
async def send_agent_message(self, message: str, title: str = ""):
|
||||
"""收集 Agent 消息并按请求模式输出。"""
|
||||
text = (message or "").strip()
|
||||
if title and text:
|
||||
text = f"{title}\n{text}"
|
||||
@@ -116,6 +119,7 @@ class _OpenAIStreamingHandlerMixin:
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化流式事件队列绑定。"""
|
||||
super().__init__()
|
||||
self._event_queue: Optional[asyncio.Queue] = None
|
||||
|
||||
@@ -129,6 +133,7 @@ class _OpenAIStreamingHandlerMixin:
|
||||
self._event_queue = None
|
||||
|
||||
def emit(self, token: str):
|
||||
"""发送已整理的流式文本到请求事件队列。"""
|
||||
emitted = super().emit(token)
|
||||
if emitted and self._event_queue is not None:
|
||||
self._event_queue.put_nowait(emitted)
|
||||
@@ -141,6 +146,7 @@ class _OpenAIStreamingHandlerMixin:
|
||||
return emitted
|
||||
|
||||
def flush_pending_tool_summary(self) -> str:
|
||||
"""结算待发送的工具摘要并写入事件队列。"""
|
||||
emitted = super().flush_pending_tool_summary()
|
||||
if emitted and self._event_queue is not None:
|
||||
self._event_queue.put_nowait(emitted)
|
||||
@@ -156,6 +162,7 @@ class _OpenAIStreamingHandlerMixin:
|
||||
original_chat_id: Optional[str] = None,
|
||||
title: str = "",
|
||||
):
|
||||
"""绑定当前请求的渠道信息并启用流式输出。"""
|
||||
self._channel = channel
|
||||
self._source = source
|
||||
self._user_id = user_id
|
||||
@@ -170,6 +177,7 @@ class _OpenAIStreamingHandlerMixin:
|
||||
self._max_message_length = 0
|
||||
|
||||
async def stop_streaming(self) -> Tuple[bool, str]:
|
||||
"""结束流式输出并返回最终文本。"""
|
||||
if not self._streaming_enabled:
|
||||
return False, ""
|
||||
self._streaming_enabled = False
|
||||
@@ -244,6 +252,7 @@ async def _stream_response(
|
||||
cleanup_session: bool,
|
||||
task_registry: TaskRegistry | None = None,
|
||||
) -> AsyncIterator[str]:
|
||||
"""把受管 Agent 事件转换为 OpenAI 流式响应。"""
|
||||
event_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
created = int(time.time())
|
||||
@@ -251,6 +260,7 @@ async def _stream_response(
|
||||
finished = False
|
||||
|
||||
async def _run_agent():
|
||||
"""运行受管 Agent 并把完成或异常结果送入响应队列。"""
|
||||
try:
|
||||
await _run_managed_agent(
|
||||
manager=manager,
|
||||
@@ -409,6 +419,7 @@ async def _run_managed_agent(
|
||||
agent_holder = {}
|
||||
|
||||
def configure_agent(agent) -> None:
|
||||
"""为请求绑定协议模式和流式事件队列。"""
|
||||
agent.configure_protocol_request(
|
||||
stream_mode=stream_mode,
|
||||
event_queue=event_queue,
|
||||
@@ -445,6 +456,7 @@ def _error_response(
|
||||
error_type: str = "invalid_request_error",
|
||||
code: Optional[str] = None,
|
||||
) -> JSONResponse:
|
||||
"""构造 OpenAI 协议格式的错误响应。"""
|
||||
return JSONResponse(
|
||||
status_code=status_code,
|
||||
content=_SchemaOpenAIErrorResponse(
|
||||
@@ -505,6 +517,7 @@ async def list_models(
|
||||
openai_bearer_scheme
|
||||
),
|
||||
):
|
||||
"""校验凭据并返回当前可用的兼容模型。"""
|
||||
auth_error = await _check_auth(credentials)
|
||||
if auth_error:
|
||||
return auth_error
|
||||
@@ -522,6 +535,7 @@ async def _chat_completions_impl(
|
||||
),
|
||||
task_registry: TaskRegistry | None = None,
|
||||
):
|
||||
"""校验并执行 OpenAI Chat Completions 请求。"""
|
||||
auth_error = await _check_auth(credentials)
|
||||
if auth_error:
|
||||
return auth_error
|
||||
@@ -619,6 +633,7 @@ async def _responses_impl(
|
||||
openai_bearer_scheme
|
||||
),
|
||||
):
|
||||
"""校验并执行 OpenAI Responses 请求。"""
|
||||
auth_error = await _check_auth(credentials)
|
||||
if auth_error:
|
||||
return auth_error
|
||||
|
||||
Reference in New Issue
Block a user