mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-11 00:06:04 +00:00
feat: improvements for installed plugin card
* feat:Add README display to installed plugins * chore: Increase the timeout of call_tool * perf: smaller animation * fix: add endpiont for readme * feat: supports for multilingual READMEs * feat: supports for getting readme img * chore: bump langbot-plugin to 0.1.13b1 * perf: plugin card layout * fix: import useTranslation linter error --------- Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
@@ -82,6 +82,16 @@ class PluginsRouterGroup(group.RouterGroup):
|
||||
|
||||
return self.success(data={})
|
||||
|
||||
@self.route(
|
||||
'/<author>/<plugin_name>/readme',
|
||||
methods=['GET'],
|
||||
auth_type=group.AuthType.USER_TOKEN,
|
||||
)
|
||||
async def _(author: str, plugin_name: str) -> quart.Response:
|
||||
language = quart.request.args.get('language', 'en')
|
||||
readme = await self.ap.plugin_connector.get_plugin_readme(author, plugin_name, language=language)
|
||||
return self.success(data={'readme': readme})
|
||||
|
||||
@self.route(
|
||||
'/<author>/<plugin_name>/icon',
|
||||
methods=['GET'],
|
||||
@@ -96,6 +106,17 @@ class PluginsRouterGroup(group.RouterGroup):
|
||||
|
||||
return quart.Response(icon_data, mimetype=mime_type)
|
||||
|
||||
@self.route(
|
||||
'/<author>/<plugin_name>/assets/<filepath>',
|
||||
methods=['GET'],
|
||||
auth_type=group.AuthType.NONE,
|
||||
)
|
||||
async def _(author: str, plugin_name: str, filepath: str) -> quart.Response:
|
||||
asset_data = await self.ap.plugin_connector.get_plugin_assets(author, plugin_name, filepath)
|
||||
asset_bytes = base64.b64decode(asset_data['asset_base64'])
|
||||
mime_type = asset_data['mime_type']
|
||||
return quart.Response(asset_bytes, mimetype=mime_type)
|
||||
|
||||
@self.route('/github/releases', methods=['POST'], auth_type=group.AuthType.USER_TOKEN)
|
||||
async def _() -> str:
|
||||
"""Get releases from a GitHub repository URL"""
|
||||
|
||||
@@ -347,6 +347,14 @@ class PluginRuntimeConnector:
|
||||
async def get_plugin_icon(self, plugin_author: str, plugin_name: str) -> dict[str, Any]:
|
||||
return await self.handler.get_plugin_icon(plugin_author, plugin_name)
|
||||
|
||||
@alru_cache(ttl=5 * 60) # 5 minutes
|
||||
async def get_plugin_readme(self, plugin_author: str, plugin_name: str, language: str = 'en') -> str:
|
||||
return await self.handler.get_plugin_readme(plugin_author, plugin_name, language)
|
||||
|
||||
@alru_cache(ttl=5 * 60)
|
||||
async def get_plugin_assets(self, plugin_author: str, plugin_name: str, filepath: str) -> dict[str, Any]:
|
||||
return await self.handler.get_plugin_assets(plugin_author, plugin_name, filepath)
|
||||
|
||||
async def emit_event(
|
||||
self,
|
||||
event: events.BaseEventModel,
|
||||
|
||||
@@ -602,6 +602,51 @@ class RuntimeConnectionHandler(handler.Handler):
|
||||
'mime_type': mime_type,
|
||||
}
|
||||
|
||||
async def get_plugin_readme(self, plugin_author: str, plugin_name: str, language: str = 'en') -> str:
|
||||
"""Get plugin readme"""
|
||||
try:
|
||||
result = await self.call_action(
|
||||
LangBotToRuntimeAction.GET_PLUGIN_README,
|
||||
{
|
||||
'plugin_author': plugin_author,
|
||||
'plugin_name': plugin_name,
|
||||
'language': language,
|
||||
},
|
||||
timeout=20,
|
||||
)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return ''
|
||||
|
||||
readme_file_key = result.get('readme_file_key')
|
||||
if not readme_file_key:
|
||||
return ''
|
||||
|
||||
readme_bytes = await self.read_local_file(readme_file_key)
|
||||
await self.delete_local_file(readme_file_key)
|
||||
|
||||
return readme_bytes.decode('utf-8')
|
||||
|
||||
async def get_plugin_assets(self, plugin_author: str, plugin_name: str, filepath: str) -> dict[str, Any]:
|
||||
"""Get plugin assets"""
|
||||
result = await self.call_action(
|
||||
LangBotToRuntimeAction.GET_PLUGIN_ASSETS_FILE,
|
||||
{
|
||||
'plugin_author': plugin_author,
|
||||
'plugin_name': plugin_name,
|
||||
'file_path': filepath,
|
||||
},
|
||||
timeout=20,
|
||||
)
|
||||
asset_file_key = result['file_file_key']
|
||||
mime_type = result['mime_type']
|
||||
asset_bytes = await self.read_local_file(asset_file_key)
|
||||
await self.delete_local_file(asset_file_key)
|
||||
return {
|
||||
'asset_base64': base64.b64encode(asset_bytes).decode('utf-8'),
|
||||
'mime_type': mime_type,
|
||||
}
|
||||
|
||||
async def cleanup_plugin_data(self, plugin_author: str, plugin_name: str) -> None:
|
||||
"""Cleanup plugin settings and binary storage"""
|
||||
# Delete plugin settings
|
||||
@@ -637,7 +682,7 @@ class RuntimeConnectionHandler(handler.Handler):
|
||||
'query_id': query_id,
|
||||
'include_plugins': include_plugins,
|
||||
},
|
||||
timeout=60,
|
||||
timeout=180,
|
||||
)
|
||||
|
||||
return result['tool_response']
|
||||
|
||||
Reference in New Issue
Block a user