mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-13 03:59:12 +00:00
fix(generic_guardrail_api): annotate the returned tool calls exactly, never rebind
The type alias that named this field read the request's field through a TypedDict subscript, which ruff reads as a forward reference, and it failed the basedpyright budget. The annotations spell the union out again, which is exact and checks against GenericGuardrailAPIInputs without an alias and without a suppression comment. The unusable-reply path no longer rebinds a Final local, so it needs no suppression comment either: the calls that will be applied are picked in one expression.
This commit is contained in:
parent
f0f06aec07
commit
47cf3170a2
2 changed files with 13 additions and 17 deletions
|
|
@ -24,15 +24,14 @@ from litellm.llms.custom_httpx.http_handler import (
|
|||
httpxSpecialProvider,
|
||||
)
|
||||
from litellm.types.guardrails import GuardrailEventHooks
|
||||
from litellm.types.llms.openai import ChatCompletionToolParam
|
||||
from litellm.types.llms.openai import ChatCompletionToolCallChunk, ChatCompletionToolParam
|
||||
from litellm.types.proxy.guardrails.guardrail_hooks.generic_guardrail_api import (
|
||||
GenericGuardrailAPIMetadata,
|
||||
GenericGuardrailAPIRequest,
|
||||
GenericGuardrailAPIResponse,
|
||||
GenericGuardrailAPIToolCalls,
|
||||
GuardrailToolParam,
|
||||
)
|
||||
from litellm.types.utils import GenericGuardrailAPIInputs
|
||||
from litellm.types.utils import ChatCompletionMessageToolCall, GenericGuardrailAPIInputs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
|
|
@ -334,7 +333,7 @@ class GenericGuardrailAPI(CustomGuardrail):
|
|||
images: list[str] | None,
|
||||
tools: list[ChatCompletionToolParam] | None,
|
||||
guardrail_response: GenericGuardrailAPIResponse,
|
||||
tool_calls: GenericGuardrailAPIToolCalls | None = None,
|
||||
tool_calls: list[ChatCompletionToolCallChunk] | list[ChatCompletionMessageToolCall] | None = None,
|
||||
) -> GenericGuardrailAPIInputs:
|
||||
# Action is NONE or no modifications needed
|
||||
return_inputs: Final = GenericGuardrailAPIInputs(texts=texts)
|
||||
|
|
@ -348,16 +347,15 @@ class GenericGuardrailAPI(CustomGuardrail):
|
|||
return_inputs["tools"] = guardrail_response.tools
|
||||
elif tools:
|
||||
return_inputs["tools"] = tools
|
||||
returned_tool_calls: Final = guardrail_response.tool_calls
|
||||
if returned_tool_calls and not all(_returned_tool_call_is_usable(call) for call in returned_tool_calls):
|
||||
returned: Final = guardrail_response.tool_calls
|
||||
usable: Final = returned is not None and all(_returned_tool_call_is_usable(call) for call in returned)
|
||||
if returned and not usable:
|
||||
verbose_proxy_logger.warning(
|
||||
"Generic Guardrail API returned tool calls missing a function name or arguments; keeping the ones already sent",
|
||||
)
|
||||
returned_tool_calls = None # rebind-ok: an unusable reply is discarded
|
||||
if returned_tool_calls:
|
||||
return_inputs["tool_calls"] = returned_tool_calls
|
||||
elif tool_calls:
|
||||
return_inputs["tool_calls"] = tool_calls
|
||||
selected: Final = returned if usable else tool_calls
|
||||
if selected:
|
||||
return_inputs["tool_calls"] = selected
|
||||
if guardrail_response.stream_holdback_chars is not None:
|
||||
return_inputs["stream_holdback_chars"] = guardrail_response.stream_holdback_chars
|
||||
return return_inputs
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any, Final, Literal, TypeAlias
|
||||
from typing import Any, Final, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing_extensions import TypedDict
|
||||
|
|
@ -8,9 +8,7 @@ from litellm.types.llms.openai import (
|
|||
ChatCompletionToolCallChunk,
|
||||
)
|
||||
from litellm.types.proxy.guardrails.guardrail_hooks.base import GuardrailConfigModel
|
||||
from litellm.types.utils import ChatCompletionMessageToolCall, GenericGuardrailAPIInputs
|
||||
|
||||
GenericGuardrailAPIToolCalls: TypeAlias = GenericGuardrailAPIInputs["tool_calls"] # noqa: F821 # TypedDict field reference, not a name
|
||||
from litellm.types.utils import ChatCompletionMessageToolCall
|
||||
|
||||
|
||||
class GuardrailToolParam(BaseModel):
|
||||
|
|
@ -169,7 +167,7 @@ class GenericGuardrailAPIResponse:
|
|||
action: str
|
||||
blocked_reason: str | None
|
||||
stream_holdback_chars: list[int] | None
|
||||
tool_calls: GenericGuardrailAPIToolCalls | None
|
||||
tool_calls: list[ChatCompletionToolCallChunk] | list[ChatCompletionMessageToolCall] | None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -179,7 +177,7 @@ class GenericGuardrailAPIResponse:
|
|||
images: list[str] | None = None,
|
||||
tools: list[GuardrailToolParam] | None = None,
|
||||
stream_holdback_chars: list[int] | None = None,
|
||||
tool_calls: GenericGuardrailAPIToolCalls | None = None,
|
||||
tool_calls: list[ChatCompletionToolCallChunk] | list[ChatCompletionMessageToolCall] | None = None,
|
||||
) -> None:
|
||||
self.action = action
|
||||
self.blocked_reason = blocked_reason
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue