Python: [Breaking] removed pydantic from types and workflows (#917)

* removed pydantic from types

* fix test

* fix test

* fix tests

* fix assistants client

* Remove Pydantic usage from workflow code.

* updated pydantic removal

* updated lock and test fixes

* fix mypy

* updated build system

* updated chat client parsing

* fix broken test

---------

Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
This commit is contained in:
Eduard van Valkenburg
2025-09-29 23:19:58 +02:00
committed by GitHub
Unverified
parent 647db9635a
commit b4ebafa9b1
56 changed files with 3881 additions and 1735 deletions
@@ -3,7 +3,7 @@
import asyncio
from abc import ABC, abstractmethod
from collections.abc import AsyncIterable, Callable, MutableMapping, MutableSequence, Sequence
from typing import TYPE_CHECKING, Any, Generic, Literal, Protocol, TypeVar, runtime_checkable
from typing import TYPE_CHECKING, Any, Literal, Protocol, TypeVar, runtime_checkable
from pydantic import BaseModel, Field
@@ -25,8 +25,7 @@ from ._types import (
ChatOptions,
ChatResponse,
ChatResponseUpdate,
ChatToolMode,
GeneratedEmbeddings,
ToolMode,
)
if TYPE_CHECKING:
@@ -42,7 +41,6 @@ logger = get_logger()
__all__ = [
"BaseChatClient",
"ChatClientProtocol",
"EmbeddingGenerator",
]
@@ -73,7 +71,7 @@ class ChatClientProtocol(Protocol):
stop: str | Sequence[str] | None = None,
store: bool | None = None,
temperature: float | None = None,
tool_choice: ChatToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tool_choice: ToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
@@ -130,7 +128,7 @@ class ChatClientProtocol(Protocol):
stop: str | Sequence[str] | None = None,
store: bool | None = None,
temperature: float | None = None,
tool_choice: ChatToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tool_choice: ToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
@@ -310,7 +308,7 @@ class BaseChatClient(AFBaseModel, ABC):
stop: str | Sequence[str] | None = None,
store: bool | None = None,
temperature: float | None = None,
tool_choice: ChatToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tool_choice: ToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
@@ -354,7 +352,7 @@ class BaseChatClient(AFBaseModel, ABC):
raise TypeError("chat_options must be an instance of ChatOptions")
else:
chat_options = ChatOptions(
ai_model_id=model,
model_id=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
max_tokens=max_tokens,
@@ -392,7 +390,7 @@ class BaseChatClient(AFBaseModel, ABC):
stop: str | Sequence[str] | None = None,
store: bool | None = None,
temperature: float | None = None,
tool_choice: ChatToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tool_choice: ToolMode | Literal["auto", "required", "none"] | dict[str, Any] | None = "auto",
tools: ToolProtocol
| Callable[..., Any]
| MutableMapping[str, Any]
@@ -435,7 +433,7 @@ class BaseChatClient(AFBaseModel, ABC):
raise TypeError("chat_options must be an instance of ChatOptions")
else:
chat_options = ChatOptions(
ai_model_id=model,
model_id=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
max_tokens=max_tokens,
@@ -448,7 +446,7 @@ class BaseChatClient(AFBaseModel, ABC):
temperature=temperature,
top_p=top_p,
tool_choice=tool_choice,
tools=self._normalize_tools(tools), # type: ignore
tools=self._normalize_tools(tools),
user=user,
additional_properties=additional_properties or {},
)
@@ -467,15 +465,15 @@ class BaseChatClient(AFBaseModel, ABC):
This function should be overridden by subclasses to customize tool handling.
Because it currently parses only AIFunctions.
"""
chat_tool_mode: ChatToolMode | None = chat_options.tool_choice # type: ignore
if chat_tool_mode is None or chat_tool_mode == ChatToolMode.NONE:
chat_tool_mode = chat_options.tool_choice
if chat_tool_mode is None or chat_tool_mode == ToolMode.NONE or chat_tool_mode == "none":
chat_options.tools = None
chat_options.tool_choice = ChatToolMode.NONE.mode
chat_options.tool_choice = ToolMode.NONE.mode
return
if not chat_options.tools:
chat_options.tool_choice = ChatToolMode.NONE.mode
chat_options.tool_choice = ToolMode.NONE.mode
else:
chat_options.tool_choice = chat_tool_mode.mode
chat_options.tool_choice = chat_tool_mode.mode if isinstance(chat_tool_mode, ToolMode) else chat_tool_mode
def service_url(self) -> str:
"""Get the URL of the service.
@@ -528,28 +526,3 @@ class BaseChatClient(AFBaseModel, ABC):
middleware=middleware,
**kwargs,
)
# region Embedding Client
@runtime_checkable
class EmbeddingGenerator(Protocol, Generic[TInput, TEmbedding]):
"""A protocol for an embedding generator that can create embeddings from input data."""
async def generate(
self,
input_data: Sequence[TInput],
**kwargs: Any,
) -> GeneratedEmbeddings[TEmbedding]:
"""Generates an embedding for the given input data.
Args:
input_data: The input data to generate an embedding for.
**kwargs: Additional options for the request.
Returns:
The generated embedding, this acts like a list, but has additional metadata and usage details.
"""
...