From 5815c092f08a0a4e650282927f16809e6ee54f00 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Sun, 8 Nov 2026 00:47:14 +0000 Subject: [PATCH] fix(typing): keep router fence visibility and py310-safe Self import Bind the Protocol-narrowed routers in pass_through_endpoints and rag ingestion to router-named locals so router_surface_check still sees the aadapter_completion and aocr uses, and import Self from typing_extensions in prisma_client for check_py310_typing_imports. --- litellm/proxy/db/prisma_client.py | 2 +- .../pass_through_endpoints.py | 21 ++++++------------- litellm/rag/ingestion/base_ingestion.py | 3 ++- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/litellm/proxy/db/prisma_client.py b/litellm/proxy/db/prisma_client.py index dec225cd348..d300b4d5a61 100644 --- a/litellm/proxy/db/prisma_client.py +++ b/litellm/proxy/db/prisma_client.py @@ -37,11 +37,11 @@ from litellm.secret_managers.main import str_to_bool if TYPE_CHECKING: from collections.abc import Sequence from types import TracebackType - from typing import Self from prisma import Prisma from prisma import models as prisma_models from prisma.types import HttpConfig + from typing_extensions import Self from litellm.repositories.prisma_protocols import TableActions diff --git a/litellm/proxy/pass_through_endpoints/pass_through_endpoints.py b/litellm/proxy/pass_through_endpoints/pass_through_endpoints.py index 93615cf92fb..c047920f81f 100644 --- a/litellm/proxy/pass_through_endpoints/pass_through_endpoints.py +++ b/litellm/proxy/pass_through_endpoints/pass_through_endpoints.py @@ -374,11 +374,8 @@ async def chat_completion_pass_through_endpoint( and data["model"] is not None and llm_router.registry().resolve(data["model"], kind="recognized") ): - llm_response = asyncio.create_task( - require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion").aadapter_completion( - **data - ) - ) + adapter_router = require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion") + llm_response = asyncio.create_task(adapter_router.aadapter_completion(**data)) elif ( llm_router is not None and data["model"] not in router_model_names @@ -387,19 +384,13 @@ async def chat_completion_pass_through_endpoint( or len(llm_router.registry().patterns().patterns) > 0 ) ): # check for wildcard routes or default deployment before checking deployment_names - llm_response = asyncio.create_task( - require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion").aadapter_completion( - **data - ) - ) + adapter_router = require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion") + llm_response = asyncio.create_task(adapter_router.aadapter_completion(**data)) elif llm_router is not None and data["model"] in llm_router.registry().names( kind="deployment_names" ): # model in router deployments, calling a specific deployment on the router (lowest priority) - llm_response = asyncio.create_task( - require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion").aadapter_completion( - **data, specific_deployment=True - ) - ) + adapter_router = require_attributes(llm_router, _AdapterCompletionRouter, "aadapter_completion") + llm_response = asyncio.create_task(adapter_router.aadapter_completion(**data, specific_deployment=True)) elif user_model is not None: # `litellm --model ` llm_response = asyncio.create_task(litellm.aadapter_completion(**data)) else: diff --git a/litellm/rag/ingestion/base_ingestion.py b/litellm/rag/ingestion/base_ingestion.py index 3742d06557f..0d75fe4e531 100644 --- a/litellm/rag/ingestion/base_ingestion.py +++ b/litellm/rag/ingestion/base_ingestion.py @@ -186,7 +186,8 @@ class BaseRAGIngestion(ABC): # Use router if available if self.router is not None: - ocr_response = await require_attributes(self.router, _OcrRouter, "aocr").aocr( + ocr_router: Final = require_attributes(self.router, _OcrRouter, "aocr") + ocr_response = await ocr_router.aocr( model=ocr_model, document={"type": doc_type, url_key: data_url}, )