| import { PluginsClient } from "@openhands/typescript-client/clients"; |
| import { getActiveBackend } from "./backend-registry/active-store"; |
| import { getAgentServerClientOptions } from "./agent-server-client-options"; |
| import type { PluginBundledSkill } from "./plugins-service"; |
|
|
| |
| |
| |
| |
| |
| |
| |
| export interface InstalledPluginInfo { |
| name: string; |
| version: string; |
| description: string | null; |
| enabled: boolean; |
| source: string; |
| resolved_ref?: string | null; |
| repo_path?: string | null; |
| installed_at: string; |
| install_path: string; |
| skills?: PluginBundledSkill[] | null; |
| files?: string[] | null; |
| } |
|
|
| |
| export interface InstallPluginRequest { |
| source: string; |
| ref?: string | null; |
| repo_path?: string | null; |
| force?: boolean; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| interface PluginsManagementClient { |
| listInstalledPlugins(): Promise<{ plugins: InstalledPluginInfo[] }>; |
| installPlugin(request: InstallPluginRequest): Promise<InstalledPluginInfo>; |
| setPluginEnabled( |
| name: string, |
| enabled: boolean, |
| ): Promise<{ name: string; enabled: boolean }>; |
| uninstallPlugin(name: string): Promise<{ message: string }>; |
| refreshPlugin( |
| name: string, |
| ): Promise<{ message: string; plugin: InstalledPluginInfo }>; |
| } |
|
|
| function isCloudBackend(): boolean { |
| return getActiveBackend().backend.kind === "cloud"; |
| } |
|
|
| function getManagementClient(): PluginsManagementClient { |
| return new PluginsClient( |
| getAgentServerClientOptions(), |
| ) as unknown as PluginsManagementClient; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class PluginsManagementService { |
| static async listInstalledPlugins(): Promise<InstalledPluginInfo[]> { |
| if (isCloudBackend()) { |
| return []; |
| } |
|
|
| try { |
| const response = await getManagementClient().listInstalledPlugins(); |
| return response.plugins ?? []; |
| } catch { |
| |
| |
| return []; |
| } |
| } |
|
|
| static async installPlugin( |
| request: InstallPluginRequest, |
| ): Promise<InstalledPluginInfo> { |
| if (isCloudBackend()) { |
| throw new Error( |
| "Installing plugins is only available on a local backend.", |
| ); |
| } |
| return getManagementClient().installPlugin(request); |
| } |
|
|
| static async setPluginEnabled( |
| name: string, |
| enabled: boolean, |
| ): Promise<{ name: string; enabled: boolean }> { |
| if (isCloudBackend()) { |
| throw new Error( |
| "Enabling and disabling plugins is only available on a local backend.", |
| ); |
| } |
| return getManagementClient().setPluginEnabled(name, enabled); |
| } |
|
|
| static async uninstallPlugin(name: string): Promise<{ message: string }> { |
| if (isCloudBackend()) { |
| throw new Error( |
| "Uninstalling plugins is only available on a local backend.", |
| ); |
| } |
| return getManagementClient().uninstallPlugin(name); |
| } |
|
|
| static async refreshPlugin( |
| name: string, |
| ): Promise<{ message: string; plugin: InstalledPluginInfo }> { |
| if (isCloudBackend()) { |
| throw new Error( |
| "Refreshing plugins is only available on a local backend.", |
| ); |
| } |
| return getManagementClient().refreshPlugin(name); |
| } |
| } |
|
|
| export default PluginsManagementService; |
|
|