From 875c89c09bd0a683d226d8836701cf2b902645bc Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Mon, 19 Jan 2026 14:22:42 -0800 Subject: [PATCH] add netwroking methods --- .../src/components/networking.tsx | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index c975877d06c..155a078f34a 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -8280,3 +8280,278 @@ export const updateUiSettings = async (accessToken: string, settings: Record { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/marketplace.json` + : `/claude-code/marketplace.json`; + + const response = await fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error("Failed to fetch Claude Code marketplace:", error); + throw error; + } +}; + +/** + * List all Claude Code plugins (admin only) + * @param accessToken - Admin access token + * @param enabledOnly - If true, only return enabled plugins (default: false) + */ +export const getClaudeCodePluginsList = async ( + accessToken: string, + enabledOnly: boolean = false +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins?enabled_only=${enabledOnly}` + : `/claude-code/plugins?enabled_only=${enabledOnly}`; + + const response = await fetch(url, { + method: "GET", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error("Failed to fetch Claude Code plugins list:", error); + throw error; + } +}; + +/** + * Get details for a specific Claude Code plugin (admin only) + * @param accessToken - Admin access token + * @param pluginName - Name of the plugin + */ +export const getClaudeCodePluginDetails = async ( + accessToken: string, + pluginName: string +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins/${pluginName}` + : `/claude-code/plugins/${pluginName}`; + + const response = await fetch(url, { + method: "GET", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Failed to fetch plugin "${pluginName}":`, error); + throw error; + } +}; + +/** + * Register or update a Claude Code plugin (admin only) + * @param accessToken - Admin access token + * @param pluginData - Plugin registration data + */ +export const registerClaudeCodePlugin = async ( + accessToken: string, + pluginData: { + name: string; + source: { source: string; repo?: string; url?: string }; + version?: string; + description?: string; + author?: { name: string; email?: string }; + homepage?: string; + keywords?: string[]; + category?: string; + } +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins` + : `/claude-code/plugins`; + + const response = await fetch(url, { + method: "POST", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(pluginData), + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error("Failed to register Claude Code plugin:", error); + throw error; + } +}; + +/** + * Enable a Claude Code plugin (admin only) + * @param accessToken - Admin access token + * @param pluginName - Name of the plugin to enable + */ +export const enableClaudeCodePlugin = async ( + accessToken: string, + pluginName: string +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins/${pluginName}/enable` + : `/claude-code/plugins/${pluginName}/enable`; + + const response = await fetch(url, { + method: "POST", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Failed to enable plugin "${pluginName}":`, error); + throw error; + } +}; + +/** + * Disable a Claude Code plugin (admin only) + * @param accessToken - Admin access token + * @param pluginName - Name of the plugin to disable + */ +export const disableClaudeCodePlugin = async ( + accessToken: string, + pluginName: string +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins/${pluginName}/disable` + : `/claude-code/plugins/${pluginName}/disable`; + + const response = await fetch(url, { + method: "POST", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Failed to disable plugin "${pluginName}":`, error); + throw error; + } +}; + +/** + * Delete a Claude Code plugin (admin only) + * @param accessToken - Admin access token + * @param pluginName - Name of the plugin to delete + */ +export const deleteClaudeCodePlugin = async ( + accessToken: string, + pluginName: string +) => { + try { + const proxyBaseUrl = getProxyBaseUrl(); + const url = proxyBaseUrl + ? `${proxyBaseUrl}/claude-code/plugins/${pluginName}` + : `/claude-code/plugins/${pluginName}`; + + const response = await fetch(url, { + method: "DELETE", + headers: { + [globalLitellmHeaderName]: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + const errorMessage = deriveErrorMessage(JSON.parse(errorData)); + handleError(errorMessage); + throw new Error(errorMessage); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Failed to delete plugin "${pluginName}":`, error); + throw error; + } +};