Spaces:
Running
Running
File size: 3,557 Bytes
79860d3 5d29fbb 77d1b2b f44d1e5 79860d3 d807ca2 79860d3 d807ca2 79860d3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | """
api_models.py
-------------
Pydantic models for API request/response bodies (chat, indexing, logs).
"""
from __future__ import annotations
from typing import Optional, Any
from pydantic import BaseModel
# ---------------------------------------------------------------------------
# Chat
# ---------------------------------------------------------------------------
class ChatMessage(BaseModel):
role: str # "user" | "assistant" | "system"
content: str
class ChatRequest(BaseModel):
message: str
history: list[ChatMessage] = []
session_id: str = ""
class TokenUsage(BaseModel):
"""Token consumption for a single chat turn (all LLM calls combined)."""
prompt_tokens: int = 0
completion_tokens: int = 0
total_tokens: int = 0
call_count: int = 0 # number of separate LLM API calls in this turn
class ChatResponse(BaseModel):
answer: str
followups: list[str] = []
session_id: str = ""
tokens_used: TokenUsage = TokenUsage()
history_trimmed: bool = False # True when earlier messages were dropped per profile limit
warming_up: bool = False # True when the profile index is still building after restart
latency_ms: int = 0 # Wall-clock time for this turn (ms); 0 when warming up
# ---------------------------------------------------------------------------
# Indexing
# ---------------------------------------------------------------------------
class IndexStatusResponse(BaseModel):
slug: str
status: str # "not_indexed" | "success" | "running" | "failed" | "empty"
chunk_count: int = 0
document_count: int = 0
last_indexed: Optional[str] = None
duration_seconds: Optional[float] = None
last_error: Optional[str] = None
class IndexHistoryEntry(BaseModel):
timestamp: str
profile_slug: str
status: str
document_count: int = 0
duration_seconds: float = 0.0
error: Optional[str] = None
# ---------------------------------------------------------------------------
# Prompts
# ---------------------------------------------------------------------------
class PromptEntry(BaseModel):
name: str
short_name: str
content: str
class PromptsResponse(BaseModel):
prompts: dict[str, PromptEntry]
is_default: bool = False
class UpdatePromptRequest(BaseModel):
short_name: str
content: str
# ---------------------------------------------------------------------------
# Documents
# ---------------------------------------------------------------------------
class DocumentInfo(BaseModel):
filename: str
size_bytes: int
uploaded_at: Optional[str] = None
class DocumentListResponse(BaseModel):
slug: str
documents: list[DocumentInfo]
# ---------------------------------------------------------------------------
# Logs
# ---------------------------------------------------------------------------
class LogEntry(BaseModel):
line: str
class LogsResponse(BaseModel):
slug: Optional[str]
log_type: str # "app" | "indexing" | "chat" | "profile"
lines: list[str]
total_lines: int
# ---------------------------------------------------------------------------
# Generic
# ---------------------------------------------------------------------------
class SuccessResponse(BaseModel):
success: bool = True
message: str = "OK"
class ErrorResponse(BaseModel):
success: bool = False
error: str
detail: Optional[Any] = None
|