from pydantic import BaseModel, Field class QueryRequest(BaseModel): text: str = Field(..., description="Вопрос от лица пациента") top_k: int = Field(5, ge=1, le=20, description="Количество чанков для retrieval") document_ids: list[str] | None = Field(None, description="Ограничить поиск конкретными документами") temperature: float | None = Field(None, ge=0.0, le=2.0) max_tokens: int | None = Field(None, ge=100, le=8000) intent_code: str | None = Field(None, description="Код ветки, чей промпт и подписки использовать. По умолчанию — _debug (страница Отладки).") system_prompt: str | None = Field(None, description="Если задан — используется как системный промпт вместо активного конфига ветки. Для тестирования черновика из textarea Настроек.") disable_rag: bool = Field(False, description="Если true — retrieval пропускается, чанки не подмешиваются. Для тестирования веток без RAG (например, _router).") class ChatRequest(BaseModel): text: str = Field(..., description="Реплика пациента") thread_id: int | None = Field(None, description="ID треда; если не передан — создаётся новый") top_k: int = Field(5, ge=1, le=20) temperature: float | None = Field(None, ge=0.0, le=2.0) max_tokens: int | None = Field(None, ge=100, le=8000) class ThreadRenameRequest(BaseModel): name: str = Field(..., min_length=1, max_length=200) class AgentConfigCreateRequest(BaseModel): intent_id: int = Field(..., description="ID ветки (intent), к которой относится конфиг") system_prompt: str = Field(..., min_length=1) rules_text: str = Field("", description="Правила в свободной markdown-форме") exit_conditions_text: str = Field("", description="Условия выхода в формате [INTENT_CHANGE: ]") name: str | None = Field(None, max_length=200) activate: bool = Field(False, description="Сразу сделать новую версию активной в рамках ветки") class IntentToggleRequest(BaseModel): is_enabled: bool class IntentStepUpdateRequest(BaseModel): name: str | None = Field(None, max_length=200) system_prompt: str | None = None allowed_next: list[str] | None = None guards: dict | None = None class IntentDocumentsUpdateRequest(BaseModel): document_ids: list[str] = Field(default_factory=list, description="Полный новый список document_id, на которые подписана ветка") class DocumentIntentsUpdateRequest(BaseModel): intent_codes: list[str] = Field(default_factory=list, description="Полный новый список кодов веток, к которым привязан документ") class DocumentRawUpdateRequest(BaseModel): raw_text: str = Field(..., min_length=1, description="Новый исходный текст документа; запускает переразметку и обновление Chroma")