refactor(types): align openai with typed route contracts

This commit is contained in:
jxxghp
2026-10-17 02:59:25 +08:00
parent 193c25f2aa
commit 0c8b9feaf8

View File

@@ -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