Spaces:
Sleeping
Sleeping
| """ | |
| Chat Sessions API | |
| チャット履歴管理用のAPIエンドポイント | |
| """ | |
| from fastapi import APIRouter, HTTPException | |
| from pydantic import BaseModel | |
| from typing import List, Optional | |
| from datetime import datetime | |
| import json | |
| import os | |
| from pathlib import Path | |
| import uuid | |
| router = APIRouter() | |
| # チャットセッションの保存先 | |
| SESSIONS_DIR = Path("chat_sessions") | |
| SESSIONS_DIR.mkdir(exist_ok=True) | |
| SESSIONS_FILE = SESSIONS_DIR / "sessions.json" | |
| class ChatMessage(BaseModel): | |
| """チャットメッセージ""" | |
| role: str # "user" or "assistant" | |
| content: str | |
| timestamp: str | |
| class ChatSession(BaseModel): | |
| """チャットセッション""" | |
| session_id: str | |
| title: str | |
| created_at: str | |
| updated_at: str | |
| domain_id: str | |
| model_id: Optional[str] = None | |
| messages: List[ChatMessage] = [] | |
| class CreateSessionRequest(BaseModel): | |
| """新規セッション作成リクエスト""" | |
| title: Optional[str] = None | |
| domain_id: str = "general" | |
| model_id: Optional[str] = None | |
| class UpdateSessionRequest(BaseModel): | |
| """セッション更新リクエスト""" | |
| title: Optional[str] = None | |
| def load_sessions() -> List[ChatSession]: | |
| """セッション一覧をロード""" | |
| if not SESSIONS_FILE.exists(): | |
| return [] | |
| try: | |
| with open(SESSIONS_FILE, 'r', encoding='utf-8') as f: | |
| data = json.load(f) | |
| return [ChatSession(**session) for session in data] | |
| except Exception as e: | |
| print(f"Error loading sessions: {e}") | |
| return [] | |
| def save_sessions(sessions: List[ChatSession]): | |
| """セッション一覧を保存""" | |
| try: | |
| with open(SESSIONS_FILE, 'w', encoding='utf-8') as f: | |
| json.dump([session.model_dump() for session in sessions], f, indent=2, ensure_ascii=False) | |
| except Exception as e: | |
| print(f"Error saving sessions: {e}") | |
| raise HTTPException(status_code=500, detail=f"Failed to save sessions: {str(e)}") | |
| def generate_title_from_message(message: str) -> str: | |
| """メッセージから自動でタイトルを生成""" | |
| # 最初の50文字を取得 | |
| title = message[:50] | |
| if len(message) > 50: | |
| title += "..." | |
| return title | |
| async def list_sessions(): | |
| """ | |
| チャットセッション一覧を取得 | |
| """ | |
| sessions = load_sessions() | |
| # 更新日時の降順でソート | |
| sessions.sort(key=lambda x: x.updated_at, reverse=True) | |
| return sessions | |
| async def create_session(request: CreateSessionRequest): | |
| """ | |
| 新規チャットセッションを作成 | |
| """ | |
| session_id = f"session_{uuid.uuid4().hex[:12]}" | |
| now = datetime.now().isoformat() | |
| # タイトルが指定されていない場合はデフォルトタイトル | |
| title = request.title or f"新しいチャット - {datetime.now().strftime('%Y/%m/%d %H:%M')}" | |
| new_session = ChatSession( | |
| session_id=session_id, | |
| title=title, | |
| created_at=now, | |
| updated_at=now, | |
| domain_id=request.domain_id, | |
| model_id=request.model_id, | |
| messages=[] | |
| ) | |
| sessions = load_sessions() | |
| sessions.append(new_session) | |
| save_sessions(sessions) | |
| return new_session | |
| async def get_session(session_id: str): | |
| """ | |
| 特定のチャットセッションを取得 | |
| """ | |
| sessions = load_sessions() | |
| for session in sessions: | |
| if session.session_id == session_id: | |
| return session | |
| raise HTTPException(status_code=404, detail="Session not found") | |
| async def update_session(session_id: str, request: UpdateSessionRequest): | |
| """ | |
| チャットセッションを更新(タイトル変更など) | |
| """ | |
| sessions = load_sessions() | |
| for i, session in enumerate(sessions): | |
| if session.session_id == session_id: | |
| if request.title: | |
| sessions[i].title = request.title | |
| sessions[i].updated_at = datetime.now().isoformat() | |
| save_sessions(sessions) | |
| return sessions[i] | |
| raise HTTPException(status_code=404, detail="Session not found") | |
| async def delete_session(session_id: str): | |
| """ | |
| チャットセッションを削除 | |
| """ | |
| sessions = load_sessions() | |
| for i, session in enumerate(sessions): | |
| if session.session_id == session_id: | |
| del sessions[i] | |
| save_sessions(sessions) | |
| return {"message": "Session deleted successfully"} | |
| raise HTTPException(status_code=404, detail="Session not found") | |
| async def add_message(session_id: str, message: ChatMessage): | |
| """ | |
| セッションにメッセージを追加 | |
| """ | |
| sessions = load_sessions() | |
| for i, session in enumerate(sessions): | |
| if session.session_id == session_id: | |
| sessions[i].messages.append(message) | |
| sessions[i].updated_at = datetime.now().isoformat() | |
| # 最初のユーザーメッセージの場合、自動でタイトルを生成 | |
| if len(sessions[i].messages) == 1 and message.role == "user": | |
| if sessions[i].title.startswith("新しいチャット"): | |
| sessions[i].title = generate_title_from_message(message.content) | |
| save_sessions(sessions) | |
| return {"message": "Message added successfully"} | |
| raise HTTPException(status_code=404, detail="Session not found") | |