Python: [BREAKING]: Introducing Options as TypedDict and Generic (#3140)

* WIP typeddict for options

* updated all clients and ChatAgents

* updated everything

* added ADR

* fix mypy

* proper typevar imports

* fixed import

* fixed other imports

* slight update in the sample

* updated from feedback

* fixes

* fixed missing covariants and test fixes

* fixed typing

* updated anthropic thinking config

* ruff fixes

* fixed int tests

* fix tests and mypy

* updated integration tests

* updated docstring and test fix

* improved options handling in obser

* mypy fix

* updated a host of integration tests

* fix tests

* bedrock fix
This commit is contained in:
Eduard van Valkenburg
2026-01-13 16:41:05 +00:00
committed by GitHub
parent 5faa2851bb
commit 3e97425245
111 changed files with 6141 additions and 4715 deletions
@@ -1,9 +1,5 @@
# Copyright (c) Microsoft. All rights reserved.
"""Unified Purview model definitions and public export surface."""
from __future__ import annotations
from collections.abc import Mapping, MutableMapping, Sequence
from datetime import datetime
from enum import Enum, Flag, auto
@@ -179,6 +175,8 @@ def translate_activity(activity: Activity) -> ProtectionScopeActivities:
# Simple value models
# --------------------------------------------------------------------------------------
TAliasSerializable = TypeVar("TAliasSerializable", bound="_AliasSerializable")
class _AliasSerializable(SerializationMixin):
"""Base class adding alias mapping + pydantic-compat helpers.
@@ -232,7 +230,7 @@ class _AliasSerializable(SerializationMixin):
return json.dumps(self.model_dump(by_alias=by_alias, exclude_none=exclude_none, **kwargs))
@classmethod
def model_validate(cls, value: MutableMapping[str, Any]) -> _AliasSerializable: # type: ignore[name-defined]
def model_validate(cls: type[TAliasSerializable], value: MutableMapping[str, Any]) -> TAliasSerializable: # type: ignore[name-defined]
return cls(**value)
# ------------------------------------------------------------------
@@ -37,7 +37,7 @@ class TestPurviewChatPolicyMiddleware:
chat_options = MagicMock()
chat_options.model = "test-model"
return ChatContext(
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], chat_options=chat_options
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], options=chat_options
)
async def test_initialization(self, middleware: PurviewChatPolicyMiddleware) -> None:
@@ -110,7 +110,7 @@ class TestPurviewChatPolicyMiddleware:
streaming_context = ChatContext(
chat_client=chat_client,
messages=[ChatMessage(role=Role.USER, text="Hello")],
chat_options=chat_options,
options=chat_options,
is_streaming=True,
)
with patch.object(middleware._processor, "process_messages", return_value=(False, "user-123")) as mock_proc:
@@ -189,7 +189,7 @@ class TestPurviewChatPolicyMiddleware:
chat_options = MagicMock()
chat_options.model = "test-model"
context = ChatContext(
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], chat_options=chat_options
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], options=chat_options
)
async def mock_process_messages(*args, **kwargs):
@@ -215,7 +215,7 @@ class TestPurviewChatPolicyMiddleware:
chat_options = MagicMock()
chat_options.model = "test-model"
context = ChatContext(
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], chat_options=chat_options
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], options=chat_options
)
async def mock_process_messages(*args, **kwargs):
@@ -257,7 +257,7 @@ class TestPurviewChatPolicyMiddleware:
chat_options = MagicMock()
chat_options.model = "test-model"
context = ChatContext(
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], chat_options=chat_options
chat_client=chat_client, messages=[ChatMessage(role=Role.USER, text="Hello")], options=chat_options
)
async def mock_process_messages(*args, **kwargs):