diff --git a/litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py b/litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py index 871ca31eb42..c03339adf29 100644 --- a/litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py +++ b/litellm/proxy/anthropic_endpoints/claude_code_endpoints/claude_code_marketplace.py @@ -21,7 +21,7 @@ import json import re from collections.abc import Mapping, Sequence from datetime import datetime, timezone -from typing import Annotated, Final, Protocol, TypedDict, cast +from typing import Annotated, Final, Protocol, TypedDict from urllib.parse import urlsplit from fastapi import APIRouter, Depends, HTTPException, Request @@ -73,6 +73,11 @@ class _MarketplaceEntry(TypedDict, total=False): installationPreference: str +def _get_manifest_string(manifest: Mapping[str, object], key: str) -> str | None: + value: Final = manifest.get(key) + return value if isinstance(value, str) else None + + async def _get_prisma_client() -> object: """Get the prisma client from proxy_server.""" from litellm.proxy.proxy_server import prisma_client @@ -154,8 +159,9 @@ async def get_marketplace(request: Request, key: str | None = None): entry["keywords"] = manifest["keywords"] if "category" in manifest: entry["category"] = manifest["category"] - if "installation_preference" in manifest: - entry["installationPreference"] = cast(str, manifest["installation_preference"]) + installation_preference: Final[str | None] = _get_manifest_string(manifest, "installation_preference") + if installation_preference is not None: + entry["installationPreference"] = installation_preference plugin_list.append(entry) @@ -439,10 +445,7 @@ async def list_plugins( category=manifest.get("category"), domain=manifest.get("domain"), namespace=manifest.get("namespace"), - installation_preference=cast( - str | None, - cast(Mapping[str, object], manifest).get("installation_preference"), - ), + installation_preference=_get_manifest_string(manifest, "installation_preference"), enabled=p.enabled, created_at=p.created_at.isoformat() if p.created_at else None, updated_at=p.updated_at.isoformat() if p.updated_at else None, diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index 17ec8367324..0b44a51040f 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -2250,6 +2250,7 @@ export interface paths { * - homepage: Plugin homepage URL (optional) * - keywords: Search keywords (optional) * - category: Plugin category (optional) + * - installation_preference: Marketplace installationPreference, e.g. 'auto_install' (optional) * * Returns: * Registration status (action is always "created") and plugin information. @@ -2316,6 +2317,7 @@ export interface paths { * - homepage: Plugin homepage URL (optional) * - keywords: Search keywords (optional) * - category: Plugin category (optional) + * - installation_preference: Marketplace installationPreference, e.g. 'auto_install' (optional) * * Returns: * Update status (action is always "updated") and plugin information. @@ -34381,6 +34383,8 @@ export interface components { homepage?: string | null; /** Id */ id: string; + /** Installation Preference */ + installation_preference?: string | null; /** Keywords */ keywords?: string[] | null; /** Name */ @@ -35699,6 +35703,11 @@ export interface components { * @description Plugin homepage URL */ homepage?: string | null; + /** + * Installation Preference + * @description Claude Code marketplace installationPreference for this plugin (e.g. 'auto_install') + */ + installation_preference?: string | null; /** * Keywords * @description Search keywords @@ -39079,6 +39088,11 @@ export interface components { * @description Plugin homepage URL */ homepage?: string | null; + /** + * Installation Preference + * @description Claude Code marketplace installationPreference for this plugin (e.g. 'auto_install') + */ + installation_preference?: string | null; /** * Keywords * @description Search keywords