feat: add pydantic models and exceptions for KB API
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
2926e702d7
commit
859494a83d
4 changed files with 202 additions and 0 deletions
1
ergpt/__init__.py
Normal file
1
ergpt/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
|
||||||
61
ergpt/kb/__init__.py
Normal file
61
ergpt/kb/__init__.py
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
from .async_client import AsyncKnowledgeBaseClient
|
||||||
|
from .client import KnowledgeBaseClient
|
||||||
|
from .exceptions import (
|
||||||
|
AuthenticationError,
|
||||||
|
ErGPTError,
|
||||||
|
NotFoundError,
|
||||||
|
PermissionDeniedError,
|
||||||
|
RateLimitError,
|
||||||
|
ServerError,
|
||||||
|
ValidationError,
|
||||||
|
)
|
||||||
|
from .models import (
|
||||||
|
ChunkPagination,
|
||||||
|
CreateKnowledgeBaseRequest,
|
||||||
|
CursorPagination,
|
||||||
|
Document,
|
||||||
|
DocumentChunk,
|
||||||
|
DocumentPagePagination,
|
||||||
|
DocumentWithContentUrl,
|
||||||
|
HTTPValidationError,
|
||||||
|
KnowledgeBase,
|
||||||
|
KnowledgeBaseAggregate,
|
||||||
|
KnowledgeBaseConfig,
|
||||||
|
PagePagination,
|
||||||
|
ScoredPayload,
|
||||||
|
SearchDocument,
|
||||||
|
SearchRequest,
|
||||||
|
SearchResponse,
|
||||||
|
UpdateKnowledgeBaseRequest,
|
||||||
|
ValidationErrorDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"KnowledgeBaseClient",
|
||||||
|
"AsyncKnowledgeBaseClient",
|
||||||
|
"ErGPTError",
|
||||||
|
"AuthenticationError",
|
||||||
|
"PermissionDeniedError",
|
||||||
|
"NotFoundError",
|
||||||
|
"ValidationError",
|
||||||
|
"ServerError",
|
||||||
|
"RateLimitError",
|
||||||
|
"KnowledgeBase",
|
||||||
|
"KnowledgeBaseAggregate",
|
||||||
|
"KnowledgeBaseConfig",
|
||||||
|
"CreateKnowledgeBaseRequest",
|
||||||
|
"UpdateKnowledgeBaseRequest",
|
||||||
|
"PagePagination",
|
||||||
|
"Document",
|
||||||
|
"DocumentWithContentUrl",
|
||||||
|
"DocumentPagePagination",
|
||||||
|
"DocumentChunk",
|
||||||
|
"CursorPagination",
|
||||||
|
"ChunkPagination",
|
||||||
|
"ScoredPayload",
|
||||||
|
"SearchDocument",
|
||||||
|
"SearchRequest",
|
||||||
|
"SearchResponse",
|
||||||
|
"ValidationErrorDetail",
|
||||||
|
"HTTPValidationError",
|
||||||
|
]
|
||||||
28
ergpt/kb/exceptions.py
Normal file
28
ergpt/kb/exceptions.py
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class ErGPTError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationError(ErGPTError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionDeniedError(ErGPTError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NotFoundError(ErGPTError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationError(ErGPTError):
|
||||||
|
def __init__(self, message: str, details: list = None):
|
||||||
|
super().__init__(message)
|
||||||
|
self.details = details or []
|
||||||
|
|
||||||
|
|
||||||
|
class ServerError(ErGPTError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RateLimitError(ErGPTError):
|
||||||
|
pass
|
||||||
112
ergpt/kb/models.py
Normal file
112
ergpt/kb/models.py
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class KnowledgeBaseConfig(BaseModel):
|
||||||
|
chunk_size: int = Field(..., description="Размер каждого чанка текста")
|
||||||
|
chunk_overlap: int = Field(..., description="Перекрытие между соседними чанками")
|
||||||
|
|
||||||
|
|
||||||
|
class CreateKnowledgeBaseRequest(BaseModel):
|
||||||
|
name: str = Field(..., description="Название базы знаний")
|
||||||
|
description: str = Field(..., description="Описание базы знаний")
|
||||||
|
config: KnowledgeBaseConfig = Field(..., description="Конфигурация разбиения на чанки")
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateKnowledgeBaseRequest(BaseModel):
|
||||||
|
name: str = Field(..., description="Новое название базы знаний")
|
||||||
|
description: str = Field(..., description="Новое описание базы знаний")
|
||||||
|
|
||||||
|
|
||||||
|
class KnowledgeBase(BaseModel):
|
||||||
|
id: str = Field(..., description="Уникальный идентификатор (UUID)")
|
||||||
|
name: str = Field(..., description="Название базы знаний")
|
||||||
|
description: str = Field(..., description="Описание базы знаний")
|
||||||
|
config: dict[str, Any] = Field(..., description="Конфигурация разбиения на чанки")
|
||||||
|
created_at: datetime = Field(..., description="Дата создания")
|
||||||
|
updated_at: datetime = Field(..., description="Дата последнего обновления")
|
||||||
|
user_id: str = Field(..., description="ID владельца (UUID)")
|
||||||
|
|
||||||
|
|
||||||
|
class KnowledgeBaseAggregate(KnowledgeBase):
|
||||||
|
documents_count: int = Field(..., description="Количество документов в базе знаний")
|
||||||
|
|
||||||
|
|
||||||
|
class PagePagination(BaseModel):
|
||||||
|
result: list[KnowledgeBaseAggregate] = Field(default_factory=list)
|
||||||
|
total: int = Field(..., description="Общее количество элементов")
|
||||||
|
|
||||||
|
|
||||||
|
class Document(BaseModel):
|
||||||
|
id: str = Field(..., description="Уникальный идентификатор (UUID)")
|
||||||
|
filename: str = Field(..., description="Исходное имя файла")
|
||||||
|
bucket: str = Field(..., description="Имя бакета хранилища")
|
||||||
|
kb_id: str = Field(..., description="ID родительской базы знаний (UUID)")
|
||||||
|
content_type: str = Field(..., description="MIME-тип документа")
|
||||||
|
size: int = Field(..., description="Размер файла в байтах")
|
||||||
|
created_at: datetime = Field(..., description="Дата создания")
|
||||||
|
updated_at: datetime = Field(..., description="Дата последнего обновления")
|
||||||
|
status: str = Field(..., description="Статус обработки: PENDING, PROCESSING, COMPLETED, FAILED")
|
||||||
|
error: str | None = Field(None, description="Сообщение об ошибке, если обработка не удалась")
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentWithContentUrl(Document):
|
||||||
|
content_url: str = Field(..., description="Подписанная URL для скачивания документа")
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentPagePagination(BaseModel):
|
||||||
|
result: list[DocumentWithContentUrl] = Field(default_factory=list)
|
||||||
|
total: int = Field(..., description="Общее количество документов")
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentChunk(BaseModel):
|
||||||
|
text: str = Field(..., description="Текстовое содержимое чанка")
|
||||||
|
document_id: str = Field(..., description="ID родительского документа (UUID)")
|
||||||
|
filename: str = Field(..., description="Исходное имя файла")
|
||||||
|
chunk_id: int = Field(..., description="Порядковый номер чанка")
|
||||||
|
|
||||||
|
|
||||||
|
class CursorPagination(BaseModel):
|
||||||
|
cursor: str | None = Field(None, description="Курсор для следующей страницы")
|
||||||
|
has_more: bool = Field(..., description="Есть ли еще результаты")
|
||||||
|
|
||||||
|
|
||||||
|
class ChunkPagination(BaseModel):
|
||||||
|
pagination: CursorPagination = Field(..., description="Метаданные пагинации")
|
||||||
|
result: list[DocumentChunk] = Field(default_factory=list, description="Список чанков")
|
||||||
|
|
||||||
|
|
||||||
|
class ScoredPayload(BaseModel):
|
||||||
|
text: str = Field(..., description="Текстовое содержимое")
|
||||||
|
score: float = Field(..., description="Оценка релевантности (0.0-1.0)")
|
||||||
|
|
||||||
|
|
||||||
|
class SearchDocument(DocumentWithContentUrl):
|
||||||
|
chunks: list[ScoredPayload] = Field(
|
||||||
|
default_factory=list, description="Найденные чанки с оценками"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SearchRequest(BaseModel):
|
||||||
|
query: str = Field(..., description="Поисковый запрос")
|
||||||
|
kb_id: str = Field(..., description="ID базы знаний (UUID)")
|
||||||
|
limit: int | None = Field(None, description="Максимальное количество результатов")
|
||||||
|
score_threshold: float = Field(0.2, description="Минимальный порог релевантности (0.0-1.0)")
|
||||||
|
|
||||||
|
|
||||||
|
class SearchResponse(BaseModel):
|
||||||
|
chunks: list[SearchDocument] = Field(
|
||||||
|
default_factory=list, description="Найденные документы с чанками"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationErrorDetail(BaseModel):
|
||||||
|
loc: list[str] = Field(default_factory=list, description="Расположение ошибки")
|
||||||
|
msg: str = Field(..., description="Сообщение об ошибке")
|
||||||
|
type: str = Field(..., description="Тип ошибки")
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPValidationError(BaseModel):
|
||||||
|
detail: list[ValidationErrorDetail] = Field(default_factory=list)
|
||||||
Loading…
Reference in a new issue