mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
fix(claude-code): fix remaining CI failures on allowed_skills addition
- Modernize Optional[X]/List[X]/Dict[X,Y] to X | None/list/dict on every line the strict-rule ruff budget flagged as newly added, instead of raising the ceiling. - Fix a golden-fixture test in test_customer_endpoints.py that hardcoded the full object_permission response shape and didn't account for the new allowed_skills field. - Regenerate schema.d.ts with a Python 3.12 venv synced the same way CI's check-ui-api-types workflow does (uv sync --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router); the prior regeneration used a mismatched local Python 3.11/deps and produced spurious diffs unrelated to this PR.
This commit is contained in:
parent
73042573c6
commit
59f2a8ed67
8 changed files with 1117 additions and 92 deletions
|
|
@ -25,4 +25,4 @@ class LiteLLM_ObjectPermissionTable(LiteLLMPydanticObjectBase):
|
|||
blocked_tools: Optional[List[str]] = []
|
||||
search_tools: Optional[List[str]] = []
|
||||
mcp_tool_search_enabled: Optional[bool] = None
|
||||
allowed_skills: Optional[List[str]] = None
|
||||
allowed_skills: list[str] | None = None
|
||||
|
|
|
|||
|
|
@ -1009,7 +1009,7 @@ class LiteLLM_ObjectPermissionBase(LiteLLMPydanticObjectBase):
|
|||
models: Optional[List[str]] = None
|
||||
search_tools: Optional[List[str]] = None
|
||||
mcp_tool_search_enabled: Optional[bool] = None
|
||||
allowed_skills: Optional[List[str]] = None
|
||||
allowed_skills: list[str] | None = None
|
||||
|
||||
|
||||
from litellm.types.object_permission import ( # noqa: E402
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Endpoints:
|
|||
import json
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, FrozenSet, Optional
|
||||
from typing import Any, Dict
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, Security
|
||||
from fastapi.responses import JSONResponse
|
||||
|
|
@ -54,11 +54,11 @@ async def _optional_user_api_key_auth(
|
|||
request: Request,
|
||||
api_key: str = Security(api_key_header),
|
||||
azure_api_key: str = Security(azure_api_key_header),
|
||||
anthropic_api_key: Optional[str] = Security(anthropic_api_key_header),
|
||||
google_ai_studio_api_key: Optional[str] = Security(google_ai_studio_api_key_header),
|
||||
azure_apim_key: Optional[str] = Security(azure_apim_header),
|
||||
custom_litellm_key: Optional[str] = Security(custom_litellm_key_header),
|
||||
) -> Optional[UserAPIKeyAuth]:
|
||||
anthropic_api_key: str | None = Security(anthropic_api_key_header),
|
||||
google_ai_studio_api_key: str | None = Security(google_ai_studio_api_key_header),
|
||||
azure_apim_key: str | None = Security(azure_apim_header),
|
||||
custom_litellm_key: str | None = Security(custom_litellm_key_header),
|
||||
) -> UserAPIKeyAuth | None:
|
||||
"""
|
||||
Resolve UserAPIKeyAuth if a key is present (header or, for this route,
|
||||
the `key` query param wired up via RouteChecks.is_claude_code_marketplace_route),
|
||||
|
|
@ -95,7 +95,7 @@ async def _get_prisma_client():
|
|||
tags=["Claude Code Marketplace"],
|
||||
)
|
||||
async def get_marketplace(
|
||||
user_api_key_dict: Optional[UserAPIKeyAuth] = Depends(_optional_user_api_key_auth), # noqa: B008 # DI idiom
|
||||
user_api_key_dict: UserAPIKeyAuth | None = Depends(_optional_user_api_key_auth), # noqa: B008 # DI idiom
|
||||
):
|
||||
"""
|
||||
Serve marketplace.json for Claude Code plugin discovery.
|
||||
|
|
@ -120,7 +120,7 @@ async def get_marketplace(
|
|||
try:
|
||||
prisma_client = await _get_prisma_client()
|
||||
|
||||
allowed_skills: FrozenSet[str] = (
|
||||
allowed_skills: frozenset[str] = (
|
||||
await get_allowed_skills(user_api_key_dict, prisma_client) if user_api_key_dict is not None else frozenset()
|
||||
)
|
||||
where = (
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ Endpoints:
|
|||
"""
|
||||
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
|
|
@ -100,7 +99,7 @@ async def _count_plugins(prisma_client, marketplace_id: str) -> int:
|
|||
return await ClaudeCodePluginRepository(prisma_client).table.count(where={"marketplace_id": marketplace_id})
|
||||
|
||||
|
||||
def _to_marketplace_source_response(marketplace, plugin_count: Optional[int]) -> MarketplaceSourceResponse:
|
||||
def _to_marketplace_source_response(marketplace, plugin_count: int | None) -> MarketplaceSourceResponse:
|
||||
return MarketplaceSourceResponse(
|
||||
id=marketplace.id,
|
||||
name=marketplace.name,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from typing import Optional
|
||||
|
||||
from litellm._logging import verbose_logger
|
||||
from litellm.proxy._types import UI_TEAM_ID, UserAPIKeyAuth
|
||||
from litellm.proxy.utils import PrismaClient
|
||||
|
|
@ -7,7 +5,7 @@ from litellm.proxy.utils import PrismaClient
|
|||
|
||||
async def _get_allowed_skills_for_key(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
prisma_client: Optional[PrismaClient],
|
||||
prisma_client: PrismaClient | None,
|
||||
) -> frozenset[str]:
|
||||
"""Key's own allowed_skills ceiling from its object_permission.
|
||||
|
||||
|
|
@ -36,7 +34,7 @@ async def _get_allowed_skills_for_key(
|
|||
|
||||
async def _get_allowed_skills_for_team(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
prisma_client: Optional[PrismaClient],
|
||||
prisma_client: PrismaClient | None,
|
||||
) -> frozenset[str]:
|
||||
"""Team's allowed_skills ceiling from team.object_permission."""
|
||||
from litellm.proxy.auth.auth_checks import get_team_object
|
||||
|
|
@ -63,7 +61,7 @@ async def _get_allowed_skills_for_team(
|
|||
|
||||
async def _get_allowed_skills_for_org(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
prisma_client: Optional[PrismaClient],
|
||||
prisma_client: PrismaClient | None,
|
||||
) -> frozenset[str]:
|
||||
"""Org's allowed_skills ceiling from org.object_permission."""
|
||||
from litellm.proxy.auth.auth_checks import get_object_permission, get_org_object
|
||||
|
|
@ -97,7 +95,7 @@ async def _get_allowed_skills_for_org(
|
|||
|
||||
async def get_allowed_skills(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
prisma_client: Optional[PrismaClient],
|
||||
prisma_client: PrismaClient | None,
|
||||
) -> frozenset[str]:
|
||||
"""
|
||||
Resolve the set of Claude Code skill names (already-namespaced, e.g.
|
||||
|
|
|
|||
|
|
@ -708,7 +708,7 @@ async def validate_key_vector_stores_against_team(
|
|||
|
||||
|
||||
def _extract_requested_allowed_skills(
|
||||
object_permission: Optional[ObjectPermissionDict],
|
||||
object_permission: ObjectPermissionDict | None,
|
||||
) -> set[str]:
|
||||
"""Return allowed_skills names from a key's object_permission dict."""
|
||||
if not object_permission or not isinstance(object_permission, dict):
|
||||
|
|
@ -720,8 +720,8 @@ def _extract_requested_allowed_skills(
|
|||
|
||||
|
||||
async def validate_key_allowed_skills_against_team(
|
||||
object_permission: Optional[ObjectPermissionDict],
|
||||
team_obj: Optional["LiteLLM_TeamTableCachedObj"],
|
||||
object_permission: ObjectPermissionDict | None,
|
||||
team_obj: "LiteLLM_TeamTableCachedObj | None",
|
||||
is_proxy_admin: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
|
|
@ -752,7 +752,7 @@ async def validate_key_allowed_skills_against_team(
|
|||
},
|
||||
)
|
||||
|
||||
team_skills: List[str] = []
|
||||
team_skills: list[str] = []
|
||||
if team_obj is not None and team_obj.object_permission is not None:
|
||||
skills = team_obj.object_permission.allowed_skills
|
||||
if skills:
|
||||
|
|
|
|||
|
|
@ -719,6 +719,7 @@ _EXPECTED_CUSTOMER = {
|
|||
"blocked_tools": [],
|
||||
"search_tools": [],
|
||||
"mcp_tool_search_enabled": None,
|
||||
"allowed_skills": None,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
1167
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
1167
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue