mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
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:
committed by
GitHub
Unverified
parent
647db9635a
commit
b4ebafa9b1
@@ -28,12 +28,12 @@ from .._types import (
|
||||
ChatOptions,
|
||||
ChatResponse,
|
||||
ChatResponseUpdate,
|
||||
ChatToolMode,
|
||||
Contents,
|
||||
FunctionCallContent,
|
||||
FunctionResultContent,
|
||||
Role,
|
||||
TextContent,
|
||||
ToolMode,
|
||||
UriContent,
|
||||
UsageContent,
|
||||
UsageDetails,
|
||||
@@ -115,7 +115,7 @@ class OpenAIAssistantsClient(OpenAIConfigMixin, BaseChatClient):
|
||||
if not openai_settings.chat_model_id:
|
||||
raise ServiceInitializationError(
|
||||
"OpenAI model ID is required. "
|
||||
"Set via 'ai_model_id' parameter or 'OPENAI_CHAT_MODEL_ID' environment variable."
|
||||
"Set via 'model_id' parameter or 'OPENAI_CHAT_MODEL_ID' environment variable."
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
@@ -361,7 +361,7 @@ class OpenAIAssistantsClient(OpenAIConfigMixin, BaseChatClient):
|
||||
|
||||
if chat_options is not None:
|
||||
run_options["max_completion_tokens"] = chat_options.max_tokens
|
||||
run_options["model"] = chat_options.ai_model_id
|
||||
run_options["model"] = chat_options.model_id
|
||||
run_options["top_p"] = chat_options.top_p
|
||||
run_options["temperature"] = chat_options.temperature
|
||||
|
||||
@@ -392,7 +392,7 @@ class OpenAIAssistantsClient(OpenAIConfigMixin, BaseChatClient):
|
||||
if chat_options.tool_choice == "none" or chat_options.tool_choice == "auto":
|
||||
run_options["tool_choice"] = chat_options.tool_choice
|
||||
elif (
|
||||
isinstance(chat_options.tool_choice, ChatToolMode)
|
||||
isinstance(chat_options.tool_choice, ToolMode)
|
||||
and chat_options.tool_choice == "required"
|
||||
and chat_options.tool_choice.required_function_name is not None
|
||||
):
|
||||
|
||||
@@ -217,7 +217,7 @@ class OpenAIBaseChatClient(OpenAIBase, BaseChatClient):
|
||||
return ChatResponseUpdate(
|
||||
role=Role.ASSISTANT,
|
||||
contents=[UsageContent(details=self._usage_details_from_openai(chunk.usage), raw_representation=chunk)],
|
||||
ai_model_id=chunk.model,
|
||||
model_id=chunk.model,
|
||||
additional_properties=chunk_metadata,
|
||||
response_id=chunk.id,
|
||||
message_id=chunk.id,
|
||||
@@ -236,7 +236,7 @@ class OpenAIBaseChatClient(OpenAIBase, BaseChatClient):
|
||||
created_at=datetime.fromtimestamp(chunk.created).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
contents=contents,
|
||||
role=Role.ASSISTANT,
|
||||
ai_model_id=chunk.model,
|
||||
model_id=chunk.model,
|
||||
additional_properties=chunk_metadata,
|
||||
finish_reason=finish_reason,
|
||||
raw_representation=chunk,
|
||||
@@ -402,8 +402,8 @@ class OpenAIBaseChatClient(OpenAIBase, BaseChatClient):
|
||||
elif content.media_type and "mp3" in content.media_type:
|
||||
audio_format = "mp3"
|
||||
else:
|
||||
# Fallback to default model_dump for unsupported audio formats
|
||||
return content.model_dump(exclude_none=True)
|
||||
# Fallback to default to_dict for unsupported audio formats
|
||||
return content.to_dict(exclude_none=True)
|
||||
|
||||
# Extract base64 data from data URI
|
||||
audio_data = content.uri
|
||||
@@ -435,11 +435,11 @@ class OpenAIBaseChatClient(OpenAIBase, BaseChatClient):
|
||||
},
|
||||
}
|
||||
|
||||
return content.model_dump(exclude_none=True)
|
||||
return content.to_dict(exclude_none=True)
|
||||
|
||||
return content.model_dump(exclude_none=True)
|
||||
return content.to_dict(exclude_none=True)
|
||||
case _:
|
||||
return content.model_dump(exclude_none=True)
|
||||
return content.to_dict(exclude_none=True)
|
||||
|
||||
@override
|
||||
def service_url(self) -> str:
|
||||
|
||||
@@ -905,7 +905,7 @@ class OpenAIBaseResponsesClient(OpenAIBase, BaseChatClient):
|
||||
contents=contents,
|
||||
conversation_id=conversation_id,
|
||||
role=Role.ASSISTANT,
|
||||
ai_model_id=model,
|
||||
model_id=model,
|
||||
additional_properties=metadata,
|
||||
raw_representation=event,
|
||||
)
|
||||
|
||||
@@ -17,13 +17,13 @@ from openai.types.chat import ChatCompletion, ChatCompletionChunk
|
||||
from openai.types.images_response import ImagesResponse
|
||||
from openai.types.responses.response import Response
|
||||
from openai.types.responses.response_stream_event import ResponseStreamEvent
|
||||
from pydantic import BaseModel, ConfigDict, Field, SecretStr, validate_call
|
||||
from pydantic import ConfigDict, Field, SecretStr, validate_call
|
||||
from pydantic.types import StringConstraints
|
||||
|
||||
from .._logging import get_logger
|
||||
from .._pydantic import AFBaseModel, AFBaseSettings
|
||||
from .._telemetry import APP_INFO, USER_AGENT_KEY, prepend_agent_framework_to_user_agent
|
||||
from .._types import ChatOptions, Contents, SpeechToTextOptions, TextToSpeechOptions
|
||||
from .._types import ChatOptions, Contents
|
||||
from ..exceptions import ServiceInitializationError
|
||||
|
||||
logger: logging.Logger = get_logger("agent_framework.openai")
|
||||
@@ -42,7 +42,7 @@ RESPONSE_TYPE = Union[
|
||||
_legacy_response.HttpxBinaryResponseContent,
|
||||
]
|
||||
|
||||
OPTION_TYPE = Union[ChatOptions, SpeechToTextOptions, TextToSpeechOptions, dict[str, Any]]
|
||||
OPTION_TYPE = Union[ChatOptions, dict[str, Any]]
|
||||
|
||||
|
||||
__all__ = [
|
||||
@@ -52,20 +52,20 @@ __all__ = [
|
||||
|
||||
def _prepare_function_call_results_as_dumpable(content: Contents | Any | list[Contents | Any]) -> Any:
|
||||
if isinstance(content, list):
|
||||
# Particularly deal with lists of BaseModel
|
||||
# Particularly deal with lists of Content
|
||||
return [_prepare_function_call_results_as_dumpable(item) for item in content]
|
||||
if isinstance(content, dict):
|
||||
return {k: _prepare_function_call_results_as_dumpable(v) for k, v in content.items()}
|
||||
if isinstance(content, BaseModel):
|
||||
return content.model_dump(exclude={"raw_representation", "additional_properties"})
|
||||
if hasattr(content, "to_dict"):
|
||||
return content.to_dict(exclude={"raw_representation", "additional_properties"})
|
||||
return content
|
||||
|
||||
|
||||
def prepare_function_call_results(content: Contents | Any | list[Contents | Any]) -> str | list[str]:
|
||||
"""Prepare the values of the function call results."""
|
||||
if isinstance(content, BaseModel):
|
||||
# BaseModel is already dumpable, shortcut for performance
|
||||
return content.model_dump_json(exclude={"raw_representation", "additional_properties"})
|
||||
if isinstance(content, Contents):
|
||||
# For BaseContent objects, use to_dict and serialize to JSON
|
||||
return json.dumps(content.to_dict(exclude={"raw_representation", "additional_properties"}))
|
||||
|
||||
dumpable = _prepare_function_call_results_as_dumpable(content)
|
||||
if isinstance(dumpable, str):
|
||||
|
||||
Reference in New Issue
Block a user