87 lines
3.3 KiB
Python
87 lines
3.3 KiB
Python
from typing import Literal
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class SourceReference(BaseModel):
|
|
"""Reference to a source artifact chunk used in RAG response."""
|
|
|
|
artifact_file: str = Field(..., description="Path to the YAML artifact file")
|
|
source_file: str = Field(..., description="Path to the source code file")
|
|
chunk_type: str = Field(..., description="Type of chunk (factual_summary, interpretive_summary, method, invariants)")
|
|
relevance_score: float = Field(..., description="Similarity score from FAISS search")
|
|
|
|
|
|
class ChatRequest(BaseModel):
|
|
"""Request model for the /chat endpoint."""
|
|
|
|
message: str = Field(..., description="The user's message")
|
|
conversation_id: str | None = Field(
|
|
default=None, description="Optional conversation ID for continuity"
|
|
)
|
|
|
|
|
|
class ChatResponse(BaseModel):
|
|
"""Response model for the /chat endpoint."""
|
|
|
|
conversation_id: str = Field(..., description="Conversation ID (generated if not provided)")
|
|
response: str = Field(..., description="The LLM's response")
|
|
mode: Literal["local", "remote", "openai", "asksage"] = Field(..., description="Which adapter was used")
|
|
intent: Literal["codebase", "general", "clarification"] = Field(
|
|
default="general", description="Classified intent of the user message"
|
|
)
|
|
sources: list[SourceReference] = Field(default_factory=list, description="Source artifact references used in response")
|
|
|
|
|
|
class HealthResponse(BaseModel):
|
|
"""Response model for the /health endpoint."""
|
|
|
|
status: str = Field(default="ok")
|
|
faiss_loaded: bool = Field(default=False, description="Whether FAISS index is loaded")
|
|
index_size: int = Field(default=0, description="Number of chunks in FAISS index")
|
|
|
|
|
|
class ErrorResponse(BaseModel):
|
|
"""Standard error response model."""
|
|
|
|
detail: str = Field(..., description="Error description")
|
|
|
|
|
|
# --- SSE Streaming Event Models ---
|
|
|
|
|
|
class StreamChunkEvent(BaseModel):
|
|
"""SSE event for content chunks during streaming."""
|
|
|
|
type: Literal["chunk"] = "chunk"
|
|
content: str = Field(..., description="Content chunk from the LLM")
|
|
conversation_id: str = Field(..., description="Conversation ID")
|
|
|
|
|
|
class StreamDoneEvent(BaseModel):
|
|
"""SSE event signaling completion of streaming."""
|
|
|
|
type: Literal["done"] = "done"
|
|
conversation_id: str = Field(..., description="Conversation ID")
|
|
mode: Literal["local", "remote", "openai", "asksage"] = Field(..., description="Which adapter was used")
|
|
intent: Literal["codebase", "general", "clarification"] = Field(
|
|
default="general", description="Classified intent of the user message"
|
|
)
|
|
sources: list[SourceReference] = Field(default_factory=list, description="Source artifact references used in response")
|
|
|
|
|
|
class IndexResponse(BaseModel):
|
|
"""Response model for the /index endpoint."""
|
|
|
|
status: str = Field(..., description="Indexing status")
|
|
chunks_indexed: int = Field(default=0, description="Number of chunks indexed")
|
|
artifacts_processed: int = Field(default=0, description="Number of YAML files processed")
|
|
|
|
|
|
class StreamErrorEvent(BaseModel):
|
|
"""SSE event for errors during streaming."""
|
|
|
|
type: Literal["error"] = "error"
|
|
message: str = Field(..., description="Error message")
|
|
code: int = Field(default=500, description="HTTP status code")
|