mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-04 23:17:20 +08:00
refactor: register protocol stream tasks
This commit is contained in:
@@ -40,6 +40,14 @@ def get_background_task_registry(
|
||||
return runtime.tasks
|
||||
|
||||
|
||||
def get_background_task_registry_compat(request: Request) -> TaskRegistry:
|
||||
"""返回协议兼容端点使用的任务登记器,允许未启动 lifespan 的旧调用回退。"""
|
||||
runtime = getattr(request.app.state, "host_runtime", None)
|
||||
if isinstance(runtime, HostRuntime):
|
||||
return runtime.tasks
|
||||
return get_task_registry()
|
||||
|
||||
|
||||
def resolve_background_task_registry(value: object) -> TaskRegistry:
|
||||
"""兼容直接调用 endpoint 的旧入口,并优先使用注入的任务登记器。"""
|
||||
if isinstance(value, TaskRegistry):
|
||||
|
||||
@@ -2,7 +2,7 @@ import asyncio
|
||||
import uuid
|
||||
from typing import AsyncIterator, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Header, Security
|
||||
from fastapi import APIRouter, Depends, Header, Security
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.schemas.openai import AnthropicErrorDetail as _SchemaAnthropicErrorDetail
|
||||
@@ -25,6 +25,11 @@ from app.api.presentation.sse import build_sse_response, encode_named_event
|
||||
from app.agent.runtime_loader import get_running_agent_manager
|
||||
from app.application.configuration import get_api_runtime_config_snapshot
|
||||
from app.adapters.web.security.access import anthropic_api_key_header
|
||||
from app.api.context import (
|
||||
get_background_task_registry_compat,
|
||||
resolve_background_task_registry,
|
||||
)
|
||||
from app.runtime.tasks import TaskRegistry
|
||||
|
||||
ANTHROPIC_ERROR_RESPONSES = {
|
||||
400: {"model": _SchemaAnthropicErrorResponse, "description": "请求格式错误"},
|
||||
@@ -88,6 +93,7 @@ async def _stream_anthropic_response(
|
||||
user_id: str,
|
||||
prompt: str,
|
||||
images: List[str],
|
||||
task_registry: TaskRegistry | None = None,
|
||||
) -> AsyncIterator[str]:
|
||||
event_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
@@ -113,7 +119,10 @@ async def _stream_anthropic_response(
|
||||
finally:
|
||||
await event_queue.put(None)
|
||||
|
||||
task = asyncio.create_task(_run_agent())
|
||||
task = resolve_background_task_registry(task_registry).create(
|
||||
_run_agent(),
|
||||
owner="api.anthropic.stream",
|
||||
)
|
||||
try:
|
||||
yield encode_named_event(
|
||||
"message_start",
|
||||
@@ -207,6 +216,7 @@ async def messages(
|
||||
payload: _SchemaAnthropicMessagesRequest,
|
||||
x_api_key: Optional[str] = Security(anthropic_api_key_header),
|
||||
anthropic_version: Optional[str] = Header(default=None, alias="anthropic-version"),
|
||||
task_registry: TaskRegistry = Depends(get_background_task_registry_compat),
|
||||
):
|
||||
auth_error = _check_auth(x_api_key)
|
||||
if auth_error:
|
||||
@@ -242,6 +252,7 @@ async def messages(
|
||||
user_id=session_id,
|
||||
prompt=prompt,
|
||||
images=images,
|
||||
task_registry=task_registry,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from threading import Lock
|
||||
from typing import AsyncIterator, List, Optional, Tuple
|
||||
|
||||
from fastapi import APIRouter, Request, Security
|
||||
from fastapi import APIRouter, Depends, Request, Security
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.security import HTTPAuthorizationCredentials
|
||||
|
||||
@@ -34,6 +34,11 @@ from app.agent.contracts import ReplyMode
|
||||
from app.application.configuration import get_api_runtime_config_snapshot
|
||||
from app.adapters.web.security.access import openai_bearer_scheme
|
||||
from app.schemas.types import NotificationChannel
|
||||
from app.api.context import (
|
||||
get_background_task_registry_compat,
|
||||
resolve_background_task_registry,
|
||||
)
|
||||
from app.runtime.tasks import TaskRegistry
|
||||
|
||||
OPENAI_ERROR_RESPONSES = {
|
||||
400: {"model": _SchemaOpenAIErrorResponse, "description": "请求格式错误"},
|
||||
@@ -228,6 +233,7 @@ async def _stream_response(
|
||||
prompt: str,
|
||||
images: List[str],
|
||||
cleanup_session: bool,
|
||||
task_registry: TaskRegistry | None = None,
|
||||
) -> AsyncIterator[str]:
|
||||
event_queue: asyncio.Queue = asyncio.Queue()
|
||||
|
||||
@@ -255,7 +261,10 @@ async def _stream_response(
|
||||
finally:
|
||||
await event_queue.put(None)
|
||||
|
||||
task = asyncio.create_task(_run_agent())
|
||||
task = resolve_background_task_registry(task_registry).create(
|
||||
_run_agent(),
|
||||
owner="api.openai.stream",
|
||||
)
|
||||
|
||||
try:
|
||||
yield _sse_payload(
|
||||
@@ -488,6 +497,7 @@ async def _chat_completions_impl(
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Security(
|
||||
openai_bearer_scheme
|
||||
),
|
||||
task_registry: TaskRegistry | None = None,
|
||||
):
|
||||
auth_error = _check_auth(credentials)
|
||||
if auth_error:
|
||||
@@ -545,6 +555,7 @@ async def _chat_completions_impl(
|
||||
prompt=prompt,
|
||||
images=images,
|
||||
cleanup_session=not use_server_session,
|
||||
task_registry=task_registry,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -684,9 +695,15 @@ async def chat_completions(
|
||||
payload: _SchemaOpenAIChatCompletionsRequest,
|
||||
request: Request,
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Security(openai_bearer_scheme),
|
||||
task_registry: TaskRegistry = Depends(get_background_task_registry_compat),
|
||||
):
|
||||
"""OpenAI Chat Completions 兼容公开入口。"""
|
||||
return await _chat_completions_impl(payload, request, credentials)
|
||||
return await _chat_completions_impl(
|
||||
payload,
|
||||
request,
|
||||
credentials,
|
||||
task_registry=task_registry,
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
|
||||
Reference in New Issue
Block a user