Python: added generic types to ChatOptions and ChatResponse/AgentResponse for Response Format (#3305)

* added generic types to ChatOptions and ChatResponse/AgentResponse for response format

* fix typevar import

* fix for older python versions

* fix missing import

* fixed imports

* fixed mypy

* mypy fix
This commit is contained in:
Eduard van Valkenburg
2026-01-28 22:23:02 +01:00
committed by GitHub
Unverified
parent 1f8463f9bb
commit 1226828ec2
42 changed files with 486 additions and 281 deletions
@@ -1,5 +1,5 @@
# Copyright (c) Microsoft. All rights reserved.
from typing import Annotated, Any, Literal
from typing import Annotated, Any, Literal, get_args, get_origin
from unittest.mock import Mock
import pytest
@@ -1493,8 +1493,6 @@ async def test_tool_with_kwargs_injection():
def test_parse_annotation_with_literal_type():
"""Test that _parse_annotation returns Literal types unchanged (issue #2891)."""
from typing import get_args, get_origin
# Literal with string values
literal_annotation = Literal["Data", "Security", "Network"]
result = _parse_annotation(literal_annotation)
@@ -1505,7 +1503,6 @@ def test_parse_annotation_with_literal_type():
def test_parse_annotation_with_literal_int_type():
"""Test that _parse_annotation returns Literal int types unchanged."""
from typing import get_args, get_origin
literal_annotation = Literal[1, 2, 3]
result = _parse_annotation(literal_annotation)
@@ -1516,7 +1513,6 @@ def test_parse_annotation_with_literal_int_type():
def test_parse_annotation_with_literal_bool_type():
"""Test that _parse_annotation returns Literal bool types unchanged."""
from typing import get_args, get_origin
literal_annotation = Literal[True, False]
result = _parse_annotation(literal_annotation)
@@ -1535,7 +1531,6 @@ def test_parse_annotation_with_simple_types():
def test_parse_annotation_with_annotated_and_literal():
"""Test that Annotated[Literal[...], description] works correctly."""
from typing import get_args, get_origin
# When Literal is inside Annotated, it should still be preserved
annotated_literal = Annotated[Literal["A", "B", "C"], "The category"]
+2 -16
View File
@@ -3,10 +3,10 @@
import base64
from collections.abc import AsyncIterable
from datetime import datetime, timezone
from typing import Any
from typing import Any, Literal
import pytest
from pydantic import BaseModel
from pydantic import BaseModel, Field, ValidationError
from pytest import fixture, mark, raises
from agent_framework import (
@@ -665,9 +665,6 @@ def test_chat_response_with_format_init():
def test_chat_response_value_raises_on_invalid_schema():
"""Test that value property raises ValidationError with field constraint details."""
from typing import Literal
from pydantic import Field, ValidationError
class StrictSchema(BaseModel):
id: Literal[5]
@@ -689,9 +686,6 @@ def test_chat_response_value_raises_on_invalid_schema():
def test_chat_response_try_parse_value_returns_none_on_invalid():
"""Test that try_parse_value returns None on validation failure with Field constraints."""
from typing import Literal
from pydantic import Field
class StrictSchema(BaseModel):
id: Literal[5]
@@ -707,7 +701,6 @@ def test_chat_response_try_parse_value_returns_none_on_invalid():
def test_chat_response_try_parse_value_returns_value_on_success():
"""Test that try_parse_value returns parsed value when all constraints pass."""
from pydantic import Field
class MySchema(BaseModel):
name: str = Field(min_length=3)
@@ -724,9 +717,6 @@ def test_chat_response_try_parse_value_returns_value_on_success():
def test_agent_response_value_raises_on_invalid_schema():
"""Test that AgentResponse.value property raises ValidationError with field constraint details."""
from typing import Literal
from pydantic import Field, ValidationError
class StrictSchema(BaseModel):
id: Literal[5]
@@ -748,9 +738,6 @@ def test_agent_response_value_raises_on_invalid_schema():
def test_agent_response_try_parse_value_returns_none_on_invalid():
"""Test that AgentResponse.try_parse_value returns None on Field constraint failure."""
from typing import Literal
from pydantic import Field
class StrictSchema(BaseModel):
id: Literal[5]
@@ -766,7 +753,6 @@ def test_agent_response_try_parse_value_returns_none_on_invalid():
def test_agent_response_try_parse_value_returns_value_on_success():
"""Test that AgentResponse.try_parse_value returns parsed value when all constraints pass."""
from pydantic import Field
class MySchema(BaseModel):
name: str = Field(min_length=3)
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft. All rights reserved.
import pytest
from typing_extensions import Never
from agent_framework import (
ChatMessage,
@@ -187,7 +188,6 @@ async def test_executor_completed_event_contains_sent_messages():
async def test_executor_completed_event_includes_yielded_outputs():
"""Test that ExecutorCompletedEvent.data includes yielded outputs."""
from typing_extensions import Never
from agent_framework import WorkflowOutputEvent
@@ -318,7 +318,6 @@ def test_executor_output_types_property():
def test_executor_workflow_output_types_property():
"""Test that the workflow_output_types property correctly identifies workflow output types."""
from typing_extensions import Never
# Test executor with no workflow output types
class NoWorkflowOutputExecutor(Executor):
@@ -42,9 +42,9 @@ from agent_framework import (
from agent_framework._workflows._checkpoint import InMemoryCheckpointStorage
if sys.version_info >= (3, 12):
from typing import override
from typing import override # type: ignore # pragma: no cover
else:
from typing_extensions import override
from typing_extensions import override # type: ignore # pragma: no cover
def test_magentic_context_reset_behavior():