from dataclasses import dataclass, field from typing import List, Optional, Dict, Any, Union @dataclass class SearchResponse: url: str title: str snippet: str cite_index: Optional[int] = None published_at: Optional[Any] = None site_name: Optional[Any] = None site_icon: str = "" @dataclass class ChatSession: id: str seq_id: int title: Optional[str] title_type: Optional[str] updated_at: float agent: str version: int current_message_id: Optional[int] inserted_at: float character: Optional[str] = None @staticmethod def from_dict(data: Dict[str, Any]) -> 'ChatSession': return ChatSession( id=data.get('id', ''), seq_id=data.get('seq_id', 0), title=data.get('title'), title_type=data.get('title_type'), updated_at=data.get('updated_at', 0), agent=data.get('agent', ''), version=data.get('version', 0), current_message_id=data.get('current_message_id'), inserted_at=data.get('inserted_at', 0), character=data.get('character'), ) @dataclass class ChatMessage: message_id: int parent_id: Optional[int] model: str role: str content: str thinking_enabled: bool thinking_content: Optional[str] thinking_elapsed_secs: Optional[int] ban_edit: bool ban_regenerate: bool status: str accumulated_token_usage: int files: List[Any] = field(default_factory=list) tips: List[Any] = field(default_factory=list) inserted_at: float = 0.0 search_enabled: bool = False search_status: Optional[str] = None search_results: List[SearchResponse] = field(default_factory=list) @dataclass class ChatHistory: chat_session: ChatSession chat_messages: List[ChatMessage] cache_valid: bool route_id: Optional[Any] @dataclass class PowChallenge: algorithm: str challenge: str salt: str signature: str target_path: str expire_at: int = 0 @dataclass class CompletionData: chat_session_id: str prompt: str thinking_enabled: bool = False search_enabled: bool = False parent_message_id: Optional[int] = None ref_file_ids: List[str] = field(default_factory=list) def to_dict(self) -> Dict[str, Any]: data = { 'chat_session_id': self.chat_session_id, 'prompt': self.prompt, 'thinking_enabled': self.thinking_enabled, 'search_enabled': self.search_enabled, 'ref_file_ids': self.ref_file_ids, } if self.parent_message_id is not None: data['parent_message_id'] = self.parent_message_id else: data['parent_message_id'] = None return data # Response wrappers for API @dataclass class AuthResponse: code: int msg: str data: Dict[str, Any] @dataclass class ChatCreateResponse: code: int msg: str data: Dict[str, Any] @dataclass class ChatEditResponse: code: int msg: str data: Dict[str, Any] @dataclass class NullResponse: code: int msg: str data: Dict[str, Any] @dataclass class ProfileResponse: code: int msg: str data: Dict[str, Any] @dataclass class QuotaResponse: code: int msg: str data: Dict[str, Any]