xtc-backend / app /api /sessions.py
a3216's picture
deploy: initial release to Hugging Face Spaces
36fae79
Raw
History Blame Contribute Delete
4.03 kB
"""会话持久化 API:/v1/xtc/sessions
- POST /v1/xtc/sessions 创建会话
- GET /v1/xtc/sessions 列出我的会话
- GET /v1/xtc/sessions/{id} 获取会话详情
- PUT /v1/xtc/sessions/{id} 更新(标题)
- DELETE /v1/xtc/sessions/{id} 删除
- POST /v1/xtc/sessions/{id}/messages 追加消息
- GET /v1/xtc/sessions/{id}/messages 列出消息
"""
from __future__ import annotations
from typing import Optional
from fastapi import APIRouter, Body, Depends, Query, Request
from ..auth import require_access_key
from ..errors import HttpError
from ..services import session_store
from ._common import ok_with_cors
router = APIRouter(prefix="/v1/xtc/sessions", tags=["sessions"])
@router.post("")
async def create_session(
body: dict = Body(default={}),
access_key: str = Depends(require_access_key),
):
sess = session_store.create_session(
access_key=access_key,
title=body.get("title"),
provider=body.get("provider"),
model=body.get("model"),
)
return ok_with_cors({"session": sess})
@router.get("")
async def list_sessions(
access_key: str = Depends(require_access_key),
limit: int = Query(default=50, ge=1, le=200),
offset: int = Query(default=0, ge=0),
):
items = session_store.list_sessions(access_key=access_key, limit=limit, offset=offset)
return ok_with_cors({"items": items, "count": len(items)})
@router.get("/{session_id}")
async def get_session(
session_id: str,
access_key: str = Depends(require_access_key),
):
sess = session_store.get_session(session_id, access_key=access_key)
if not sess:
raise HttpError(f"session not found: {session_id}", status=404, code="not_found")
return ok_with_cors({"session": sess})
@router.put("/{session_id}")
async def update_session(
session_id: str,
body: dict = Body(default={}),
access_key: str = Depends(require_access_key),
):
sess = session_store.update_session(
session_id, title=body.get("title"), access_key=access_key
)
if not sess:
raise HttpError(f"session not found: {session_id}", status=404, code="not_found")
return ok_with_cors({"session": sess})
@router.delete("/{session_id}")
async def delete_session(
session_id: str,
access_key: str = Depends(require_access_key),
):
ok = session_store.delete_session(session_id, access_key=access_key)
if not ok:
raise HttpError(f"session not found: {session_id}", status=404, code="not_found")
return ok_with_cors({"deleted": True, "id": session_id})
@router.post("/{session_id}/messages")
async def append_message(
session_id: str,
body: dict = Body(default={}),
access_key: str = Depends(require_access_key),
):
if not session_store.get_session(session_id, access_key=access_key):
raise HttpError(f"session not found: {session_id}", status=404, code="not_found")
role = body.get("role") or "user"
if role not in ("user", "assistant", "system"):
raise HttpError("role must be user/assistant/system", status=400, code="bad_request")
content = body.get("content")
if content is None:
raise HttpError("content is required", status=400, code="bad_request")
msg = session_store.append_message(
session_id=session_id,
role=role,
content=str(content),
thought=body.get("thought"),
provider=body.get("provider"),
model=body.get("model"),
file_keys=body.get("file_keys"),
)
return ok_with_cors({"message": msg})
@router.get("/{session_id}/messages")
async def list_messages(
session_id: str,
access_key: str = Depends(require_access_key),
):
if not session_store.get_session(session_id, access_key=access_key):
raise HttpError(f"session not found: {session_id}", status=404, code="not_found")
msgs = session_store.list_messages(session_id)
return ok_with_cors({"messages": msgs or [], "count": len(msgs or [])})