138 lines
4.7 KiB
Python
138 lines
4.7 KiB
Python
"""聊天 API。"""
|
|
|
|
from fastapi import APIRouter, Depends, Header, Query, Request, Response, status
|
|
|
|
from app.api.v1.deps import get_current_user
|
|
from app.schemas.auth import CurrentUser
|
|
from app.schemas.chat import (
|
|
ChatMessageListResponse,
|
|
ChatMessageResponse,
|
|
ChatSessionListResponse,
|
|
ChatSessionResponse,
|
|
CreateSessionRequest,
|
|
SelectVersionRequest,
|
|
SendMessageRequest,
|
|
SendMessageResponse,
|
|
UpdateSessionRequest,
|
|
)
|
|
from app.services.chat import (
|
|
create_session,
|
|
delete_session,
|
|
get_session_response,
|
|
list_message_responses,
|
|
list_session_responses,
|
|
select_message_version,
|
|
send_message,
|
|
update_session_response,
|
|
)
|
|
from app.services.idempotency import run_idempotent
|
|
|
|
router = APIRouter(prefix="/chat", tags=["chat"])
|
|
|
|
|
|
@router.post("/sessions", response_model=ChatSessionResponse)
|
|
async def create_chat_session(
|
|
payload: CreateSessionRequest,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> ChatSessionResponse:
|
|
return await create_session(payload, owner_scope=current_user.owner_scope)
|
|
|
|
|
|
@router.get("/sessions", response_model=ChatSessionListResponse)
|
|
async def list_chat_sessions(
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
status: str | None = Query(default=None, description="按状态过滤:active / archived"),
|
|
limit: int = Query(default=50, ge=1, le=100),
|
|
offset: int = Query(default=0, ge=0),
|
|
) -> ChatSessionListResponse:
|
|
return await list_session_responses(
|
|
owner_scope=current_user.owner_scope, status=status, limit=limit, offset=offset
|
|
)
|
|
|
|
|
|
@router.get("/sessions/{session_id}", response_model=ChatSessionResponse)
|
|
async def get_chat_session(
|
|
session_id: str,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> ChatSessionResponse:
|
|
return await get_session_response(session_id, owner_scope=current_user.owner_scope)
|
|
|
|
|
|
@router.patch("/sessions/{session_id}", response_model=ChatSessionResponse)
|
|
async def update_chat_session(
|
|
session_id: str,
|
|
payload: UpdateSessionRequest,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> ChatSessionResponse:
|
|
return await update_session_response(session_id, payload, owner_scope=current_user.owner_scope)
|
|
|
|
|
|
@router.delete("/sessions/{session_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_chat_session(
|
|
session_id: str,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> Response:
|
|
await delete_session(session_id, owner_scope=current_user.owner_scope)
|
|
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
|
|
|
|
|
@router.post("/sessions/{session_id}/messages", response_model=SendMessageResponse)
|
|
async def send_chat_message(
|
|
session_id: str,
|
|
payload: SendMessageRequest,
|
|
request: Request,
|
|
idempotency_key: str | None = Header(default=None, alias="Idempotency-Key"),
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> SendMessageResponse:
|
|
return await run_idempotent(
|
|
key=idempotency_key,
|
|
method="POST",
|
|
path=str(request.url.path),
|
|
payload=payload,
|
|
response_type=SendMessageResponse,
|
|
resource_type="run",
|
|
handler=lambda session: send_message(
|
|
session,
|
|
session_id,
|
|
payload,
|
|
owner_scope=current_user.owner_scope,
|
|
tool_runtime=getattr(request.app.state, "tool_runtime", None),
|
|
confirmation_registry=getattr(request.app.state, "confirmation_registry", None),
|
|
confirmation_store=getattr(request.app.state, "confirmation_store", None),
|
|
event_store=getattr(request.app.state, "event_store", None),
|
|
agent_run_registry=getattr(request.app.state, "agent_run_registry", None),
|
|
python_skill_catalog=getattr(request.app.state, "python_skill_catalog", None),
|
|
),
|
|
)
|
|
|
|
|
|
@router.get("/sessions/{session_id}/messages", response_model=ChatMessageListResponse)
|
|
async def list_chat_messages(
|
|
session_id: str,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
limit: int = Query(default=100, ge=1, le=200),
|
|
offset: int = Query(default=0, ge=0),
|
|
) -> ChatMessageListResponse:
|
|
return await list_message_responses(
|
|
session_id, owner_scope=current_user.owner_scope, limit=limit, offset=offset
|
|
)
|
|
|
|
|
|
@router.patch(
|
|
"/sessions/{session_id}/messages/{message_id}/version",
|
|
response_model=ChatMessageResponse,
|
|
)
|
|
async def select_message_version_endpoint(
|
|
session_id: str,
|
|
message_id: str,
|
|
payload: SelectVersionRequest,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> ChatMessageResponse:
|
|
"""选择/激活消息的某个历史版本。"""
|
|
return await select_message_version(
|
|
session_id,
|
|
message_id,
|
|
payload,
|
|
owner_scope=current_user.owner_scope,
|
|
)
|