feat: plugin installation

This commit is contained in:
Junyan Qin
2025-08-15 21:30:26 +08:00
parent e1a78e8ff9
commit b464d238c5
3 changed files with 64 additions and 2 deletions

View File

@@ -1,10 +1,11 @@
from __future__ import annotations
import base64
import quart
from .....core import taskmgr
from .. import group
from langbot_plugin.runtime.plugin.mgr import PluginInstallSource
@group.group_class('plugins', '/api/v1/plugins')
@@ -100,7 +101,47 @@ class PluginsRouterGroup(group.RouterGroup):
self.ap.plugin_mgr.install_plugin(data['source'], task_context=ctx),
kind='plugin-operation',
name='plugin-install-github',
label=f'安装插件 ...{short_source_str}',
label=f'Installing plugin from github ...{short_source_str}',
context=ctx,
)
return self.success(data={'task_id': wrapper.id})
@self.route('/install/marketplace', methods=['POST'], auth_type=group.AuthType.USER_TOKEN)
async def _() -> str:
data = await quart.request.json
ctx = taskmgr.TaskContext.new()
wrapper = self.ap.task_mgr.create_user_task(
self.ap.plugin_connector.install_plugin(PluginInstallSource.MARKETPLACE, data, task_context=ctx),
kind='plugin-operation',
name='plugin-install-marketplace',
label=f'Installing plugin from marketplace ...{data}',
context=ctx,
)
return self.success(data={'task_id': wrapper.id})
@self.route('/install/local', methods=['POST'], auth_type=group.AuthType.USER_TOKEN)
async def _() -> str:
file = (await quart.request.files).get('file')
if file is None:
return self.http_status(400, -1, 'file is required')
file_bytes = file.read()
file_base64 = base64.b64encode(file_bytes).decode('utf-8')
data = {
'plugin_file': file_base64,
}
ctx = taskmgr.TaskContext.new()
wrapper = self.ap.task_mgr.create_user_task(
self.ap.plugin_connector.install_plugin(PluginInstallSource.LOCAL, data, task_context=ctx),
kind='plugin-operation',
name='plugin-install-local',
label=f'Installing plugin from local ...{file.filename}',
context=ctx,
)

View File

@@ -17,6 +17,8 @@ from langbot_plugin.api.entities import context
import langbot_plugin.runtime.io.connection as base_connection
from langbot_plugin.api.definition.components.manifest import ComponentManifest
from langbot_plugin.api.entities.builtin.command import context as command_context
from langbot_plugin.runtime.plugin.mgr import PluginInstallSource
from ..core import taskmgr
class PluginRuntimeConnector:
@@ -97,6 +99,14 @@ class PluginRuntimeConnector:
async def initialize_plugins(self):
pass
async def install_plugin(
self,
install_source: PluginInstallSource,
install_info: dict[str, Any],
task_context: taskmgr.TaskContext | None = None,
):
return await self.handler.install_plugin(install_source.value, install_info)
async def list_plugins(self) -> list[dict[str, Any]]:
return await self.handler.list_plugins()

View File

@@ -373,6 +373,17 @@ class RuntimeConnectionHandler(handler.Handler):
timeout=10,
)
async def install_plugin(self, install_source: str, install_info: dict[str, Any]) -> dict[str, Any]:
"""Install plugin"""
return await self.call_action(
LangBotToRuntimeAction.INSTALL_PLUGIN,
{
'install_source': install_source,
'install_info': install_info,
},
timeout=10,
)
async def list_plugins(self) -> list[dict[str, Any]]:
"""List plugins"""
result = await self.call_action(