refactor: register protocol stream tasks

This commit is contained in:
jxxghp
2026-08-23 15:13:05 +08:00
parent e7e232d625
commit 7afabeda02
6 changed files with 150 additions and 9 deletions
+8
View File
@@ -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):
+13 -2
View File
@@ -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,
),
)
+20 -3
View File
@@ -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(