Просмотр исходного кода

feat: add category for plugins

Yeuoly месяцев назад: 7
Родитель
Сommit
a81293cf5a

+ 6 - 10
api/controllers/console/workspace/plugin.py

@@ -133,9 +133,7 @@ class PluginInstallFromPkgApi(Resource):
 
         response = PluginService.install_from_local_pkg(tenant_id, args["plugin_unique_identifier"])
 
-        return {
-            "task_id": response,
-        }
+        return response.model_dump()
 
 
 class PluginInstallFromGithubApi(Resource):
@@ -160,9 +158,7 @@ class PluginInstallFromGithubApi(Resource):
             tenant_id, args["repo"], args["version"], args["package"], args["plugin_unique_identifier"]
         )
 
-        return {
-            "task_id": response,
-        }
+        return response.model_dump()
 
 
 class PluginInstallFromMarketplaceApi(Resource):
@@ -182,9 +178,7 @@ class PluginInstallFromMarketplaceApi(Resource):
 
         response = PluginService.install_from_marketplace_pkg(tenant_id, args["plugin_unique_identifier"])
 
-        return {
-            "task_id": response,
-        }
+        return response.model_dump()
 
 
 class PluginFetchManifestApi(Resource):
@@ -200,7 +194,9 @@ class PluginFetchManifestApi(Resource):
 
         tenant_id = user.current_tenant_id
 
-        return {"manifest": PluginService.fetch_plugin_manifest(tenant_id, args["plugin_unique_identifier"])}
+        return jsonable_encoder(
+            {"manifest": PluginService.fetch_plugin_manifest(tenant_id, args["plugin_unique_identifier"]).model_dump()}
+        )
 
 
 class PluginFetchInstallTasksApi(Resource):

+ 20 - 1
api/core/plugin/entities/plugin.py

@@ -3,7 +3,7 @@ from collections.abc import Mapping
 from enum import Enum
 from typing import Any, Optional
 
-from pydantic import BaseModel, Field
+from pydantic import BaseModel, Field, model_validator
 
 from core.model_runtime.entities.provider_entities import ProviderEntity
 from core.plugin.entities.base import BasePluginEntity
@@ -54,6 +54,12 @@ class PluginResourceRequirements(BaseModel):
     permission: Optional[Permission]
 
 
+class PluginCategory(str, Enum):
+    Tool = "tool"
+    Model = "model"
+    Extension = "extension"
+
+
 class PluginDeclaration(BaseModel):
     class Plugins(BaseModel):
         tools: Optional[list[str]] = Field(default_factory=list)
@@ -65,6 +71,7 @@ class PluginDeclaration(BaseModel):
     name: str = Field(..., pattern=r"^[a-z0-9_-]{1,128}$")
     icon: str
     label: I18nObject
+    category: PluginCategory
     created_at: datetime.datetime
     resource: PluginResourceRequirements
     plugins: Plugins
@@ -72,6 +79,18 @@ class PluginDeclaration(BaseModel):
     model: Optional[ProviderEntity] = None
     endpoint: Optional[EndpointProviderDeclaration] = None
 
+    @model_validator(mode="before")
+    @classmethod
+    def validate_category(cls, values: dict) -> dict:
+        # auto detect category
+        if values.get("tool"):
+            values["category"] = PluginCategory.Tool
+        elif values.get("model"):
+            values["category"] = PluginCategory.Model
+        else:
+            values["category"] = PluginCategory.Extension
+        return values
+
 
 class PluginEntity(BasePluginEntity):
     name: str

+ 5 - 0
api/core/plugin/entities/plugin_daemon.py

@@ -128,3 +128,8 @@ class PluginInstallTask(BasePluginEntity):
     total_plugins: int = Field(description="The total number of plugins to be installed.")
     completed_plugins: int = Field(description="The number of plugins that have been installed.")
     plugins: list[PluginInstallTaskPluginStatus] = Field(description="The status of the plugins.")
+
+
+class PluginInstallTaskStartResponse(BasePluginEntity):
+    all_installed: bool = Field(description="Whether all plugins are installed.")
+    task_id: str = Field(description="The ID of the install task.")

+ 14 - 7
api/core/plugin/manager/plugin.py

@@ -1,7 +1,9 @@
 from collections.abc import Sequence
 
+from pydantic import BaseModel
+
 from core.plugin.entities.plugin import PluginDeclaration, PluginEntity, PluginInstallationSource
-from core.plugin.entities.plugin_daemon import PluginInstallTask
+from core.plugin.entities.plugin_daemon import PluginInstallTask, PluginInstallTaskStartResponse
 from core.plugin.manager.base import BasePluginManager
 
 
@@ -53,15 +55,15 @@ class PluginInstallationManager(BasePluginManager):
 
     def install_from_identifiers(
         self, tenant_id: str, identifiers: Sequence[str], source: PluginInstallationSource, meta: dict
-    ) -> str:
+    ) -> PluginInstallTaskStartResponse:
         """
         Install a plugin from an identifier.
         """
         # exception will be raised if the request failed
         return self._request_with_plugin_daemon_response(
             "POST",
-            f"plugin/{tenant_id}/management/install/identifier",
-            str,
+            f"plugin/{tenant_id}/management/install/identifiers",
+            PluginInstallTaskStartResponse,
             data={
                 "plugin_unique_identifiers": identifiers,
                 "source": source,
@@ -94,11 +96,16 @@ class PluginInstallationManager(BasePluginManager):
         """
         Fetch a plugin manifest.
         """
+
+        class PluginDeclarationResponse(BaseModel):
+            declaration: PluginDeclaration
+
         return self._request_with_plugin_daemon_response(
             "GET",
-            f"plugin/{tenant_id}/management/fetch/identifier",
-            PluginDeclaration,
-        )
+            f"plugin/{tenant_id}/management/fetch/manifest",
+            PluginDeclarationResponse,
+            params={"plugin_unique_identifier": plugin_unique_identifier},
+        ).declaration
 
     def uninstall(self, tenant_id: str, plugin_installation_id: str) -> bool:
         """

+ 3 - 5
api/services/plugin/plugin_service.py

@@ -87,7 +87,7 @@ class PluginService:
         )
 
     @staticmethod
-    def install_from_local_pkg(tenant_id: str, plugin_unique_identifier: str) -> str:
+    def install_from_local_pkg(tenant_id: str, plugin_unique_identifier: str):
         manager = PluginInstallationManager()
         return manager.install_from_identifiers(
             tenant_id,
@@ -97,9 +97,7 @@ class PluginService:
         )
 
     @staticmethod
-    def install_from_github(
-        tenant_id: str, plugin_unique_identifier: str, repo: str, version: str, package: str
-    ) -> str:
+    def install_from_github(tenant_id: str, plugin_unique_identifier: str, repo: str, version: str, package: str):
         """
         Install plugin from github release package files,
         returns plugin_unique_identifier
@@ -117,7 +115,7 @@ class PluginService:
         )
 
     @staticmethod
-    def install_from_marketplace_pkg(tenant_id: str, plugin_unique_identifier: str) -> str:
+    def install_from_marketplace_pkg(tenant_id: str, plugin_unique_identifier: str):
         """
         Install plugin from marketplace package files,
         returns installation task id