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