mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
105 lines
4.5 KiB
Python
105 lines
4.5 KiB
Python
"""External knowledge use cases without transport or persistence dependencies."""
|
|
|
|
from collections.abc import Mapping
|
|
from typing import Any, Protocol
|
|
|
|
from machinery.context import RequestContext
|
|
from services.entities.external_knowledge_entities.external_knowledge_entities import ExternalDatasetCreatePayload
|
|
from services.knowledge.dataset_access import DatasetAccess
|
|
from services.knowledge.entities.datasets import DatasetDetailRecord
|
|
from services.knowledge.resource_scope import DatasetRef
|
|
|
|
|
|
class ExternalTemplateNotFoundError(Exception):
|
|
pass
|
|
|
|
|
|
class ExternalHitTestingError(Exception):
|
|
pass
|
|
|
|
|
|
class ExternalKnowledgeOperations(Protocol):
|
|
def list_templates(self, workspace_id: str, *, page: int, limit: int, keyword: str | None) -> dict[str, Any]: ...
|
|
def get_template(self, workspace_id: str, template_id: str) -> dict[str, Any]: ...
|
|
def create_template(self, context: RequestContext, *, name: str, settings: Mapping[str, Any]) -> dict[str, Any]: ...
|
|
def update_template(
|
|
self, context: RequestContext, template_id: str, *, name: str, settings: Mapping[str, Any]
|
|
) -> dict[str, Any]: ...
|
|
def delete_template(self, workspace_id: str, template_id: str) -> None: ...
|
|
def template_usage(self, workspace_id: str, template_id: str) -> tuple[bool, int]: ...
|
|
def create_dataset(self, context: RequestContext, payload: ExternalDatasetCreatePayload) -> DatasetDetailRecord: ...
|
|
def retrieve(
|
|
self,
|
|
context: RequestContext,
|
|
ref: DatasetRef,
|
|
*,
|
|
query: str,
|
|
retrieval_model: dict[str, Any] | None,
|
|
metadata_filters: dict[str, Any] | None,
|
|
) -> dict[str, Any]: ...
|
|
|
|
|
|
class ExternalKnowledgeApplicationService:
|
|
def __init__(self, *, dataset_access: DatasetAccess, operations: ExternalKnowledgeOperations) -> None:
|
|
self._dataset_access = dataset_access
|
|
self._operations = operations
|
|
|
|
@staticmethod
|
|
def _validate_settings(settings: Mapping[str, Any]) -> None:
|
|
if not settings:
|
|
raise ValueError("api list is empty")
|
|
if not settings.get("endpoint"):
|
|
raise ValueError("endpoint is required")
|
|
if not settings.get("api_key"):
|
|
raise ValueError("api_key is required")
|
|
|
|
def list_templates(self, context: RequestContext, *, page: int, limit: int, keyword: str | None) -> dict[str, Any]:
|
|
return self._operations.list_templates(context.active_workspace_id, page=page, limit=limit, keyword=keyword)
|
|
|
|
def get_template(self, context: RequestContext, *, template_id: str) -> dict[str, Any]:
|
|
return self._operations.get_template(context.active_workspace_id, template_id)
|
|
|
|
def create_template(self, context: RequestContext, *, name: str, settings: Mapping[str, Any]) -> dict[str, Any]:
|
|
self._validate_settings(settings)
|
|
return self._operations.create_template(context, name=name, settings=settings)
|
|
|
|
def update_template(
|
|
self, context: RequestContext, *, template_id: str, name: str, settings: Mapping[str, Any]
|
|
) -> dict[str, Any]:
|
|
self._validate_settings(settings)
|
|
return self._operations.update_template(context, template_id, name=name, settings=settings)
|
|
|
|
def delete_template(self, context: RequestContext, *, template_id: str) -> None:
|
|
self._operations.delete_template(context.active_workspace_id, template_id)
|
|
|
|
def template_usage(self, context: RequestContext, *, template_id: str) -> tuple[bool, int]:
|
|
return self._operations.template_usage(context.active_workspace_id, template_id)
|
|
|
|
def create_dataset(self, context: RequestContext, *, payload: ExternalDatasetCreatePayload) -> DatasetDetailRecord:
|
|
return self._operations.create_dataset(context, payload)
|
|
|
|
def hit_testing(
|
|
self,
|
|
context: RequestContext,
|
|
*,
|
|
dataset_id: str,
|
|
query: str,
|
|
retrieval_model: dict[str, Any] | None,
|
|
metadata_filters: dict[str, Any] | None,
|
|
) -> dict[str, Any]:
|
|
dataset = self._dataset_access.require_accessible(context, dataset_id)
|
|
if not query:
|
|
raise ValueError("Query or attachment_ids is required")
|
|
if len(query) > 250:
|
|
raise ValueError("Query cannot exceed 250 characters")
|
|
try:
|
|
return self._operations.retrieve(
|
|
context,
|
|
DatasetRef(dataset.workspace_id, dataset.id),
|
|
query=query,
|
|
retrieval_model=retrieval_model,
|
|
metadata_filters=metadata_filters,
|
|
)
|
|
except Exception as error:
|
|
raise ExternalHitTestingError(str(error)) from error
|