mirror of
https://github.com/langgenius/dify.git
synced 2026-11-11 05:41:09 +08:00
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
92 lines
2.5 KiB
Python
92 lines
2.5 KiB
Python
"""Detached annotation reads shared by Console and Service API endpoints.
|
|
|
|
These queries need no application orchestration. The composition root injects
|
|
their repository implementation directly, as it does for app statistics.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from typing import Protocol
|
|
|
|
|
|
class AnnotationAppNotFoundError(Exception):
|
|
"""The requested app is unavailable in the caller's workspace."""
|
|
|
|
|
|
class AnnotationNotFoundError(Exception):
|
|
"""The requested annotation does not belong to the admitted app."""
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AnnotationRecord:
|
|
id: str
|
|
question: str
|
|
content: str
|
|
hit_count: int
|
|
created_at: datetime
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AnnotationHitHistoryRecord:
|
|
id: str
|
|
source: str
|
|
score: float
|
|
question: str
|
|
created_at: datetime
|
|
annotation_question: str
|
|
annotation_content: str
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AnnotationPage[RecordT]:
|
|
data: tuple[RecordT, ...]
|
|
page: int
|
|
limit: int
|
|
total: int
|
|
|
|
@property
|
|
def has_more(self) -> bool:
|
|
return self.page * self.limit < self.total
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AnnotationEmbeddingModel:
|
|
"""Both names are None when an enabled setting's binding was removed."""
|
|
|
|
embedding_provider_name: str | None
|
|
embedding_model_name: str | None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AnnotationSettingRecord:
|
|
"""Disabled apps have no setting ID, threshold, or embedding model."""
|
|
|
|
enabled: bool
|
|
id: str | None
|
|
score_threshold: float | None
|
|
embedding_model: AnnotationEmbeddingModel | None
|
|
|
|
|
|
class AnnotationAppQuery(Protocol):
|
|
def require_app(self, *, tenant_id: str, app_id: str) -> None:
|
|
"""Validate a normal app's workspace and close the database session before returning."""
|
|
...
|
|
|
|
|
|
class AnnotationQuery(Protocol):
|
|
def count(self, *, tenant_id: str, app_id: str) -> int: ...
|
|
|
|
def get_page(
|
|
self, *, tenant_id: str, app_id: str, page: int, limit: int, keyword: str
|
|
) -> AnnotationPage[AnnotationRecord]: ...
|
|
|
|
def get_all(self, *, tenant_id: str, app_id: str) -> tuple[AnnotationRecord, ...]:
|
|
"""Read all annotations for export, retaining their original text."""
|
|
...
|
|
|
|
def get_setting(self, *, tenant_id: str, app_id: str) -> AnnotationSettingRecord: ...
|
|
|
|
def get_hit_history_page(
|
|
self, *, tenant_id: str, app_id: str, annotation_id: str, page: int, limit: int
|
|
) -> AnnotationPage[AnnotationHitHistoryRecord]: ...
|