diff --git a/sdk/agentserver/azure-ai-agentserver-core/CHANGELOG.md b/sdk/agentserver/azure-ai-agentserver-core/CHANGELOG.md index 54b64fd3e6c1..8891a5c6b131 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/CHANGELOG.md +++ b/sdk/agentserver/azure-ai-agentserver-core/CHANGELOG.md @@ -1,5 +1,17 @@ # Release History +## 2.0.0b7 (Unreleased) + +### Features Added + +- Container protocol version `2.0.0` support: added the platform identity header constants `x-agent-user-id` (`USER_ID`) — the global, cross-agent per-user partition key — and `x-agent-foundry-call-id` (`FOUNDRY_CALL_ID`) — the opaque per-request call identifier — to the `_platform_headers` module. +- Added `FOUNDRY_AGENT_ID` environment variable support exposing the agent's stable GUID via `AgentConfig.agent_guid` and the `resolve_agent_guid()` helper. +- Added a request-scoped platform context: `FoundryAgentRequestContext`, `get_request_context()`, `set_request_context()`, and `reset_request_context()`. Protocol packages bind the inbound per-request call ID and user ID so that handler code (and the SDK HTTP pipeline) can read them. `FoundryAgentRequestContext.platform_headers()` builds the headers to forward on outbound Foundry 1P calls — the per-request call ID only; `x-agent-user-id` is **not** forwarded (it is not accepted/trusted by 1P services and is used only for container-side state partitioning). + +### Breaking Changes + +- Replaced the `x-agent-user-isolation-key` / `x-agent-chat-isolation-key` header constants (`USER_ISOLATION_KEY` / `CHAT_ISOLATION_KEY`) with `x-agent-user-id` (`USER_ID`) and `x-agent-foundry-call-id` (`FOUNDRY_CALL_ID`) per container protocol version `2.0.0`. + ## 2.0.0b6 (2026-06-12) ### Bugs Fixed diff --git a/sdk/agentserver/azure-ai-agentserver-core/README.md b/sdk/agentserver/azure-ai-agentserver-core/README.md index add29e0bb57b..2a9d56c42346 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/README.md +++ b/sdk/agentserver/azure-ai-agentserver-core/README.md @@ -60,6 +60,36 @@ async def handle(request): app.run() ``` +### Per-request identity (multi-user sessions) + +On container protocol `2.0.0` a single agent session can serve **multiple users**. Each request carries `x-agent-user-id` (the user — partition state by it) and an opaque `x-agent-foundry-call-id` (the per-request caller identity). Read both via `get_request_context()`; the SDK forwards **only** the call ID on outbound Foundry calls — `x-agent-user-id` is never echoed. Forwarding the call ID lets a tool server resolve which user made the request and act on their behalf. + +```python +import os + +import httpx +from azure.ai.agentserver.core import get_request_context + + +def foundry_headers() -> dict[str, str]: + # Echoes x-agent-foundry-call-id only; x-agent-user-id is never forwarded. + return dict(get_request_context().platform_headers()) + + +async def call_toolbox(query: str) -> str: + user_id = get_request_context().user_id # for the container's OWN per-user state + # Attach the call ID PER CALL — a toolbox MCP session is long-lived and serves many + # users/turns, so never bake one call's ID into the client's static headers. + async with httpx.AsyncClient() as mcp: + resp = await mcp.post( + f"{os.environ['FOUNDRY_PROJECT_ENDPOINT']}/toolboxes/github/mcp", + headers={"Authorization": f"Bearer {get_agent_token()}", **foundry_headers()}, + json={"jsonrpc": "2.0", "method": "tools/call", + "params": {"name": "list_my_assigned_issues", "arguments": {}}}, + ) + return resp.text # the toolbox resolved the caller from the call ID and acted as that user +``` + ### Subclassing AgentServerHost For custom protocol implementations, subclass `AgentServerHost` and add routes: diff --git a/sdk/agentserver/azure-ai-agentserver-core/api.md b/sdk/agentserver/azure-ai-agentserver-core/api.md new file mode 100644 index 000000000000..d3aafdb8a0bd --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-core/api.md @@ -0,0 +1,205 @@ +```py +namespace azure.ai.agentserver.core + + def azure.ai.agentserver.core.build_server_version(sdk_name: str, version: str) -> str: ... + + + def azure.ai.agentserver.core.configure_observability( + *, + connection_string: Optional[str] = ..., + enable_sensitive_data: bool = False, + log_level: Optional[str] = ... + ) -> None: ... + + + def azure.ai.agentserver.core.create_error_response( + code: str, + message: str, + *, + details: Optional[list[dict[str, Any]]] = ..., + error_type: Optional[str] = ..., + headers: Optional[dict[str, str]] = ..., + status_code: int + ) -> JSONResponse: ... + + + def azure.ai.agentserver.core.detach_context(token: Any) -> None: ... + + + def azure.ai.agentserver.core.end_span(span: Any, exc: Optional[BaseException] = None) -> None: ... + + + def azure.ai.agentserver.core.flush_spans(timeout_millis: int = 5000) -> None: ... + + + def azure.ai.agentserver.core.get_request_context() -> FoundryAgentRequestContext: ... + + + def azure.ai.agentserver.core.record_error(span: Any, exc: BaseException) -> None: ... + + + def azure.ai.agentserver.core.reset_request_context(token: Token[FoundryAgentRequestContext]) -> None: ... + + + def azure.ai.agentserver.core.set_current_span(span: Any) -> Any: ... + + + def azure.ai.agentserver.core.set_request_context(context: FoundryAgentRequestContext) -> Token[FoundryAgentRequestContext]: ... + + + async def azure.ai.agentserver.core.trace_stream:async(iterator: AsyncIterable[_Content], span: Any) -> AsyncIterator[_Content]: ... + + + class azure.ai.agentserver.core.AgentConfig: + + def __init__( + self, + *, + agent_guid: str = "", + agent_id: str, + agent_name: str, + agent_version: str, + appinsights_connection_string: str, + is_hosted: bool, + otlp_endpoint: str, + port: int, + project_endpoint: str, + project_id: str, + session_id: str, + sse_keepalive_interval: int, + ws_ping_interval: float = 0.0 + ) -> None: ... + + @classmethod + def from_env(cls) -> Self: ... + + + class azure.ai.agentserver.core.AgentServerHost(Starlette): + property routes: list[BaseRoute] # Read-only + + async def __call__( + self, + scope: Scope, + receive: Receive, + send: Send + ) -> None: ... + + def __init__( + self, + *, + access_log: Optional[Logger] = _SENTINEL_ACCESS_LOG, + access_log_format: Optional[str] = ..., + applicationinsights_connection_string: Optional[str] = ..., + configure_observability: Optional[Callable[, None]] = _tracing.configure_observability, + graceful_shutdown_timeout: Optional[int] = ..., + log_level: Optional[str] = ..., + routes: Optional[list[Route]] = ..., + **kwargs: Any + ) -> None: ... + + def add_exception_handler( + self, + exc_class_or_status_code: int | type[Exception], + handler: ExceptionHandler + ) -> None: ... + + def add_middleware( + self, + middleware_class: _MiddlewareFactory[P], + *args: args, + **kwargs: kwargs + ) -> None: ... + + def add_route( + self, + path: str, + route: Callable[[Request], Awaitable[Response] | Response], + methods: list[str] | None = None, + name: str | None = None, + include_in_schema: bool = True + ) -> None: ... + + def build_middleware_stack(self) -> ASGIApp: ... + + def host( + self, + host: str, + app: ASGIApp, + name: str | None = None + ) -> None: ... + + def mount( + self, + path: str, + app: ASGIApp, + name: str | None = None + ) -> None: ... + + def register_server_version(self, version_segment: str) -> None: ... + + def run( + self, + host: str = "0.0.0.0", + port: Optional[int] = None + ) -> None: ... + + async def run_async( + self, + host: str = "0.0.0.0", + port: Optional[int] = None + ) -> None: ... + + def shutdown_handler(self, fn: Callable[[], Awaitable[None]]) -> Callable[[], Awaitable[None]]: ... + + @staticmethod + async def sse_keepalive_stream(iterator: AsyncIterable[_Content], interval: int) -> AsyncIterator[_Content]: ... + + def url_path_for( + self, + name: str, + /, + **path_params: Any + ) -> URLPath: ... + + + class azure.ai.agentserver.core.FoundryAgentRequestContext: + call_id: str | None + session_id: str | None + user_id: str | None + + def __init__( + self, + *, + call_id: str | None = ..., + session_id: str | None = ..., + user_id: str | None = ... + ) -> None: ... + + def platform_headers(self) -> dict[str, str]: ... + + + class azure.ai.agentserver.core.InboundRequestLoggingMiddleware: + + async def __call__( + self, + scope: Scope, + receive: Receive, + send: Send + ) -> None: ... + + def __init__(self, app: ASGIApp) -> None: ... + + + class azure.ai.agentserver.core.RequestIdMiddleware: + + async def __call__( + self, + scope: Scope, + receive: Receive, + send: Send + ) -> None: ... + + def __init__(self, app: ASGIApp) -> None: ... + + +``` \ No newline at end of file diff --git a/sdk/agentserver/azure-ai-agentserver-core/api.metadata.yml b/sdk/agentserver/azure-ai-agentserver-core/api.metadata.yml new file mode 100644 index 000000000000..ae26722896e3 --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-core/api.metadata.yml @@ -0,0 +1,3 @@ +apiMdSha256: cbbfb5e77c255601f97cc31505d7e0962ac3eeb665c690659064b2bd4940071e +parserVersion: 0.3.28 +pythonVersion: 3.11.9 diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/__init__.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/__init__.py index d360a00966a8..1c08b10f13c6 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/__init__.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/__init__.py @@ -11,11 +11,13 @@ from azure.ai.agentserver.core import ( AgentConfig, AgentServerHost, + FoundryAgentRequestContext, configure_observability, create_error_response, detach_context, end_span, flush_spans, + get_request_context, record_error, set_current_span, trace_stream, @@ -27,6 +29,12 @@ from ._config import AgentConfig from ._errors import create_error_response from ._middleware import InboundRequestLoggingMiddleware +from ._request_context import ( + FoundryAgentRequestContext, + get_request_context, + reset_request_context, + set_request_context, +) from ._request_id import RequestIdMiddleware from ._server_version import build_server_version from ._tracing import ( @@ -44,6 +52,7 @@ "AgentConfig", "AgentServerHost", "InboundRequestLoggingMiddleware", + "FoundryAgentRequestContext", "RequestIdMiddleware", "build_server_version", "configure_observability", @@ -51,8 +60,11 @@ "detach_context", "end_span", "flush_spans", + "get_request_context", "record_error", + "reset_request_context", "set_current_span", + "set_request_context", "trace_stream", ] __version__ = VERSION diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_config.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_config.py index 493f58794776..5804ec34b05a 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_config.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_config.py @@ -23,6 +23,7 @@ # ====================================================================== _ENV_FOUNDRY_AGENT_NAME = "FOUNDRY_AGENT_NAME" +_ENV_FOUNDRY_AGENT_ID = "FOUNDRY_AGENT_ID" _ENV_FOUNDRY_AGENT_VERSION = "FOUNDRY_AGENT_VERSION" _ENV_FOUNDRY_AGENT_INSTANCE_CLIENT_ID = "FOUNDRY_AGENT_INSTANCE_CLIENT_ID" _ENV_FOUNDRY_AGENT_BLUEPRINT_CLIENT_ID = "FOUNDRY_AGENT_BLUEPRINT_CLIENT_ID" @@ -60,6 +61,7 @@ class AgentConfig: # pylint: disable=too-many-instance-attributes :param agent_name: Agent name from ``FOUNDRY_AGENT_NAME``. :param agent_version: Agent version from ``FOUNDRY_AGENT_VERSION``. :param agent_id: Combined identifier (``"name:version"`` or ``"name"`` or ``""``). + :param agent_guid: Agent stable identifier (GUID) from ``FOUNDRY_AGENT_ID``. :param is_hosted: Whether the agent is running in a Foundry-hosted container environment, derived from ``FOUNDRY_HOSTING_ENVIRONMENT``. :param project_endpoint: Foundry project endpoint from ``FOUNDRY_PROJECT_ENDPOINT``. @@ -79,6 +81,7 @@ def __init__( agent_name: str, agent_version: str, agent_id: str, + agent_guid: str = "", is_hosted: bool, project_endpoint: str, project_id: str, @@ -92,6 +95,7 @@ def __init__( self.agent_name = agent_name self.agent_version = agent_version self.agent_id = agent_id + self.agent_guid = agent_guid self.is_hosted = is_hosted self.project_endpoint = project_endpoint self.project_id = project_id @@ -123,6 +127,7 @@ def from_env(cls) -> Self: agent_name=agent_name, agent_version=agent_version, agent_id=agent_id, + agent_guid=os.environ.get(_ENV_FOUNDRY_AGENT_ID, ""), is_hosted=bool(os.environ.get(_ENV_FOUNDRY_HOSTING_ENVIRONMENT, "")), project_endpoint=os.environ.get(_ENV_FOUNDRY_PROJECT_ENDPOINT, ""), project_id=os.environ.get(_ENV_FOUNDRY_PROJECT_ARM_ID, ""), @@ -315,6 +320,15 @@ def resolve_agent_id() -> str: return agent_name +def resolve_agent_guid() -> str: + """Resolve the agent stable GUID from the ``FOUNDRY_AGENT_ID`` environment variable. + + :return: The agent GUID, or an empty string if not set. + :rtype: str + """ + return os.environ.get(_ENV_FOUNDRY_AGENT_ID, "") + + def resolve_agent_blueprint_id() -> str: """Resolve the agent blueprint client ID from the ``FOUNDRY_AGENT_BLUEPRINT_CLIENT_ID`` environment variable. diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_constants.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_constants.py index 93e017f0ca8b..21f1286390cd 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_constants.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_constants.py @@ -8,6 +8,7 @@ class Constants: # Foundry identity FOUNDRY_AGENT_NAME = "FOUNDRY_AGENT_NAME" + FOUNDRY_AGENT_ID = "FOUNDRY_AGENT_ID" FOUNDRY_AGENT_VERSION = "FOUNDRY_AGENT_VERSION" FOUNDRY_PROJECT_ENDPOINT = "FOUNDRY_PROJECT_ENDPOINT" FOUNDRY_PROJECT_ARM_ID = "FOUNDRY_PROJECT_ARM_ID" diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_platform_headers.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_platform_headers.py index af69142d40bc..6525b78850e3 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_platform_headers.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_platform_headers.py @@ -21,7 +21,8 @@ **Request headers** (set by the platform or client): - :data:`REQUEST_ID` — client-provided correlation ID (echoed back on the response). -- :data:`USER_ISOLATION_KEY` / :data:`CHAT_ISOLATION_KEY` — platform isolation keys. +- :data:`USER_ID` — platform per-user (global, cross-agent) identity header. +- :data:`FOUNDRY_CALL_ID` — platform per-request opaque call identifier (protocol ``2.0.0``). - :data:`CLIENT_HEADER_PREFIX` — prefix for pass-through client headers. - :data:`TRACEPARENT` — W3C Trace Context propagation header. - :data:`CLIENT_REQUEST_ID` — Azure SDK client correlation header. @@ -50,16 +51,28 @@ Set on responses by protocol-specific session resolution logic. """ -# -- Platform isolation ----------------------------------------------------- +# -- Platform identity ------------------------------------------------------ -USER_ISOLATION_KEY: str = "x-agent-user-isolation-key" -"""The ``x-agent-user-isolation-key`` header — the platform-injected -partition key for user-private state. +USER_ID: str = "x-agent-user-id" +"""The ``x-agent-user-id`` header — the platform-injected global, +cross-agent partition key for per-user state. + +The same user yields the same value regardless of which agent they +interact with. Use it as the primary partition key for per-user data +(profiles, preferences, OAuth tokens, memory). Present on protocol +requests (not health probes); absent during local development. """ -CHAT_ISOLATION_KEY: str = "x-agent-chat-isolation-key" -"""The ``x-agent-chat-isolation-key`` header — the platform-injected -partition key for conversation-scoped state. +FOUNDRY_CALL_ID: str = "x-agent-foundry-call-id" +"""The ``x-agent-foundry-call-id`` header — the platform-minted opaque +per-request call identifier. + +Present only when the agent definition declares container protocol +version ``2.0.0``. The container **MUST** forward this value on all +outbound calls to Foundry platform services (Storage, Toolboxes/MCP +proxy, A2A) so that 1P services can resolve the server-side-stored +caller context. The container never parses it. Absent under protocol +version ``1.0.0`` or local development. """ # -- Client pass-through --------------------------------------------------- diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_request_context.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_request_context.py new file mode 100644 index 000000000000..545360b39911 --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_request_context.py @@ -0,0 +1,131 @@ +# --------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# --------------------------------------------------------- +"""Request-scoped platform context for AgentServer containers. + +On container protocol version ``2.0.0`` the platform delivers a per-request +opaque call identifier (``x-agent-foundry-call-id``) plus a global per-user +identity header (``x-agent-user-id``). The container **MUST** forward these on +all outbound calls to Foundry platform services (Storage, Toolboxes/MCP proxy, +A2A) routed through ``FOUNDRY_PROJECT_ENDPOINT``. + +This module stores those values in a :class:`~contextvars.ContextVar` so that +they are available to any code running during request processing — including +handler code making raw ``httpx`` calls and the SDK's own HTTP pipeline — without +threading them through every call signature. + +Inbound protocol endpoints populate the context via :func:`set_request_context` +(internal); handler/tool code reads it via :func:`get_request_context` (public), +mirroring the hero samples in the container protocol spec:: + + from azure.ai.agentserver.core import get_request_context + + ctx = get_request_context() + headers = {"x-agent-foundry-call-id": ctx.call_id} if ctx.call_id else {} +""" + +from __future__ import annotations + +from contextvars import ContextVar, Token + +from ._platform_headers import FOUNDRY_CALL_ID + +__all__ = [ + "FoundryAgentRequestContext", + "get_request_context", + "set_request_context", + "reset_request_context", +] + + +class FoundryAgentRequestContext: + """Platform-supplied, request-scoped identity context. + + Populated by the protocol endpoint from inbound platform headers on every + request. All fields are ``None`` when the corresponding header was absent + (e.g. local development, or ``call_id`` under protocol version ``1.0.0``). + + :ivar call_id: Opaque per-request call identifier from ``x-agent-foundry-call-id`` + (protocol version ``2.0.0`` only). Forward verbatim on outbound Foundry + calls; never parse it. + :vartype call_id: str | None + :ivar user_id: Global, cross-agent per-user identity from ``x-agent-user-id``. + :vartype user_id: str | None + :ivar session_id: The resolved session ID for the request, when available. + :vartype session_id: str | None + """ + + __slots__ = ("call_id", "user_id", "session_id") + + def __init__( + self, + *, + call_id: str | None = None, + user_id: str | None = None, + session_id: str | None = None, + ) -> None: + self.call_id = call_id + self.user_id = user_id + self.session_id = session_id + + def platform_headers(self) -> dict[str, str]: + """Build the platform identity headers to forward on outbound 1P calls. + + Only ``x-agent-foundry-call-id`` is forwarded: 1P services resolve the + caller context server-side from the opaque call ID. ``x-agent-user-id`` + is **not** forwarded — it is not accepted/trusted by 1P services and is + only consumed container-side for per-user state partitioning. The call ID + is included only when present (non-``None``). The managed-identity + ``Authorization`` header is unaffected — this is an **additional** header + for caller-identity context. + + :return: A mapping of header name to value, suitable for merging into an + outbound request's headers. + :rtype: dict[str, str] + """ + headers: dict[str, str] = {} + if self.call_id is not None: + headers[FOUNDRY_CALL_ID] = self.call_id + return headers + + +_EMPTY = FoundryAgentRequestContext() + +_request_context_var: ContextVar[FoundryAgentRequestContext] = ContextVar("agentserver_request_context") + + +def get_request_context() -> FoundryAgentRequestContext: + """Return the platform context for the current request. + + Safe to call from anywhere during request processing. When no context has + been established (e.g. outside a request, or local development), an empty + :class:`FoundryAgentRequestContext` with all-``None`` fields is returned. + + :return: The current request-scoped platform context. + :rtype: FoundryAgentRequestContext + """ + return _request_context_var.get(_EMPTY) + + +def set_request_context(context: FoundryAgentRequestContext) -> Token[FoundryAgentRequestContext]: + """Bind ``context`` as the current request context (internal). + + Called by protocol endpoints at the start of request handling. The returned + token should be passed to :func:`reset_request_context` when the request + completes to avoid leaking context across requests on the same task. + + :param context: The request context to bind. + :type context: FoundryAgentRequestContext + :return: A reset token for restoring the previous value. + :rtype: ~contextvars.Token + """ + return _request_context_var.set(context) + + +def reset_request_context(token: Token[FoundryAgentRequestContext]) -> None: + """Restore the request context to its previous value (internal). + + :param token: The token returned by :func:`set_request_context`. + :type token: ~contextvars.Token + """ + _request_context_var.reset(token) diff --git a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_version.py b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_version.py index 2577b81a5658..369f0dcc3bea 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_version.py +++ b/sdk/agentserver/azure-ai-agentserver-core/azure/ai/agentserver/core/_version.py @@ -2,4 +2,4 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # --------------------------------------------------------- -VERSION = "2.0.0b6" +VERSION = "2.0.0b7" diff --git a/sdk/agentserver/azure-ai-agentserver-core/tests/test_config.py b/sdk/agentserver/azure-ai-agentserver-core/tests/test_config.py index be194e6ec0fd..af18a8d84846 100644 --- a/sdk/agentserver/azure-ai-agentserver-core/tests/test_config.py +++ b/sdk/agentserver/azure-ai-agentserver-core/tests/test_config.py @@ -37,3 +37,26 @@ def test_is_hosted_snapshotted_at_creation(self, monkeypatch: pytest.MonkeyPatch # Changing the env var after creation must not affect the already-created config. monkeypatch.delenv("FOUNDRY_HOSTING_ENVIRONMENT") assert config.is_hosted is True + + +class TestAgentConfigAgentGuid: + """Tests for the FOUNDRY_AGENT_ID (agent_guid) resolution.""" + + def test_agent_guid_from_env(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("FOUNDRY_AGENT_ID", "11111111-2222-3333-4444-555555555555") + config = AgentConfig.from_env() + assert config.agent_guid == "11111111-2222-3333-4444-555555555555" + + def test_agent_guid_empty_when_absent(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.delenv("FOUNDRY_AGENT_ID", raising=False) + config = AgentConfig.from_env() + assert config.agent_guid == "" + + def test_agent_guid_distinct_from_composite_agent_id(self, monkeypatch: pytest.MonkeyPatch) -> None: + """agent_guid (GUID) is independent of the name:version composite agent_id.""" + monkeypatch.setenv("FOUNDRY_AGENT_NAME", "weather") + monkeypatch.setenv("FOUNDRY_AGENT_VERSION", "1") + monkeypatch.setenv("FOUNDRY_AGENT_ID", "guid-abc") + config = AgentConfig.from_env() + assert config.agent_id == "weather:1" + assert config.agent_guid == "guid-abc" diff --git a/sdk/agentserver/azure-ai-agentserver-core/tests/test_request_context.py b/sdk/agentserver/azure-ai-agentserver-core/tests/test_request_context.py new file mode 100644 index 000000000000..9c59cb2af7ac --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-core/tests/test_request_context.py @@ -0,0 +1,63 @@ +# --------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# --------------------------------------------------------- +"""Unit tests for the request-scoped platform context.""" +from __future__ import annotations + +import asyncio + +from azure.ai.agentserver.core import ( + FoundryAgentRequestContext, + get_request_context, + reset_request_context, + set_request_context, +) +from azure.ai.agentserver.core._platform_headers import FOUNDRY_CALL_ID, USER_ID + + +class TestRequestContext: + def test_default_is_empty(self) -> None: + ctx = get_request_context() + assert ctx.call_id is None + assert ctx.user_id is None + assert ctx.session_id is None + + def test_set_and_reset(self) -> None: + token = set_request_context( + FoundryAgentRequestContext(call_id="c1", user_id="u1", session_id="s1") + ) + try: + ctx = get_request_context() + assert ctx.call_id == "c1" + assert ctx.user_id == "u1" + assert ctx.session_id == "s1" + finally: + reset_request_context(token) + assert get_request_context().call_id is None + + def test_platform_headers_includes_call_id(self) -> None: + ctx = FoundryAgentRequestContext(call_id="cid", user_id="uid") + headers = ctx.platform_headers() + # Only the call ID is forwarded to 1P services; user_id is not. + assert headers == {FOUNDRY_CALL_ID: "cid"} + assert USER_ID not in headers + + def test_platform_headers_omits_absent_values(self) -> None: + assert FoundryAgentRequestContext().platform_headers() == {} + # user_id alone never produces an outbound header. + assert FoundryAgentRequestContext(user_id="uid").platform_headers() == {} + assert FoundryAgentRequestContext(call_id="cid").platform_headers() == {FOUNDRY_CALL_ID: "cid"} + + def test_context_propagates_into_child_task(self) -> None: + async def _run() -> FoundryAgentRequestContext: + set_request_context(FoundryAgentRequestContext(call_id="task-cid", user_id="task-uid")) + + async def _child() -> FoundryAgentRequestContext: + return get_request_context() + + # Child task created in this scope inherits the current context. + return await asyncio.create_task(_child()) + + ctx = asyncio.run(_run()) + assert ctx.call_id == "task-cid" + assert ctx.user_id == "task-uid" diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/CHANGELOG.md b/sdk/agentserver/azure-ai-agentserver-invocations/CHANGELOG.md index 5d0d19f060a7..9106cf7fa345 100644 --- a/sdk/agentserver/azure-ai-agentserver-invocations/CHANGELOG.md +++ b/sdk/agentserver/azure-ai-agentserver-invocations/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History +## 1.0.0b6 (Unreleased) + +### Features Added + +- Container protocol version `2.0.0` support: reads `x-agent-user-id` and `x-agent-foundry-call-id` from inbound requests and binds them to the request-scoped platform context so the per-request call ID is forwarded on outbound Foundry 1P calls (`x-agent-user-id` is not forwarded to 1P). The values are also exposed on `request.state.user_id` and `request.state.call_id`. + +### Breaking Changes + +- Replaced `request.state.user_isolation_key` / `request.state.chat_isolation_key` with `request.state.user_id` / `request.state.call_id` per container protocol version `2.0.0`. + ## 1.0.0b5 (2026-06-12) ### Bugs Fixed diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/README.md b/sdk/agentserver/azure-ai-agentserver-invocations/README.md index 913e95d7329e..aa06d288917e 100644 --- a/sdk/agentserver/azure-ai-agentserver-invocations/README.md +++ b/sdk/agentserver/azure-ai-agentserver-invocations/README.md @@ -65,6 +65,8 @@ Inside handler functions, the SDK sets these attributes on `request.state`: - `request.state.invocation_id` — The invocation ID (echoed or generated). - `request.state.session_id` — The resolved session ID (POST /invocations only). +- `request.state.user_id` — The per-user ID from `x-agent-user-id` (container protocol `2.0.0`); use for per-user state. +- `request.state.call_id` — The per-request call ID from `x-agent-foundry-call-id` (protocol `2.0.0`); forward on outbound Foundry calls. ### Distributed tracing @@ -95,6 +97,42 @@ async def handle(request: Request) -> Response: app.run() ``` +### Multi-user session (per-request call ID) + +On container protocol `2.0.0` a single agent session can serve **multiple users**. Forwarding the per-request `x-agent-foundry-call-id` on outbound toolbox calls lets the tool server resolve *which* user made this request and act on their behalf. (`x-agent-user-id` is never forwarded; the tool resolves the user from the call ID server-side. Use `request.state.user_id` only for the container's own per-user state.) + +```python +import os + +import httpx +from azure.ai.agentserver.core import get_request_context +from azure.ai.agentserver.invocations import InvocationAgentServerHost +from starlette.requests import Request +from starlette.responses import JSONResponse, Response + +app = InvocationAgentServerHost() + + +@app.invoke_handler +async def handle(request: Request) -> Response: + # platform_headers() echoes x-agent-foundry-call-id only (never x-agent-user-id). + headers = get_request_context().platform_headers() + + # Toolbox / MCP — attach the call ID PER CALL (the MCP session is shared across users/turns). + async with httpx.AsyncClient() as mcp: + resp = await mcp.post( + f"{os.environ['FOUNDRY_PROJECT_ENDPOINT']}/toolboxes/github/mcp", + headers={"Authorization": f"Bearer {get_agent_token()}", **headers}, # get_agent_token(): the agent's managed-identity token + json={"jsonrpc": "2.0", "method": "tools/call", + "params": {"name": "list_my_assigned_issues", "arguments": {}}}, + ) + # The toolbox resolved the caller from the call ID and returned THIS user's issues. + + return JSONResponse(resp.json()) + +app.run() +``` + ### Long-running operations with polling ```python diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/api.md b/sdk/agentserver/azure-ai-agentserver-invocations/api.md new file mode 100644 index 000000000000..b7bf4e3441f3 --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-invocations/api.md @@ -0,0 +1,97 @@ +```py +namespace azure.ai.agentserver.invocations + + class azure.ai.agentserver.invocations.InvocationAgentServerHost(_WSHandlerMixin, AgentServerHost): + property routes: list[BaseRoute] # Read-only + property ws_ping_interval: float # Read-only + + async def __call__( + self, + scope: Scope, + receive: Receive, + send: Send + ) -> None: ... + + def __init__( + self, + *, + openapi_spec: Optional[dict[str, Any]] = ..., + **kwargs: Any + ) -> None: ... + + def add_exception_handler( + self, + exc_class_or_status_code: int | type[Exception], + handler: ExceptionHandler + ) -> None: ... + + def add_middleware( + self, + middleware_class: _MiddlewareFactory[P], + *args: args, + **kwargs: kwargs + ) -> None: ... + + def add_route( + self, + path: str, + route: Callable[[Request], Awaitable[Response] | Response], + methods: list[str] | None = None, + name: str | None = None, + include_in_schema: bool = True + ) -> None: ... + + def build_middleware_stack(self) -> ASGIApp: ... + + def cancel_invocation_handler(self, fn: Callable[[Request], Awaitable[Response]]) -> Callable[[Request], Awaitable[Response]]: ... + + def get_invocation_handler(self, fn: Callable[[Request], Awaitable[Response]]) -> Callable[[Request], Awaitable[Response]]: ... + + def get_openapi_spec(self) -> Optional[dict[str, Any]]: ... + + def host( + self, + host: str, + app: ASGIApp, + name: str | None = None + ) -> None: ... + + def invoke_handler(self, fn: Callable[[Request], Awaitable[Response]]) -> Callable[[Request], Awaitable[Response]]: ... + + def mount( + self, + path: str, + app: ASGIApp, + name: str | None = None + ) -> None: ... + + def register_server_version(self, version_segment: str) -> None: ... + + def run( + self, + host: str = "0.0.0.0", + port: Optional[int] = None + ) -> None: ... + + async def run_async( + self, + host: str = "0.0.0.0", + port: Optional[int] = None + ) -> None: ... + + def shutdown_handler(self, fn: Callable[[], Awaitable[None]]) -> Callable[[], Awaitable[None]]: ... + + @staticmethod + async def sse_keepalive_stream(iterator: AsyncIterable[_Content], interval: int) -> AsyncIterator[_Content]: ... + + def url_path_for( + self, + name: str, + /, + **path_params: Any + ) -> URLPath: ... + + def ws_handler(self, fn: WSHandler) -> WSHandler: ... + + +``` \ No newline at end of file diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/api.metadata.yml b/sdk/agentserver/azure-ai-agentserver-invocations/api.metadata.yml new file mode 100644 index 000000000000..03445e84fe2e --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-invocations/api.metadata.yml @@ -0,0 +1,3 @@ +apiMdSha256: 20e0c715368a99cb4302338429be892247a5f77a7500a96cf5164fbce402050d +parserVersion: 0.3.28 +pythonVersion: 3.11.9 diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_invocation.py b/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_invocation.py index 116ff0d62546..fd2f6aff3aeb 100644 --- a/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_invocation.py +++ b/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_invocation.py @@ -22,15 +22,18 @@ from azure.ai.agentserver.core import ( # pylint: disable=no-name-in-module AgentServerHost, + FoundryAgentRequestContext, create_error_response, + reset_request_context, + set_request_context, ) from azure.ai.agentserver.core._platform_headers import ( # pylint: disable=import-error,no-name-in-module - CHAT_ISOLATION_KEY, ERROR_DETAIL, ERROR_SOURCE, + FOUNDRY_CALL_ID, MAX_ERROR_DETAIL_LENGTH, PLATFORM_ERROR_TAG, - USER_ISOLATION_KEY, + USER_ID, ) from ._constants import InvocationConstants @@ -362,6 +365,7 @@ def _wrap_streaming_response( response: StreamingResponse, invocation_id: str, session_id: str, + platform_context: FoundryAgentRequestContext | None = None, ) -> StreamingResponse: """Wrap streaming body iteration with invocation logging/tracing context. @@ -371,6 +375,9 @@ def _wrap_streaming_response( :type invocation_id: str :param session_id: Session identifier to stamp in context/logging. :type session_id: str + :param platform_context: Platform context to re-establish for outbound + 1P calls made during stream iteration (protocol 2.0.0). + :type platform_context: ~azure.ai.agentserver.core.FoundryAgentRequestContext | None :return: The response with a wrapped body_iterator. :rtype: StreamingResponse """ @@ -380,6 +387,9 @@ async def _wrapped_body() -> AsyncIterator[Any]: # Re-establish the invocation context for the streaming task. stream_inv_token = _invocation_id_var.set(invocation_id) stream_session_token = _session_id_var.set(session_id) + stream_ctx_token = ( + set_request_context(platform_context) if platform_context is not None else None + ) try: async for chunk in original_iterator: yield chunk @@ -398,6 +408,8 @@ async def _wrapped_body() -> AsyncIterator[Any]: finally: _invocation_id_var.reset(stream_inv_token) _session_id_var.reset(stream_session_token) + if stream_ctx_token is not None: + reset_request_context(stream_ctx_token) response.body_iterator = _wrapped_body() return response @@ -417,9 +429,11 @@ async def _create_invocation_endpoint(self, request: Request) -> Response: session_id = _sanitize_id(raw_session_id, str(uuid.uuid4())) request.state.session_id = session_id - # Platform isolation headers — expose to handlers - request.state.user_isolation_key = request.headers.get(USER_ISOLATION_KEY, "") - request.state.chat_isolation_key = request.headers.get(CHAT_ISOLATION_KEY, "") + # Platform identity headers — expose to handlers + user_id = request.headers.get(USER_ID, "") + call_id = request.headers.get(FOUNDRY_CALL_ID, "") + request.state.user_id = user_id + request.state.call_id = call_id # Incoming baggage and trace context are already attached by # BaggageMiddleware and the Starlette OTel instrumentor. @@ -437,6 +451,14 @@ async def _create_invocation_endpoint(self, request: Request) -> Response: _ensure_log_filter() inv_token = _invocation_id_var.set(invocation_id) session_token = _session_id_var.set(session_id) + # Bind platform context so outbound 1P calls (and handler/tool code) can + # forward the per-request call ID and user ID (protocol 2.0.0). + platform_ctx = FoundryAgentRequestContext( + call_id=call_id or None, + user_id=user_id or None, + session_id=session_id, + ) + ctx_token = set_request_context(platform_ctx) try: response = await self._dispatch_invoke(request) response.headers[InvocationConstants.INVOCATION_ID_HEADER] = invocation_id @@ -477,6 +499,7 @@ async def _create_invocation_endpoint(self, request: Request) -> Response: # tokens it sets for stream iteration. _invocation_id_var.reset(inv_token) _session_id_var.reset(session_token) + reset_request_context(ctx_token) try: _otel_context.detach(baggage_token) except ValueError: @@ -485,7 +508,9 @@ async def _create_invocation_endpoint(self, request: Request) -> Response: # Wrap streaming response body so exceptions during iteration are # recorded on the current trace span and logged as invocation errors. if isinstance(response, StreamingResponse): - response = self._wrap_streaming_response(response, invocation_id, session_id) + response = self._wrap_streaming_response( + response, invocation_id, session_id, platform_ctx + ) return response diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_version.py b/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_version.py index eecd2a8e450f..ffa055f43119 100644 --- a/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_version.py +++ b/sdk/agentserver/azure-ai-agentserver-invocations/azure/ai/agentserver/invocations/_version.py @@ -2,4 +2,4 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # --------------------------------------------------------- -VERSION = "1.0.0b5" +VERSION = "1.0.0b6" diff --git a/sdk/agentserver/azure-ai-agentserver-invocations/pyproject.toml b/sdk/agentserver/azure-ai-agentserver-invocations/pyproject.toml index b70d8ea30022..a21545753fab 100644 --- a/sdk/agentserver/azure-ai-agentserver-invocations/pyproject.toml +++ b/sdk/agentserver/azure-ai-agentserver-invocations/pyproject.toml @@ -21,7 +21,7 @@ classifiers = [ keywords = ["azure", "azure sdk", "agent", "agentserver", "invocations"] dependencies = [ - "azure-ai-agentserver-core>=2.0.0b4", + "azure-ai-agentserver-core>=2.0.0b7", ] [dependency-groups] @@ -68,6 +68,7 @@ mypy = true pyright = true verifytypes = false latestdependency = false +mindependency = false pylint = true type_check_samples = false diff --git a/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md b/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md index 6a35aabcf294..cbbcdf06c35e 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md +++ b/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md @@ -1,5 +1,18 @@ # Release History +## 1.0.0b8 (Unreleased) + +### Features Added + +- Container protocol version `2.0.0` support: the per-request call ID (`x-agent-foundry-call-id`) and global user ID (`x-agent-user-id`) are read from inbound requests and exposed on `ResponseContext.platform_context`. The per-request call ID is forwarded on all outbound Foundry Storage calls and bound to the request-scoped platform context so handler/tool code making raw outbound calls can forward it; `x-agent-user-id` is used only for container-side partitioning and is not forwarded to 1P services. + +### Breaking Changes + +- Renamed the public `IsolationContext` type to `PlatformContext`. Its fields are now `user_id_key` (from `x-agent-user-id`) and `call_id` (from `x-agent-foundry-call-id`), replacing `user_key` / `chat_key`. +- `ResponseContext.isolation` is now `ResponseContext.platform_context`. +- Response provider protocol methods now accept a `context` keyword argument (previously `isolation`). +- In-process partition enforcement is now keyed on the user ID (`x-agent-user-id`) instead of the chat isolation key. + ## 1.0.0b7 (2026-05-25) ### Features Added diff --git a/sdk/agentserver/azure-ai-agentserver-responses/Makefile b/sdk/agentserver/azure-ai-agentserver-responses/Makefile index 2805f475736f..488836d2fa9a 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/Makefile +++ b/sdk/agentserver/azure-ai-agentserver-responses/Makefile @@ -12,10 +12,10 @@ TEMP_TSP_DIR := $(TYPESPEC_DIR)/TempTypeSpecFiles OPENAPI_SPEC ?= $(TEMP_TSP_DIR)/Foundry/openapi.virtual-public-preview.yaml VALIDATORS_OUTPUT ?= $(OUTPUT_DIR)/_validators.py ROOT_SCHEMAS ?= CreateResponse -OVERLAY ?= scripts/validation-overlay.yaml +OVERLAY ?= _scripts/validation-overlay.yaml TEMP_OUTPUT_DIR := $(OUTPUT_DIR)/.tmp_codegen MODEL_PACKAGE_DIR := $(TEMP_OUTPUT_DIR)/azure/ai/agentserver/responses/models -MODEL_SHIMS_DIR := scripts/generated_shims +MODEL_SHIMS_DIR := _scripts/generated_shims CONTRACTS_DIR := $(TEMP_TSP_DIR)/sdk-service-agentserver-contracts MODEL_BASE := $(OUTPUT_DIR)/sdk/models/_utils/model_base.py @@ -34,7 +34,7 @@ generate-validators: @where python >NUL 2>NUL || (echo Error: python is required and was not found on PATH. 1>&2 && exit /b 1) @if not exist "$(OPENAPI_SPEC)" (echo Error: OpenAPI spec not found at $(OPENAPI_SPEC). Run 'make generate-openapi' first. 1>&2 && exit /b 1) @echo Generating payload validators from $(OPENAPI_SPEC)... - python scripts/generate_validators.py --input "$(OPENAPI_SPEC)" --output "$(VALIDATORS_OUTPUT)" --root-schemas "$(ROOT_SCHEMAS)" --overlay "$(OVERLAY)" + python _scripts/generate_validators.py --input "$(OPENAPI_SPEC)" --output "$(VALIDATORS_OUTPUT)" --root-schemas "$(ROOT_SCHEMAS)" --overlay "$(OVERLAY)" @echo Generated validators at $(VALIDATORS_OUTPUT) else generate-validators: @@ -48,7 +48,7 @@ generate-validators: exit 1; \ } @echo "Generating payload validators from $(OPENAPI_SPEC)..." - python scripts/generate_validators.py --input "$(OPENAPI_SPEC)" --output "$(VALIDATORS_OUTPUT)" --root-schemas "$(ROOT_SCHEMAS)" --overlay "$(OVERLAY)" + python _scripts/generate_validators.py --input "$(OPENAPI_SPEC)" --output "$(VALIDATORS_OUTPUT)" --root-schemas "$(ROOT_SCHEMAS)" --overlay "$(OVERLAY)" @echo "Generated validators at $(VALIDATORS_OUTPUT)" endif diff --git a/sdk/agentserver/azure-ai-agentserver-responses/README.md b/sdk/agentserver/azure-ai-agentserver-responses/README.md index da041d5d926b..5e8be3aa93ba 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/README.md +++ b/sdk/agentserver/azure-ai-agentserver-responses/README.md @@ -91,7 +91,7 @@ The `ResponseContext` provides request-scoped state: |---|---| | `response_id` | Unique ID for this response | | `is_shutdown_requested` | Whether the server is draining | -| `isolation` | `IsolationContext` with `user_key` and `chat_key` for multi-tenant state partitioning | +| `platform_context` | `PlatformContext` with `user_id_key` (from `x-agent-user-id`) and `call_id` (from `x-agent-foundry-call-id`) for multi-tenant state partitioning and per-request caller-context forwarding | | `client_headers` | Dictionary of `x-client-*` headers forwarded from the platform (keys normalized to lowercase) | | `query_parameters` | Dictionary of query string parameters | | `get_input_items()` | Load resolved input items as `Item` subtypes | @@ -136,6 +136,48 @@ async def handler(request: CreateResponse, context: ResponseContext, cancellatio return TextResponse(context, request, text=f"Echo: {text}") +app.run() +``` + +### Multi-user session (per-request call ID) + +On container protocol `2.0.0` a single agent session can serve **multiple users**. Forwarding the per-request `x-agent-foundry-call-id` on outbound toolbox calls lets the tool server resolve *which* user made this request and act on their behalf — so user A's and user B's requests to the same session each get a user-scoped result. (`x-agent-user-id` is never forwarded; the tool resolves the user from the call ID server-side. Use `context.platform_context.user_id_key` only for the container's own per-user state.) + +```python +import asyncio +import os + +import httpx +from azure.ai.agentserver.core import get_request_context +from azure.ai.agentserver.responses import ( + CreateResponse, + ResponseContext, + ResponsesAgentServerHost, + TextResponse, +) + +app = ResponsesAgentServerHost() + + +@app.response_handler +async def handler(request: CreateResponse, context: ResponseContext, cancellation_signal: asyncio.Event): + # platform_headers() echoes x-agent-foundry-call-id only (never x-agent-user-id). + headers = get_request_context().platform_headers() + + # Toolbox / MCP — attach the call ID PER CALL. The MCP session is long-lived and + # shared across users/turns, so never bake one call's ID into static client headers. + async with httpx.AsyncClient() as mcp: + resp = await mcp.post( + f"{os.environ['FOUNDRY_PROJECT_ENDPOINT']}/toolboxes/github/mcp", + headers={"Authorization": f"Bearer {get_agent_token()}", **headers}, # get_agent_token(): the agent's managed-identity token + json={"jsonrpc": "2.0", "method": "tools/call", + "params": {"name": "list_my_assigned_issues", "arguments": {}}}, + ) + # The toolbox resolved the caller from the call ID and returned THIS user's issues. + + return TextResponse(context, request, text=resp.text) + + app.run() ``` diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/__init__.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/__init__.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/__init__.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/__init__.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generate_validators.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generate_validators.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generate_validators.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generate_validators.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/__init__.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/__init__.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/__init__.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/__init__.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_enums.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_enums.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_enums.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_enums.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_models.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_models.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_models.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_models.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_patch.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_patch.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/_patch.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/_patch.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/models_patch.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/models_patch.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/models_patch.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/models_patch.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/sdk_models__init__.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/sdk_models__init__.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/generated_shims/sdk_models__init__.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/generated_shims/sdk_models__init__.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/validation-overlay.yaml b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/validation-overlay.yaml similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/validation-overlay.yaml rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/validation-overlay.yaml diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/validator_emitter.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/validator_emitter.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/validator_emitter.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/validator_emitter.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/scripts/validator_schema_walker.py b/sdk/agentserver/azure-ai-agentserver-responses/_scripts/validator_schema_walker.py similarity index 100% rename from sdk/agentserver/azure-ai-agentserver-responses/scripts/validator_schema_walker.py rename to sdk/agentserver/azure-ai-agentserver-responses/_scripts/validator_schema_walker.py diff --git a/sdk/agentserver/azure-ai-agentserver-responses/api.md b/sdk/agentserver/azure-ai-agentserver-responses/api.md new file mode 100644 index 000000000000..c269b3a26d17 --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-responses/api.md @@ -0,0 +1,9419 @@ +```py +namespace azure.ai.agentserver.responses + + def azure.ai.agentserver.responses.get_conversation_id(request: CreateResponse | ResponseObject) -> Optional[str]: ... + + + def azure.ai.agentserver.responses.get_input_expanded(request: CreateResponse) -> list[Item]: ... + + + def azure.ai.agentserver.responses.to_output_item(item: Item, response_id: str | None = None) -> OutputItem | None: ... + + + class azure.ai.agentserver.responses.CreateResponse(CreateResponseGenerated): + prompt_cache_key: Optional[str] + safety_identifier: Optional[str] + temperature: Optional[float] + top_p: Optional[float] + user: Optional[str] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + background: Optional[bool] = ..., + context_management: Optional[list[ContextManagementParam]] = ..., + conversation: Optional[ConversationParam] = ..., + include: Optional[list[Union[str, IncludeEnum]]] = ..., + input: Optional[InputParam] = ..., + instructions: Optional[str] = ..., + max_output_tokens: Optional[int] = ..., + max_tool_calls: Optional[int] = ..., + metadata: Optional[Metadata] = ..., + model: Optional[str] = ..., + parallel_tool_calls: Optional[bool] = ..., + previous_response_id: Optional[str] = ..., + prompt: Optional[Prompt] = ..., + prompt_cache_key: Optional[str] = ..., + prompt_cache_retention: Optional[Literal[in-memory, 24h]] = ..., + reasoning: Optional[Reasoning] = ..., + safety_identifier: Optional[str] = ..., + service_tier: Optional[Literal[auto, default, flex, scale, priority]] = ..., + store: Optional[bool] = ..., + stream: Optional[bool] = ..., + stream_options: Optional[ResponseStreamOptions] = ..., + structured_inputs: Optional[dict[str, Any]] = ..., + temperature: Optional[int] = ..., + text: Optional[ResponseTextParam] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_logprobs: Optional[int] = ..., + top_p: Optional[int] = ..., + truncation: Optional[Literal[auto, disabled]] = ..., + user: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.FoundryApiError(FoundryStorageError): + + def __init__( + self, + message: str, + *, + response_body: dict[str, Any] | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.FoundryBadRequestError(FoundryStorageError): + + def __init__( + self, + message: str, + *, + response_body: dict[str, Any] | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.FoundryResourceNotFoundError(FoundryStorageError): + + def __init__( + self, + message: str, + *, + response_body: dict[str, Any] | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.FoundryStorageError(Exception): + + def __init__( + self, + message: str, + *, + response_body: dict[str, Any] | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.FoundryStorageProvider: implements AsyncContextManager + + def __init__( + self, + credential: AsyncTokenCredential, + settings: FoundryStorageSettings | None = None, + get_server_version: Callable[[], str] | None = None + ) -> None: ... + + async def aclose(self) -> None: ... + + async def create_response( + self, + response: ResponseObject, + input_items: Iterable[OutputItem] | None, + history_item_ids: Iterable[str] | None, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def delete_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def get_history_item_ids( + self, + previous_response_id: str | None, + conversation_id: str | None, + limit: int, + *, + context: PlatformContext | None = ... + ) -> list[str]: ... + + async def get_input_items( + self, + response_id: str, + limit: int = 20, + ascending: bool = False, + after: str | None = None, + before: str | None = None, + *, + context: PlatformContext | None = ... + ) -> list[OutputItem]: ... + + async def get_items( + self, + item_ids: Iterable[str], + *, + context: PlatformContext | None = ... + ) -> list[OutputItem | None]: ... + + async def get_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> ResponseObject: ... + + async def update_response( + self, + response: ResponseObject, + *, + context: PlatformContext | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.FoundryStorageSettings: + + def __init__( + self, + *, + storage_base_url: str + ) -> None: ... + + @classmethod + def from_endpoint(cls, endpoint: str) -> FoundryStorageSettings: ... + + @classmethod + def from_env(cls) -> FoundryStorageSettings: ... + + def build_url( + self, + path: str, + **extra_params: str + ) -> str: ... + + + class azure.ai.agentserver.responses.InMemoryResponseProvider(ResponseProviderProtocol, ResponseStreamProviderProtocol): + + def __init__(self) -> None: ... + + async def append_stream_event( + self, + response_id: str, + event: StreamEventRecord, + *, + ttl_seconds: int | None = ... + ) -> bool: ... + + async def create_execution( + self, + execution: ResponseExecution, + *, + ttl_seconds: int | None = ... + ) -> None: ... + + async def create_response( + self, + response: ResponseObject, + input_items: Iterable[OutputItem] | None, + history_item_ids: Iterable[str] | None, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def delete(self, response_id: str) -> bool: ... + + async def delete_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def delete_stream_events( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def get_execution(self, response_id: str) -> ResponseExecution | None: ... + + async def get_history_item_ids( + self, + previous_response_id: str | None, + conversation_id: str | None, + limit: int, + *, + context: PlatformContext | None = ... + ) -> list[str]: ... + + async def get_input_items( + self, + response_id: str, + limit: int = 20, + ascending: bool = False, + after: str | None = None, + before: str | None = None, + *, + context: PlatformContext | None = ... + ) -> list[OutputItem]: ... + + async def get_items( + self, + item_ids: Iterable[str], + *, + context: PlatformContext | None = ... + ) -> list[OutputItem | None]: ... + + async def get_replay_events(self, response_id: str) -> list[StreamEventRecord] | None: ... + + async def get_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> ResponseObject: ... + + async def get_stream_events( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> list[ResponseStreamEvent] | None: ... + + async def purge_expired( + self, + *, + now: datetime | None = ... + ) -> int: ... + + async def save_stream_events( + self, + response_id: str, + events: list[ResponseStreamEvent], + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def set_cancel_requested( + self, + response_id: str, + *, + ttl_seconds: int | None = ... + ) -> bool: ... + + async def set_response_snapshot( + self, + response_id: str, + response: ResponseObject, + *, + ttl_seconds: int | None = ... + ) -> bool: ... + + async def transition_execution_status( + self, + response_id: str, + next_status: ResponseStatus, + *, + ttl_seconds: int | None = ... + ) -> bool: ... + + async def update_response( + self, + response: ResponseObject, + *, + context: PlatformContext | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.PlatformContext: + + def __init__( + self, + *, + call_id: str | None = ..., + user_id_key: str | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.ResponseContext: + + def __init__( + self, + *, + client_headers: dict[str, str] | None = ..., + conversation_id: str | None = ..., + created_at: datetime | None = ..., + history_limit: int = 100, + input_items: list[InputParam] | list[OutputItem] | None = ..., + mode_flags: ResponseModeFlags, + platform_context: PlatformContext | None = ..., + prefetched_history_ids: list[str] | None = ..., + previous_response_id: str | None = ..., + provider: ResponseProviderProtocol | None = ..., + query_parameters: dict[str, str] | None = ..., + request: CreateResponse | None = ..., + response_id: str + ) -> None: ... + + async def get_history(self) -> Sequence[OutputItem]: ... + + async def get_input_items( + self, + *, + resolve_references: bool = True + ) -> Sequence[Item]: ... + + async def get_input_text( + self, + *, + resolve_references: bool = True + ) -> str: ... + + + class azure.ai.agentserver.responses.ResponseEventStream: + property response: ResponseObject # Read-only + + def __init__( + self, + *, + agent_reference: AgentReference | None = ..., + model: str | None = ..., + request: CreateResponse | None = ..., + response: ResponseObject | None = ..., + response_id: str | None = ... + ) -> None: ... + + def add_output_item(self, item_id: str) -> OutputItemBuilder: ... + + def add_output_item_apply_patch_call(self) -> OutputItemBuilder: ... + + def add_output_item_apply_patch_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_code_interpreter_call(self) -> OutputItemCodeInterpreterCallBuilder: ... + + def add_output_item_compaction(self) -> OutputItemBuilder: ... + + def add_output_item_computer_call(self) -> OutputItemBuilder: ... + + def add_output_item_computer_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_custom_tool_call( + self, + call_id: str, + name: str + ) -> OutputItemCustomToolCallBuilder: ... + + def add_output_item_custom_tool_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_file_search_call(self) -> OutputItemFileSearchCallBuilder: ... + + def add_output_item_function_call( + self, + name: str, + call_id: str + ) -> OutputItemFunctionCallBuilder: ... + + def add_output_item_function_call_output(self, call_id: str) -> OutputItemFunctionCallOutputBuilder: ... + + def add_output_item_function_shell_call(self) -> OutputItemBuilder: ... + + def add_output_item_function_shell_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_image_gen_call(self) -> OutputItemImageGenCallBuilder: ... + + def add_output_item_local_shell_call(self) -> OutputItemBuilder: ... + + def add_output_item_local_shell_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_approval_request(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_approval_response(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_call( + self, + server_label: str, + name: str, + *, + item_id: str | None = ... + ) -> OutputItemMcpCallBuilder: ... + + def add_output_item_mcp_list_tools(self, server_label: str) -> OutputItemMcpListToolsBuilder: ... + + def add_output_item_message(self) -> OutputItemMessageBuilder: ... + + def add_output_item_reasoning_item(self) -> OutputItemReasoningItemBuilder: ... + + def add_output_item_structured_outputs(self) -> OutputItemBuilder: ... + + def add_output_item_web_search_call(self) -> OutputItemWebSearchCallBuilder: ... + + async def aoutput_item_apply_patch_call( + self, + call_id: str, + operation: ApplyPatchFileOperation, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_apply_patch_call_output( + self, + call_id: str, + *, + output: str | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_compaction(self, encrypted_content: str) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_computer_call( + self, + call_id: str, + action: ComputerAction, + *, + pending_safety_checks: list[ComputerCallSafetyCheckParam] | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_computer_call_output( + self, + call_id: str, + output: ComputerScreenshotImage, + *, + acknowledged_safety_checks: list[ComputerCallSafetyCheckParam] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_custom_tool_call_output( + self, + call_id: str, + output: str | list[FunctionAndCustomToolCallOutput] + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_call( + self, + name: str, + call_id: str, + arguments: str | AsyncIterable[str] + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_call_output( + self, + call_id: str, + output: str + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_shell_call( + self, + call_id: str, + action: FunctionShellAction, + environment: FunctionShellCallEnvironment, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_shell_call_output( + self, + call_id: str, + output: list[FunctionShellCallOutputContent], + *, + max_output_length: int | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_image_gen_call( + self, + result_base64: str, + *, + partials: AsyncIterable[str] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_local_shell_call( + self, + call_id: str, + action: LocalShellExecAction, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_local_shell_call_output(self, output: str) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_mcp_approval_request( + self, + server_label: str, + name: str, + arguments: str + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_mcp_approval_response( + self, + approval_request_id: str, + approve: bool = False, + *, + reason: str | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_message( + self, + text: str | AsyncIterable[str], + *, + annotations: Sequence[Annotation] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_reasoning_item(self, summary_text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_structured_outputs(self, output: Any) -> AsyncIterator[ResponseStreamEvent]: ... + + def emit_completed( + self, + *, + usage: ResponseUsage | None = ... + ) -> ResponseCompletedEvent: ... + + def emit_created( + self, + *, + status: str = "in_progress" + ) -> ResponseCreatedEvent: ... + + def emit_failed( + self, + *, + code: str | ResponseErrorCode = "server_error", + message: str = "An internal server error occurred.", + usage: ResponseUsage | None = ... + ) -> ResponseFailedEvent: ... + + def emit_in_progress(self) -> ResponseInProgressEvent: ... + + def emit_incomplete( + self, + *, + reason: str | None = ..., + usage: ResponseUsage | None = ... + ) -> ResponseIncompleteEvent: ... + + def emit_queued(self) -> ResponseQueuedEvent: ... + + def events(self) -> list[ResponseStreamEvent]: ... + + def output_item_apply_patch_call( + self, + call_id: str, + operation: ApplyPatchFileOperation, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_apply_patch_call_output( + self, + call_id: str, + *, + output: str | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_compaction(self, encrypted_content: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_computer_call( + self, + call_id: str, + action: ComputerAction, + *, + pending_safety_checks: list[ComputerCallSafetyCheckParam] | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_computer_call_output( + self, + call_id: str, + output: ComputerScreenshotImage, + *, + acknowledged_safety_checks: list[ComputerCallSafetyCheckParam] | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_custom_tool_call_output( + self, + call_id: str, + output: str | list[FunctionAndCustomToolCallOutput] + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_call( + self, + name: str, + call_id: str, + arguments: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_call_output( + self, + call_id: str, + output: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_shell_call( + self, + call_id: str, + action: FunctionShellAction, + environment: FunctionShellCallEnvironment, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_shell_call_output( + self, + call_id: str, + output: list[FunctionShellCallOutputContent], + *, + max_output_length: int | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_image_gen_call(self, result_base64: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_local_shell_call( + self, + call_id: str, + action: LocalShellExecAction, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_local_shell_call_output(self, output: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_mcp_approval_request( + self, + server_label: str, + name: str, + arguments: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_mcp_approval_response( + self, + approval_request_id: str, + approve: bool = False, + *, + reason: str | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_message( + self, + text: str, + *, + annotations: Sequence[Annotation] | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_reasoning_item(self, summary_text: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_structured_outputs(self, output: Any) -> Iterator[ResponseStreamEvent]: ... + + + class azure.ai.agentserver.responses.ResponseObject(ResponseObjectGenerated): + output: list[OutputItem] + prompt_cache_key: Optional[str] + safety_identifier: Optional[str] + temperature: Optional[float] + top_p: Optional[float] + user: Optional[str] + + @overload + def __init__( + self, + *, + agent_reference: AgentReference, + background: Optional[bool] = ..., + completed_at: Optional[datetime] = ..., + conversation: Optional[ConversationReference] = ..., + created_at: datetime, + error: ResponseErrorInfo, + id: str, + incomplete_details: ResponseIncompleteDetails, + instructions: Union[str, list[Item]], + max_output_tokens: Optional[int] = ..., + max_tool_calls: Optional[int] = ..., + metadata: Optional[Metadata] = ..., + model: Optional[str] = ..., + output: list[OutputItem], + output_text: Optional[str] = ..., + parallel_tool_calls: bool, + previous_response_id: Optional[str] = ..., + prompt: Optional[Prompt] = ..., + prompt_cache_key: Optional[str] = ..., + prompt_cache_retention: Optional[Literal[in-memory, 24h]] = ..., + reasoning: Optional[Reasoning] = ..., + safety_identifier: Optional[str] = ..., + service_tier: Optional[Literal[auto, default, flex, scale, priority]] = ..., + status: Optional[Literal[completed, failed, in_progress, cancelled, queued, incomplete]] = ..., + temperature: Optional[int] = ..., + text: Optional[ResponseTextParam] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_logprobs: Optional[int] = ..., + top_p: Optional[int] = ..., + truncation: Optional[Literal[auto, disabled]] = ..., + usage: Optional[ResponseUsage] = ..., + user: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + @runtime_checkable + class azure.ai.agentserver.responses.ResponseProviderProtocol(Protocol): + + async def create_response( + self, + response: ResponseObject, + input_items: Iterable[OutputItem] | None, + history_item_ids: Iterable[str] | None, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def delete_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def get_history_item_ids( + self, + previous_response_id: str | None, + conversation_id: str | None, + limit: int, + *, + context: PlatformContext | None = ... + ) -> list[str]: ... + + async def get_input_items( + self, + response_id: str, + limit: int = 20, + ascending: bool = False, + after: str | None = None, + before: str | None = None, + *, + context: PlatformContext | None = ... + ) -> list[OutputItem]: ... + + async def get_items( + self, + item_ids: Iterable[str], + *, + context: PlatformContext | None = ... + ) -> list[OutputItem | None]: ... + + async def get_response( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> ResponseObject: ... + + async def update_response( + self, + response: ResponseObject, + *, + context: PlatformContext | None = ... + ) -> None: ... + + + @runtime_checkable + class azure.ai.agentserver.responses.ResponseStreamProviderProtocol(Protocol): + + async def delete_stream_events( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> None: ... + + async def get_stream_events( + self, + response_id: str, + *, + context: PlatformContext | None = ... + ) -> list[ResponseStreamEvent] | None: ... + + async def save_stream_events( + self, + response_id: str, + events: list[ResponseStreamEvent], + *, + context: PlatformContext | None = ... + ) -> None: ... + + + class azure.ai.agentserver.responses.ResponsesAgentServerHost(AgentServerHost): + property routes: list[BaseRoute] # Read-only + + def __init__( + self, + *, + options: ResponsesServerOptions | None = ..., + prefix: str = "", + store: ResponseProviderProtocol | None = ..., + **kwargs: Any + ) -> None: ... + + def response_handler(self, fn: CreateHandlerFn) -> CreateHandlerFn: ... + + + class azure.ai.agentserver.responses.ResponsesServerOptions: + property sse_keep_alive_enabled: bool # Read-only + + def __init__( + self, + *, + additional_server_version: str | None = ..., + create_span_hook: CreateSpanHook | None = ..., + default_fetch_history_count: int = 100, + default_model: str | None = ..., + shutdown_grace_period_seconds: int = 10, + sse_keep_alive_interval_seconds: int | None = ... + ) -> None: ... + + @classmethod + def from_env(cls, environ: Mapping[str, str] | None = None) -> ResponsesServerOptions: ... + + + class azure.ai.agentserver.responses.TextResponse: + + def __aiter__(self) -> AsyncIterator[ResponseStreamEvent]: ... + + def __init__( + self, + context: ResponseContext, + request: CreateResponse, + *, + configure: Callable[[ResponseObject], None] | None = ..., + text: TextSource + ) -> None: ... + + +namespace azure.ai.agentserver.responses.hosting + + class azure.ai.agentserver.responses.hosting.ResponsesAgentServerHost(AgentServerHost): + property routes: list[BaseRoute] # Read-only + + def __init__( + self, + *, + options: ResponsesServerOptions | None = ..., + prefix: str = "", + store: ResponseProviderProtocol | None = ..., + **kwargs: Any + ) -> None: ... + + def response_handler(self, fn: CreateHandlerFn) -> CreateHandlerFn: ... + + +namespace azure.ai.agentserver.responses.models + + def azure.ai.agentserver.responses.models.get_content_expanded(message: ItemMessage) -> list[MessageContent]: ... + + + def azure.ai.agentserver.responses.models.get_conversation_expanded(request: CreateResponse) -> Optional[ConversationParam_2]: ... + + + def azure.ai.agentserver.responses.models.get_conversation_id(request: CreateResponse | ResponseObject) -> Optional[str]: ... + + + def azure.ai.agentserver.responses.models.get_input_expanded(request: CreateResponse) -> list[Item]: ... + + + def azure.ai.agentserver.responses.models.get_tool_choice_expanded(request: CreateResponse) -> Optional[ToolChoiceParam]: ... + + + class azure.ai.agentserver.responses.models.A2APreviewTool(Tool, discriminator='a2a_preview'): + agent_card_path: Optional[str] + base_url: Optional[str] + description: Optional[str] + name: Optional[str] + project_connection_id: Optional[str] + type: Literal[ToolType.A2_A_PREVIEW] + + @overload + def __init__( + self, + *, + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.A2AToolCall(OutputItem, discriminator='a2a_preview_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + name: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.A2_A_PREVIEW_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + name: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.A2AToolCallOutput(OutputItem, discriminator='a2a_preview_call_output'): + agent_reference: AgentReference + call_id: str + id: str + name: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.A2_A_PREVIEW_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + name: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AISearchIndexResource(_Model): + description: Optional[str] + filter: Optional[str] + index_asset_id: Optional[str] + index_name: Optional[str] + name: Optional[str] + project_connection_id: Optional[str] + query_type: Optional[Union[str, AzureAISearchQueryType]] + top_k: Optional[int] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + filter: Optional[str] = ..., + index_asset_id: Optional[str] = ..., + index_name: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + query_type: Optional[Union[str, AzureAISearchQueryType]] = ..., + top_k: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AgentReference(_Model): + name: str + type: Literal["agent_reference"] + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.Annotation(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AnnotationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_FILE_CITATION = "container_file_citation" + FILE_CITATION = "file_citation" + FILE_PATH = "file_path" + URL_CITATION = "url_citation" + + + class azure.ai.agentserver.responses.models.ApiErrorResponse(_Model): + error: Error + + @overload + def __init__( + self, + *, + error: Error + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchCallOutputStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + + + class azure.ai.agentserver.responses.models.ApplyPatchCallOutputStatusParam(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + + + class azure.ai.agentserver.responses.models.ApplyPatchCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.ApplyPatchCallStatusParam(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.ApplyPatchCreateFileOperation(ApplyPatchFileOperation, discriminator='create_file'): + diff: str + path: str + type: Literal[ApplyPatchFileOperationType.CREATE_FILE] + + @overload + def __init__( + self, + *, + diff: str, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchCreateFileOperationParam(ApplyPatchOperationParam, discriminator='create_file'): + diff: str + path: str + type: Literal[ApplyPatchOperationParamType.CREATE_FILE] + + @overload + def __init__( + self, + *, + diff: str, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchDeleteFileOperation(ApplyPatchFileOperation, discriminator='delete_file'): + path: str + type: Literal[ApplyPatchFileOperationType.DELETE_FILE] + + @overload + def __init__( + self, + *, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchDeleteFileOperationParam(ApplyPatchOperationParam, discriminator='delete_file'): + path: str + type: Literal[ApplyPatchOperationParamType.DELETE_FILE] + + @overload + def __init__( + self, + *, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchFileOperation(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchFileOperationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATE_FILE = "create_file" + DELETE_FILE = "delete_file" + UPDATE_FILE = "update_file" + + + class azure.ai.agentserver.responses.models.ApplyPatchOperationParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchOperationParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATE_FILE = "create_file" + DELETE_FILE = "delete_file" + UPDATE_FILE = "update_file" + + + class azure.ai.agentserver.responses.models.ApplyPatchToolCallItemParam(Item, discriminator='apply_patch_call'): + call_id: str + id: Optional[str] + operation: ApplyPatchOperationParam + status: Union[str, ApplyPatchCallStatusParam] + type: Literal[ItemType.APPLY_PATCH_CALL] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + operation: ApplyPatchOperationParam, + status: Union[str, ApplyPatchCallStatusParam] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchToolCallOutputItemParam(Item, discriminator='apply_patch_call_output'): + call_id: str + id: Optional[str] + output: Optional[str] + status: Union[str, ApplyPatchCallOutputStatusParam] + type: Literal[ItemType.APPLY_PATCH_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + output: Optional[str] = ..., + status: Union[str, ApplyPatchCallOutputStatusParam] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchToolParam(Tool, discriminator='apply_patch'): + type: Literal[ToolType.APPLY_PATCH] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchUpdateFileOperation(ApplyPatchFileOperation, discriminator='update_file'): + diff: str + path: str + type: Literal[ApplyPatchFileOperationType.UPDATE_FILE] + + @overload + def __init__( + self, + *, + diff: str, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApplyPatchUpdateFileOperationParam(ApplyPatchOperationParam, discriminator='update_file'): + diff: str + path: str + type: Literal[ApplyPatchOperationParamType.UPDATE_FILE] + + @overload + def __init__( + self, + *, + diff: str, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ApproximateLocation(_Model): + city: Optional[str] + country: Optional[str] + region: Optional[str] + timezone: Optional[str] + type: Literal["approximate"] + + @overload + def __init__( + self, + *, + city: Optional[str] = ..., + country: Optional[str] = ..., + region: Optional[str] = ..., + timezone: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AutoCodeInterpreterToolParam(_Model): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ContainerNetworkPolicyParam] + type: Literal["auto"] + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ContainerNetworkPolicyParam] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureAISearchQueryType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SEMANTIC = "semantic" + SIMPLE = "simple" + VECTOR = "vector" + VECTOR_SEMANTIC_HYBRID = "vector_semantic_hybrid" + VECTOR_SIMPLE_HYBRID = "vector_simple_hybrid" + + + class azure.ai.agentserver.responses.models.AzureAISearchTool(Tool, discriminator='azure_ai_search'): + azure_ai_search: AzureAISearchToolResource + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.AZURE_AI_SEARCH] + + @overload + def __init__( + self, + *, + azure_ai_search: AzureAISearchToolResource, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureAISearchToolCall(OutputItem, discriminator='azure_ai_search_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.AZURE_AI_SEARCH_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureAISearchToolCallOutput(OutputItem, discriminator='azure_ai_search_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.AZURE_AI_SEARCH_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureAISearchToolResource(_Model): + description: Optional[str] + indexes: list[AISearchIndexResource] + name: Optional[str] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + indexes: list[AISearchIndexResource], + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionBinding(_Model): + storage_queue: AzureFunctionStorageQueue + type: Literal["storage_queue"] + + @overload + def __init__( + self, + *, + storage_queue: AzureFunctionStorageQueue + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionDefinition(_Model): + function: AzureFunctionDefinitionFunction + input_binding: AzureFunctionBinding + output_binding: AzureFunctionBinding + + @overload + def __init__( + self, + *, + function: AzureFunctionDefinitionFunction, + input_binding: AzureFunctionBinding, + output_binding: AzureFunctionBinding + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionDefinitionFunction(_Model): + description: Optional[str] + name: str + parameters: dict[str, Any] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionStorageQueue(_Model): + queue_name: str + queue_service_endpoint: str + + @overload + def __init__( + self, + *, + queue_name: str, + queue_service_endpoint: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionTool(Tool, discriminator='azure_function'): + azure_function: AzureFunctionDefinition + type: Literal[ToolType.AZURE_FUNCTION] + + @overload + def __init__( + self, + *, + azure_function: AzureFunctionDefinition + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionToolCall(OutputItem, discriminator='azure_function_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + name: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.AZURE_FUNCTION_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + name: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.AzureFunctionToolCallOutput(OutputItem, discriminator='azure_function_call_output'): + agent_reference: AgentReference + call_id: str + id: str + name: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.AZURE_FUNCTION_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + name: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingCustomSearchConfiguration(_Model): + count: Optional[int] + description: Optional[str] + freshness: Optional[str] + instance_name: str + market: Optional[str] + name: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + description: Optional[str] = ..., + freshness: Optional[str] = ..., + instance_name: str, + market: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingCustomSearchPreviewTool(Tool, discriminator='bing_custom_search_preview'): + bing_custom_search_preview: BingCustomSearchToolParameters + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.BING_CUSTOM_SEARCH_PREVIEW] + + @overload + def __init__( + self, + *, + bing_custom_search_preview: BingCustomSearchToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingCustomSearchToolCall(OutputItem, discriminator='bing_custom_search_preview_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BING_CUSTOM_SEARCH_PREVIEW_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingCustomSearchToolCallOutput(OutputItem, discriminator='bing_custom_search_preview_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BING_CUSTOM_SEARCH_PREVIEW_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingCustomSearchToolParameters(_Model): + description: Optional[str] + name: Optional[str] + search_configurations: list[BingCustomSearchConfiguration] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + search_configurations: list[BingCustomSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingGroundingSearchConfiguration(_Model): + count: Optional[int] + description: Optional[str] + freshness: Optional[str] + market: Optional[str] + name: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + description: Optional[str] = ..., + freshness: Optional[str] = ..., + market: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingGroundingSearchToolParameters(_Model): + description: Optional[str] + name: Optional[str] + search_configurations: list[BingGroundingSearchConfiguration] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + search_configurations: list[BingGroundingSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingGroundingTool(Tool, discriminator='bing_grounding'): + bing_grounding: BingGroundingSearchToolParameters + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.BING_GROUNDING] + + @overload + def __init__( + self, + *, + bing_grounding: BingGroundingSearchToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingGroundingToolCall(OutputItem, discriminator='bing_grounding_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BING_GROUNDING_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BingGroundingToolCallOutput(OutputItem, discriminator='bing_grounding_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BING_GROUNDING_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BrowserAutomationPreviewTool(Tool, discriminator='browser_automation_preview'): + browser_automation_preview: BrowserAutomationToolParameters + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.BROWSER_AUTOMATION_PREVIEW] + + @overload + def __init__( + self, + *, + browser_automation_preview: BrowserAutomationToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BrowserAutomationToolCall(OutputItem, discriminator='browser_automation_preview_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BROWSER_AUTOMATION_PREVIEW_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BrowserAutomationToolCallOutput(OutputItem, discriminator='browser_automation_preview_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.BROWSER_AUTOMATION_PREVIEW_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BrowserAutomationToolConnectionParameters(_Model): + description: Optional[str] + name: Optional[str] + project_connection_id: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.BrowserAutomationToolParameters(_Model): + connection: BrowserAutomationToolConnectionParameters + description: Optional[str] + name: Optional[str] + + @overload + def __init__( + self, + *, + connection: BrowserAutomationToolConnectionParameters, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CaptureStructuredOutputsTool(Tool, discriminator='capture_structured_outputs'): + outputs: StructuredOutputDefinition + type: Literal[ToolType.CAPTURE_STRUCTURED_OUTPUTS] + + @overload + def __init__( + self, + *, + outputs: StructuredOutputDefinition + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ChatSummaryMemoryItem(MemoryItem, discriminator='chat_summary'): + content: str + kind: Literal[MemoryItemKind.CHAT_SUMMARY] + memory_id: str + scope: str + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + memory_id: str, + scope: str, + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ClickButtonType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BACK = "back" + FORWARD = "forward" + LEFT = "left" + RIGHT = "right" + WHEEL = "wheel" + + + class azure.ai.agentserver.responses.models.ClickParam(ComputerAction, discriminator='click'): + button: Union[str, ClickButtonType] + type: Literal[ComputerActionType.CLICK] + x: int + y: int + + @overload + def __init__( + self, + *, + button: Union[str, ClickButtonType], + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CodeInterpreterOutputImage(_Model): + type: Literal["image"] + url: str + + @overload + def __init__( + self, + *, + url: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CodeInterpreterOutputLogs(_Model): + logs: str + type: Literal["logs"] + + @overload + def __init__( + self, + *, + logs: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CodeInterpreterTool(Tool, discriminator='code_interpreter'): + container: Optional[Union[str, AutoCodeInterpreterToolParam]] + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.CODE_INTERPRETER] + + @overload + def __init__( + self, + *, + container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CompactResource(_Model): + created_at: datetime + id: str + object: Literal["compaction"] + output: list[ItemField] + usage: ResponseUsage + + @overload + def __init__( + self, + *, + created_at: datetime, + id: str, + output: list[ItemField], + usage: ResponseUsage + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CompactionSummaryItemParam(Item, discriminator='compaction'): + encrypted_content: str + id: Optional[str] + type: Literal[ItemType.COMPACTION] + + @overload + def __init__( + self, + *, + encrypted_content: str, + id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComparisonFilter(_Model): + key: str + type: Literal["eq", "ne", "gt", "gte", "lt", "lte"] + value: Union[str, int, bool, list[Union[str, int]]] + + @overload + def __init__( + self, + *, + key: str, + type: Literal["eq", "ne", "gt", "gte", "lt", "lte"], + value: Union[str, int, bool, list[Union[str, int]]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CompoundFilter(_Model): + filters: list[Union[ComparisonFilter, Any]] + type: Literal["and", "or"] + + @overload + def __init__( + self, + *, + filters: list[Union[ComparisonFilter, Any]], + type: Literal["and", "or"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerAction(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLICK = "click" + DOUBLE_CLICK = "double_click" + DRAG = "drag" + KEYPRESS = "keypress" + MOVE = "move" + SCREENSHOT = "screenshot" + SCROLL = "scroll" + TYPE = "type" + WAIT = "wait" + + + class azure.ai.agentserver.responses.models.ComputerCallOutputItemParam(Item, discriminator='computer_call_output'): + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] + call_id: str + id: Optional[str] + output: ComputerScreenshotImage + status: Optional[Union[str, FunctionCallItemStatus]] + type: Literal[ItemType.COMPUTER_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] = ..., + call_id: str, + id: Optional[str] = ..., + output: ComputerScreenshotImage, + status: Optional[Union[str, FunctionCallItemStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerCallSafetyCheckParam(_Model): + code: Optional[str] + id: str + message: Optional[str] + + @overload + def __init__( + self, + *, + code: Optional[str] = ..., + id: str, + message: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BROWSER = "browser" + LINUX = "linux" + MAC = "mac" + UBUNTU = "ubuntu" + WINDOWS = "windows" + + + class azure.ai.agentserver.responses.models.ComputerScreenshotContent(MessageContent, discriminator='computer_screenshot'): + file_id: str + image_url: str + type: Literal[MessageContentType.COMPUTER_SCREENSHOT] + + @overload + def __init__( + self, + *, + file_id: str, + image_url: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerScreenshotImage(_Model): + file_id: Optional[str] + image_url: Optional[str] + type: Literal["computer_screenshot"] + + @overload + def __init__( + self, + *, + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ComputerUsePreviewTool(Tool, discriminator='computer_use_preview'): + display_height: int + display_width: int + environment: Union[str, ComputerEnvironment] + type: Literal[ToolType.COMPUTER_USE_PREVIEW] + + @overload + def __init__( + self, + *, + display_height: int, + display_width: int, + environment: Union[str, ComputerEnvironment] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerAutoParam(FunctionShellToolParamEnvironment, discriminator='container_auto'): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ContainerNetworkPolicyParam] + skills: Optional[list[ContainerSkill]] + type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_AUTO] + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ContainerNetworkPolicyParam] = ..., + skills: Optional[list[ContainerSkill]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerFileCitationBody(Annotation, discriminator='container_file_citation'): + container_id: str + end_index: int + file_id: str + filename: str + start_index: int + type: Literal[AnnotationType.CONTAINER_FILE_CITATION] + + @overload + def __init__( + self, + *, + container_id: str, + end_index: int, + file_id: str, + filename: str, + start_index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerMemoryLimit(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ENUM_16_G = "16g" + ENUM_1_G = "1g" + ENUM_4_G = "4g" + ENUM_64_G = "64g" + + + class azure.ai.agentserver.responses.models.ContainerNetworkPolicyAllowlistParam(ContainerNetworkPolicyParam, discriminator='allowlist'): + allowed_domains: list[str] + domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] + type: Literal[ContainerNetworkPolicyParamType.ALLOWLIST] + + @overload + def __init__( + self, + *, + allowed_domains: list[str], + domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerNetworkPolicyDisabledParam(ContainerNetworkPolicyParam, discriminator='disabled'): + type: Literal[ContainerNetworkPolicyParamType.DISABLED] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerNetworkPolicyDomainSecretParam(_Model): + domain: str + name: str + value: str + + @overload + def __init__( + self, + *, + domain: str, + name: str, + value: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerNetworkPolicyParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerNetworkPolicyParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWLIST = "allowlist" + DISABLED = "disabled" + + + class azure.ai.agentserver.responses.models.ContainerReferenceResource(FunctionShellCallEnvironment, discriminator='container_reference'): + container_id: str + type: Literal[FunctionShellCallEnvironmentType.CONTAINER_REFERENCE] + + @overload + def __init__( + self, + *, + container_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerSkill(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INLINE = "inline" + SKILL_REFERENCE = "skill_reference" + + + class azure.ai.agentserver.responses.models.ContextManagementParam(_Model): + compact_threshold: Optional[int] + type: str + + @overload + def __init__( + self, + *, + compact_threshold: Optional[int] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ConversationParam_2(_Model): + id: str + + @overload + def __init__( + self, + *, + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ConversationReference(_Model): + id: str + + @overload + def __init__( + self, + *, + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CoordParam(_Model): + x: int + y: int + + @overload + def __init__( + self, + *, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CreateResponse(CreateResponseGenerated): + prompt_cache_key: Optional[str] + safety_identifier: Optional[str] + temperature: Optional[float] + top_p: Optional[float] + user: Optional[str] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + background: Optional[bool] = ..., + context_management: Optional[list[ContextManagementParam]] = ..., + conversation: Optional[ConversationParam] = ..., + include: Optional[list[Union[str, IncludeEnum]]] = ..., + input: Optional[InputParam] = ..., + instructions: Optional[str] = ..., + max_output_tokens: Optional[int] = ..., + max_tool_calls: Optional[int] = ..., + metadata: Optional[Metadata] = ..., + model: Optional[str] = ..., + parallel_tool_calls: Optional[bool] = ..., + previous_response_id: Optional[str] = ..., + prompt: Optional[Prompt] = ..., + prompt_cache_key: Optional[str] = ..., + prompt_cache_retention: Optional[Literal[in-memory, 24h]] = ..., + reasoning: Optional[Reasoning] = ..., + safety_identifier: Optional[str] = ..., + service_tier: Optional[Literal[auto, default, flex, scale, priority]] = ..., + store: Optional[bool] = ..., + stream: Optional[bool] = ..., + stream_options: Optional[ResponseStreamOptions] = ..., + structured_inputs: Optional[dict[str, Any]] = ..., + temperature: Optional[int] = ..., + text: Optional[ResponseTextParam] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_logprobs: Optional[int] = ..., + top_p: Optional[int] = ..., + truncation: Optional[Literal[auto, disabled]] = ..., + user: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CustomGrammarFormatParam(CustomToolParamFormat, discriminator='grammar'): + definition: str + syntax: Union[str, GrammarSyntax1] + type: Literal[CustomToolParamFormatType.GRAMMAR] + + @overload + def __init__( + self, + *, + definition: str, + syntax: Union[str, GrammarSyntax1] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CustomTextFormatParam(CustomToolParamFormat, discriminator='text'): + type: Literal[CustomToolParamFormatType.TEXT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CustomToolParam(Tool, discriminator='custom'): + description: Optional[str] + format: Optional[CustomToolParamFormat] + name: str + type: Literal[ToolType.CUSTOM] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + format: Optional[CustomToolParamFormat] = ..., + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CustomToolParamFormat(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.CustomToolParamFormatType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GRAMMAR = "grammar" + TEXT = "text" + + + class azure.ai.agentserver.responses.models.DeleteResponseResult(_Model): + deleted: Literal[True] + id: str + object: Literal["response"] + + @overload + def __init__( + self, + *, + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.DetailEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + HIGH = "high" + LOW = "low" + + + class azure.ai.agentserver.responses.models.DoubleClickAction(ComputerAction, discriminator='double_click'): + type: Literal[ComputerActionType.DOUBLE_CLICK] + x: int + y: int + + @overload + def __init__( + self, + *, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.DragParam(ComputerAction, discriminator='drag'): + path: list[CoordParam] + type: Literal[ComputerActionType.DRAG] + + @overload + def __init__( + self, + *, + path: list[CoordParam] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.Error(_Model): + additional_info: Optional[dict[str, Any]] + code: str + debug_info: Optional[dict[str, Any]] + details: Optional[list[Error]] + message: str + param: Optional[str] + type: Optional[str] + + @overload + def __init__( + self, + *, + additional_info: Optional[dict[str, Any]] = ..., + code: str, + debug_info: Optional[dict[str, Any]] = ..., + details: Optional[list[Error]] = ..., + message: str, + param: Optional[str] = ..., + type: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FabricDataAgentToolCall(OutputItem, discriminator='fabric_dataagent_preview_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.FABRIC_DATAAGENT_PREVIEW_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FabricDataAgentToolCallOutput(OutputItem, discriminator='fabric_dataagent_preview_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.FABRIC_DATAAGENT_PREVIEW_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FabricDataAgentToolParameters(_Model): + description: Optional[str] + name: Optional[str] + project_connections: Optional[list[ToolProjectConnection]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connections: Optional[list[ToolProjectConnection]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FileCitationBody(Annotation, discriminator='file_citation'): + file_id: str + filename: str + index: int + type: Literal[AnnotationType.FILE_CITATION] + + @overload + def __init__( + self, + *, + file_id: str, + filename: str, + index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FilePath(Annotation, discriminator='file_path'): + file_id: str + index: int + type: Literal[AnnotationType.FILE_PATH] + + @overload + def __init__( + self, + *, + file_id: str, + index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FileSearchTool(Tool, discriminator='file_search'): + description: Optional[str] + filters: Optional[Filters] + max_num_results: Optional[int] + name: Optional[str] + ranking_options: Optional[RankingOptions] + type: Literal[ToolType.FILE_SEARCH] + vector_store_ids: list[str] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + filters: Optional[Filters] = ..., + max_num_results: Optional[int] = ..., + name: Optional[str] = ..., + ranking_options: Optional[RankingOptions] = ..., + vector_store_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FileSearchToolCallResults(_Model): + attributes: Optional[VectorStoreFileAttributes] + file_id: Optional[str] + filename: Optional[str] + score: Optional[float] + text: Optional[str] + + @overload + def __init__( + self, + *, + attributes: Optional[VectorStoreFileAttributes] = ..., + file_id: Optional[str] = ..., + filename: Optional[str] = ..., + score: Optional[float] = ..., + text: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionAndCustomToolCallOutput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionAndCustomToolCallOutputInputFileContent(FunctionAndCustomToolCallOutput, discriminator='input_file'): + file_data: Optional[str] + file_id: Optional[str] + file_url: Optional[str] + filename: Optional[str] + type: Literal[FunctionAndCustomToolCallOutputType.INPUT_FILE] + + @overload + def __init__( + self, + *, + file_data: Optional[str] = ..., + file_id: Optional[str] = ..., + file_url: Optional[str] = ..., + filename: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionAndCustomToolCallOutputInputImageContent(FunctionAndCustomToolCallOutput, discriminator='input_image'): + detail: Union[str, ImageDetail] + file_id: Optional[str] + image_url: Optional[str] + type: Literal[FunctionAndCustomToolCallOutputType.INPUT_IMAGE] + + @overload + def __init__( + self, + *, + detail: Union[str, ImageDetail], + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionAndCustomToolCallOutputInputTextContent(FunctionAndCustomToolCallOutput, discriminator='input_text'): + text: str + type: Literal[FunctionAndCustomToolCallOutputType.INPUT_TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionAndCustomToolCallOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INPUT_FILE = "input_file" + INPUT_IMAGE = "input_image" + INPUT_TEXT = "input_text" + + + class azure.ai.agentserver.responses.models.FunctionCallItemStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.FunctionCallOutputItemParam(Item, discriminator='function_call_output'): + call_id: str + id: Optional[str] + output: Union[str, list[Union[InputTextContentParam, InputImageContentParamAutoParam, InputFileContentParam]]] + status: Optional[Union[str, FunctionCallItemStatus]] + type: Literal[ItemType.FUNCTION_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[Union[InputTextContentParam, InputImageContentParamAutoParam, InputFileContentParam]]], + status: Optional[Union[str, FunctionCallItemStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellAction(_Model): + commands: list[str] + max_output_length: int + timeout_ms: int + + @overload + def __init__( + self, + *, + commands: list[str], + max_output_length: int, + timeout_ms: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellActionParam(_Model): + commands: list[str] + max_output_length: Optional[int] + timeout_ms: Optional[int] + + @overload + def __init__( + self, + *, + commands: list[str], + max_output_length: Optional[int] = ..., + timeout_ms: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallEnvironment(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_REFERENCE = "container_reference" + LOCAL = "local" + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemParam(Item, discriminator='shell_call'): + action: FunctionShellActionParam + call_id: str + environment: Optional[FunctionShellCallItemParamEnvironment] + id: Optional[str] + status: Optional[Union[str, FunctionShellCallItemStatus]] + type: Literal[ItemType.SHELL_CALL] + + @overload + def __init__( + self, + *, + action: FunctionShellActionParam, + call_id: str, + environment: Optional[FunctionShellCallItemParamEnvironment] = ..., + id: Optional[str] = ..., + status: Optional[Union[str, FunctionShellCallItemStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemParamEnvironment(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemParamEnvironmentContainerReferenceParam(FunctionShellCallItemParamEnvironment, discriminator='container_reference'): + container_id: str + type: Literal[FunctionShellCallItemParamEnvironmentType.CONTAINER_REFERENCE] + + @overload + def __init__( + self, + *, + container_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemParamEnvironmentLocalEnvironmentParam(FunctionShellCallItemParamEnvironment, discriminator='local'): + skills: Optional[list[LocalSkillParam]] + type: Literal[FunctionShellCallItemParamEnvironmentType.LOCAL] + + @overload + def __init__( + self, + *, + skills: Optional[list[LocalSkillParam]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_REFERENCE = "container_reference" + LOCAL = "local" + + + class azure.ai.agentserver.responses.models.FunctionShellCallItemStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputContent(_Model): + created_by: Optional[str] + outcome: FunctionShellCallOutputOutcome + stderr: str + stdout: str + + @overload + def __init__( + self, + *, + created_by: Optional[str] = ..., + outcome: FunctionShellCallOutputOutcome, + stderr: str, + stdout: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputContentParam(_Model): + outcome: FunctionShellCallOutputOutcomeParam + stderr: str + stdout: str + + @overload + def __init__( + self, + *, + outcome: FunctionShellCallOutputOutcomeParam, + stderr: str, + stdout: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputExitOutcome(FunctionShellCallOutputOutcome, discriminator='exit'): + exit_code: int + type: Literal[FunctionShellCallOutputOutcomeType.EXIT] + + @overload + def __init__( + self, + *, + exit_code: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputExitOutcomeParam(FunctionShellCallOutputOutcomeParam, discriminator='exit'): + exit_code: int + type: Literal[FunctionShellCallOutputOutcomeParamType.EXIT] + + @overload + def __init__( + self, + *, + exit_code: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputItemParam(Item, discriminator='shell_call_output'): + call_id: str + id: Optional[str] + max_output_length: Optional[int] + output: list[FunctionShellCallOutputContentParam] + status: Optional[Union[str, FunctionShellCallItemStatus]] + type: Literal[ItemType.SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + max_output_length: Optional[int] = ..., + output: list[FunctionShellCallOutputContentParam], + status: Optional[Union[str, FunctionShellCallItemStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputOutcome(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputOutcomeParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputOutcomeParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EXIT = "exit" + TIMEOUT = "timeout" + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputOutcomeType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EXIT = "exit" + TIMEOUT = "timeout" + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputTimeoutOutcome(FunctionShellCallOutputOutcome, discriminator='timeout'): + type: Literal[FunctionShellCallOutputOutcomeType.TIMEOUT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellCallOutputTimeoutOutcomeParam(FunctionShellCallOutputOutcomeParam, discriminator='timeout'): + type: Literal[FunctionShellCallOutputOutcomeParamType.TIMEOUT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellToolParam(Tool, discriminator='shell'): + description: Optional[str] + environment: Optional[FunctionShellToolParamEnvironment] + name: Optional[str] + type: Literal[ToolType.SHELL] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + environment: Optional[FunctionShellToolParamEnvironment] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellToolParamEnvironment(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellToolParamEnvironmentContainerReferenceParam(FunctionShellToolParamEnvironment, discriminator='container_reference'): + container_id: str + type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_REFERENCE] + + @overload + def __init__( + self, + *, + container_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam(FunctionShellToolParamEnvironment, discriminator='local'): + skills: Optional[list[LocalSkillParam]] + type: Literal[FunctionShellToolParamEnvironmentType.LOCAL] + + @overload + def __init__( + self, + *, + skills: Optional[list[LocalSkillParam]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionShellToolParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_AUTO = "container_auto" + CONTAINER_REFERENCE = "container_reference" + LOCAL = "local" + + + class azure.ai.agentserver.responses.models.FunctionTool(Tool, discriminator='function'): + description: Optional[str] + name: str + parameters: dict[str, Any] + strict: bool + type: Literal[ToolType.FUNCTION] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any], + strict: bool + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionToolCallOutput(ItemField, discriminator='function_call_output'): + call_id: str + id: Optional[str] + output: Union[str, list[FunctionAndCustomToolCallOutput]] + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemFieldType.FUNCTION_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[FunctionAndCustomToolCallOutput]], + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.FunctionToolCallOutputResource(OutputItem, discriminator='function_call_output'): + agent_reference: AgentReference + call_id: str + id: Optional[str] + output: Union[str, list[FunctionAndCustomToolCallOutput]] + response_id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[OutputItemType.FUNCTION_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[FunctionAndCustomToolCallOutput]], + response_id: Optional[str] = ..., + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.GrammarSyntax1(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LARK = "lark" + REGEX = "regex" + + + class azure.ai.agentserver.responses.models.HybridSearchOptions(_Model): + embedding_weight: int + text_weight: int + + @overload + def __init__( + self, + *, + embedding_weight: int, + text_weight: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ImageDetail(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + HIGH = "high" + LOW = "low" + + + class azure.ai.agentserver.responses.models.ImageGenActionEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + EDIT = "edit" + GENERATE = "generate" + + + class azure.ai.agentserver.responses.models.ImageGenTool(Tool, discriminator='image_generation'): + action: Optional[Union[str, ImageGenActionEnum]] + background: Optional[Literal["transparent", "opaque", "auto"]] + description: Optional[str] + input_fidelity: Optional[Union[str, InputFidelity]] + input_image_mask: Optional[ImageGenToolInputImageMask] + model: Optional[Union[Literal["gpt-image-1"], Literal["gpt-image-1-mini"], Literal["gpt-image-5"], str]] + moderation: Optional[Literal["auto", "low"]] + name: Optional[str] + output_compression: Optional[int] + output_format: Optional[Literal["png", "webp", "jpeg"]] + partial_images: Optional[int] + quality: Optional[Literal["low", "medium", "high", "auto"]] + size: Optional[Literal["1024x1024", "1024x1536", "1536x1024", "auto"]] + type: Literal[ToolType.IMAGE_GENERATION] + + @overload + def __init__( + self, + *, + action: Optional[Union[str, ImageGenActionEnum]] = ..., + background: Optional[Literal[transparent, opaque, auto]] = ..., + description: Optional[str] = ..., + input_fidelity: Optional[Union[str, InputFidelity]] = ..., + input_image_mask: Optional[ImageGenToolInputImageMask] = ..., + model: Optional[Union[Literal[gpt-image-1], Literal[gpt-image-1-mini], Literal[gpt-image-5], str]] = ..., + moderation: Optional[Literal[auto, low]] = ..., + name: Optional[str] = ..., + output_compression: Optional[int] = ..., + output_format: Optional[Literal[png, webp, jpeg]] = ..., + partial_images: Optional[int] = ..., + quality: Optional[Literal[low, medium, high, auto]] = ..., + size: Optional[Literal[1024x1024, 1024x1536, 1536x1024, auto]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ImageGenToolInputImageMask(_Model): + file_id: Optional[str] + image_url: Optional[str] + + @overload + def __init__( + self, + *, + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.IncludeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE_INTERPRETER_CALL_OUTPUTS = "code_interpreter_call.outputs" + COMPUTER_CALL_OUTPUT_OUTPUT_IMAGE_URL = "computer_call_output.output.image_url" + FILE_SEARCH_CALL_RESULTS = "file_search_call.results" + MEMORY_SEARCH_CALL_RESULTS = "memory_search_call.results" + MESSAGE_INPUT_IMAGE_IMAGE_URL = "message.input_image.image_url" + MESSAGE_OUTPUT_TEXT_LOGPROBS = "message.output_text.logprobs" + REASONING_ENCRYPTED_CONTENT = "reasoning.encrypted_content" + WEB_SEARCH_CALL_ACTION_SOURCES = "web_search_call.action.sources" + WEB_SEARCH_CALL_RESULTS = "web_search_call.results" + + + class azure.ai.agentserver.responses.models.InlineSkillParam(ContainerSkill, discriminator='inline'): + description: str + name: str + source: InlineSkillSourceParam + type: Literal[ContainerSkillType.INLINE] + + @overload + def __init__( + self, + *, + description: str, + name: str, + source: InlineSkillSourceParam + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InlineSkillSourceParam(_Model): + data: str + media_type: Literal["application/zip"] + type: Literal["base64"] + + @overload + def __init__( + self, + *, + data: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputFidelity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + + + class azure.ai.agentserver.responses.models.InputFileContent(_Model): + file_data: Optional[str] + file_id: Optional[str] + file_url: Optional[str] + filename: Optional[str] + type: Literal["input_file"] + + @overload + def __init__( + self, + *, + file_data: Optional[str] = ..., + file_id: Optional[str] = ..., + file_url: Optional[str] = ..., + filename: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputFileContentParam(_Model): + file_data: Optional[str] + file_id: Optional[str] + file_url: Optional[str] + filename: Optional[str] + type: Literal["input_file"] + + @overload + def __init__( + self, + *, + file_data: Optional[str] = ..., + file_id: Optional[str] = ..., + file_url: Optional[str] = ..., + filename: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputImageContent(_Model): + detail: Union[str, ImageDetail] + file_id: Optional[str] + image_url: Optional[str] + type: Literal["input_image"] + + @overload + def __init__( + self, + *, + detail: Union[str, ImageDetail], + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputImageContentParamAutoParam(_Model): + detail: Optional[Union[str, DetailEnum]] + file_id: Optional[str] + image_url: Optional[str] + type: Literal["input_image"] + + @overload + def __init__( + self, + *, + detail: Optional[Union[str, DetailEnum]] = ..., + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputTextContent(_Model): + text: str + type: Literal["input_text"] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.InputTextContentParam(_Model): + text: str + type: Literal["input_text"] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.Item(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemCodeInterpreterToolCall(Item, discriminator='code_interpreter_call'): + code: str + container_id: str + id: str + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]] + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + type: Literal[ItemType.CODE_INTERPRETER_CALL] + + @overload + def __init__( + self, + *, + code: str, + container_id: str, + id: str, + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]], + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemComputerToolCall(Item, discriminator='computer_call'): + action: ComputerAction + call_id: str + id: str + pending_safety_checks: list[ComputerCallSafetyCheckParam] + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[ItemType.COMPUTER_CALL] + + @overload + def __init__( + self, + *, + action: ComputerAction, + call_id: str, + id: str, + pending_safety_checks: list[ComputerCallSafetyCheckParam], + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemCustomToolCall(Item, discriminator='custom_tool_call'): + call_id: str + id: Optional[str] + input: str + name: str + type: Literal[ItemType.CUSTOM_TOOL_CALL] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + input: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemCustomToolCallOutput(Item, discriminator='custom_tool_call_output'): + call_id: str + id: Optional[str] + output: Union[str, list[FunctionAndCustomToolCallOutput]] + type: Literal[ItemType.CUSTOM_TOOL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[FunctionAndCustomToolCallOutput]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemField(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldApplyPatchToolCall(ItemField, discriminator='apply_patch_call'): + call_id: str + created_by: Optional[str] + id: str + operation: ApplyPatchFileOperation + status: Union[str, ApplyPatchCallStatus] + type: Literal[ItemFieldType.APPLY_PATCH_CALL] + + @overload + def __init__( + self, + *, + call_id: str, + created_by: Optional[str] = ..., + id: str, + operation: ApplyPatchFileOperation, + status: Union[str, ApplyPatchCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldApplyPatchToolCallOutput(ItemField, discriminator='apply_patch_call_output'): + call_id: str + created_by: Optional[str] + id: str + output: Optional[str] + status: Union[str, ApplyPatchCallOutputStatus] + type: Literal[ItemFieldType.APPLY_PATCH_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + created_by: Optional[str] = ..., + id: str, + output: Optional[str] = ..., + status: Union[str, ApplyPatchCallOutputStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldCodeInterpreterToolCall(ItemField, discriminator='code_interpreter_call'): + code: str + container_id: str + id: str + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]] + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + type: Literal[ItemFieldType.CODE_INTERPRETER_CALL] + + @overload + def __init__( + self, + *, + code: str, + container_id: str, + id: str, + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]], + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldCompactionBody(ItemField, discriminator='compaction'): + created_by: Optional[str] + encrypted_content: str + id: str + type: Literal[ItemFieldType.COMPACTION] + + @overload + def __init__( + self, + *, + created_by: Optional[str] = ..., + encrypted_content: str, + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldComputerToolCall(ItemField, discriminator='computer_call'): + action: ComputerAction + call_id: str + id: str + pending_safety_checks: list[ComputerCallSafetyCheckParam] + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[ItemFieldType.COMPUTER_CALL] + + @overload + def __init__( + self, + *, + action: ComputerAction, + call_id: str, + id: str, + pending_safety_checks: list[ComputerCallSafetyCheckParam], + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldComputerToolCallOutputResource(ItemField, discriminator='computer_call_output'): + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] + call_id: str + id: Optional[str] + output: ComputerScreenshotImage + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemFieldType.COMPUTER_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] = ..., + call_id: str, + id: Optional[str] = ..., + output: ComputerScreenshotImage, + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldCustomToolCall(ItemField, discriminator='custom_tool_call'): + call_id: str + id: Optional[str] + input: str + name: str + type: Literal[ItemFieldType.CUSTOM_TOOL_CALL] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + input: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldCustomToolCallOutput(ItemField, discriminator='custom_tool_call_output'): + call_id: str + id: Optional[str] + output: Union[str, list[FunctionAndCustomToolCallOutput]] + type: Literal[ItemFieldType.CUSTOM_TOOL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[FunctionAndCustomToolCallOutput]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldFileSearchToolCall(ItemField, discriminator='file_search_call'): + id: str + queries: list[str] + results: Optional[list[FileSearchToolCallResults]] + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + type: Literal[ItemFieldType.FILE_SEARCH_CALL] + + @overload + def __init__( + self, + *, + id: str, + queries: list[str], + results: Optional[list[FileSearchToolCallResults]] = ..., + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldFunctionShellCall(ItemField, discriminator='shell_call'): + action: FunctionShellAction + call_id: str + created_by: Optional[str] + environment: FunctionShellCallEnvironment + id: str + status: Union[str, LocalShellCallStatus] + type: Literal[ItemFieldType.SHELL_CALL] + + @overload + def __init__( + self, + *, + action: FunctionShellAction, + call_id: str, + created_by: Optional[str] = ..., + environment: FunctionShellCallEnvironment, + id: str, + status: Union[str, LocalShellCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldFunctionShellCallOutput(ItemField, discriminator='shell_call_output'): + call_id: str + created_by: Optional[str] + id: str + max_output_length: int + output: list[FunctionShellCallOutputContent] + status: Union[str, LocalShellCallOutputStatusEnum] + type: Literal[ItemFieldType.SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + call_id: str, + created_by: Optional[str] = ..., + id: str, + max_output_length: int, + output: list[FunctionShellCallOutputContent], + status: Union[str, LocalShellCallOutputStatusEnum] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldFunctionToolCall(ItemField, discriminator='function_call'): + arguments: str + call_id: str + id: Optional[str] + name: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemFieldType.FUNCTION_CALL] + + @overload + def __init__( + self, + *, + arguments: str, + call_id: str, + id: Optional[str] = ..., + name: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldImageGenToolCall(ItemField, discriminator='image_generation_call'): + id: str + result: str + status: Literal["in_progress", "completed", "generating", "failed"] + type: Literal[ItemFieldType.IMAGE_GENERATION_CALL] + + @overload + def __init__( + self, + *, + id: str, + result: str, + status: Literal["in_progress", "completed", "generating", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldLocalShellToolCall(ItemField, discriminator='local_shell_call'): + action: LocalShellExecAction + call_id: str + id: str + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[ItemFieldType.LOCAL_SHELL_CALL] + + @overload + def __init__( + self, + *, + action: LocalShellExecAction, + call_id: str, + id: str, + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldLocalShellToolCallOutput(ItemField, discriminator='local_shell_call_output'): + id: str + output: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemFieldType.LOCAL_SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + id: str, + output: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldMcpApprovalRequest(ItemField, discriminator='mcp_approval_request'): + arguments: str + id: str + name: str + server_label: str + type: Literal[ItemFieldType.MCP_APPROVAL_REQUEST] + + @overload + def __init__( + self, + *, + arguments: str, + id: str, + name: str, + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldMcpApprovalResponseResource(ItemField, discriminator='mcp_approval_response'): + approval_request_id: str + approve: bool + id: str + reason: Optional[str] + type: Literal[ItemFieldType.MCP_APPROVAL_RESPONSE] + + @overload + def __init__( + self, + *, + approval_request_id: str, + approve: bool, + id: str, + reason: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldMcpListTools(ItemField, discriminator='mcp_list_tools'): + error: Optional[str] + id: str + server_label: str + tools: list[MCPListToolsTool] + type: Literal[ItemFieldType.MCP_LIST_TOOLS] + + @overload + def __init__( + self, + *, + error: Optional[str] = ..., + id: str, + server_label: str, + tools: list[MCPListToolsTool] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldMcpToolCall(ItemField, discriminator='mcp_call'): + approval_request_id: Optional[str] + arguments: str + error: Optional[dict[str, Any]] + id: str + name: str + output: Optional[str] + server_label: str + status: Optional[Union[str, MCPToolCallStatus]] + type: Literal[ItemFieldType.MCP_CALL] + + @overload + def __init__( + self, + *, + approval_request_id: Optional[str] = ..., + arguments: str, + error: Optional[dict[str, Any]] = ..., + id: str, + name: str, + output: Optional[str] = ..., + server_label: str, + status: Optional[Union[str, MCPToolCallStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldMessage(ItemField, discriminator='message'): + content: list[MessageContent] + id: str + role: Union[str, MessageRole] + status: Union[str, MessageStatus] + type: Literal[ItemFieldType.MESSAGE] + + @overload + def __init__( + self, + *, + content: list[MessageContent], + id: str, + role: Union[str, MessageRole], + status: Union[str, MessageStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldReasoningItem(ItemField, discriminator='reasoning'): + content: Optional[list[ReasoningTextContent]] + encrypted_content: Optional[str] + id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + summary: list[SummaryTextContent] + type: Literal[ItemFieldType.REASONING] + + @overload + def __init__( + self, + *, + content: Optional[list[ReasoningTextContent]] = ..., + encrypted_content: Optional[str] = ..., + id: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ..., + summary: list[SummaryTextContent] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFieldType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + APPLY_PATCH_CALL = "apply_patch_call" + APPLY_PATCH_CALL_OUTPUT = "apply_patch_call_output" + CODE_INTERPRETER_CALL = "code_interpreter_call" + COMPACTION = "compaction" + COMPUTER_CALL = "computer_call" + COMPUTER_CALL_OUTPUT = "computer_call_output" + CUSTOM_TOOL_CALL = "custom_tool_call" + CUSTOM_TOOL_CALL_OUTPUT = "custom_tool_call_output" + FILE_SEARCH_CALL = "file_search_call" + FUNCTION_CALL = "function_call" + FUNCTION_CALL_OUTPUT = "function_call_output" + IMAGE_GENERATION_CALL = "image_generation_call" + LOCAL_SHELL_CALL = "local_shell_call" + LOCAL_SHELL_CALL_OUTPUT = "local_shell_call_output" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + MCP_CALL = "mcp_call" + MCP_LIST_TOOLS = "mcp_list_tools" + MESSAGE = "message" + REASONING = "reasoning" + SHELL_CALL = "shell_call" + SHELL_CALL_OUTPUT = "shell_call_output" + WEB_SEARCH_CALL = "web_search_call" + + + class azure.ai.agentserver.responses.models.ItemFieldWebSearchToolCall(ItemField, discriminator='web_search_call'): + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind] + id: str + status: Literal["in_progress", "searching", "completed", "failed"] + type: Literal[ItemFieldType.WEB_SEARCH_CALL] + + @overload + def __init__( + self, + *, + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind], + id: str, + status: Literal["in_progress", "searching", "completed", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFileSearchToolCall(Item, discriminator='file_search_call'): + id: str + queries: list[str] + results: Optional[list[FileSearchToolCallResults]] + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + type: Literal[ItemType.FILE_SEARCH_CALL] + + @overload + def __init__( + self, + *, + id: str, + queries: list[str], + results: Optional[list[FileSearchToolCallResults]] = ..., + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemFunctionToolCall(Item, discriminator='function_call'): + arguments: str + call_id: str + id: Optional[str] + name: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemType.FUNCTION_CALL] + + @overload + def __init__( + self, + *, + arguments: str, + call_id: str, + id: Optional[str] = ..., + name: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemImageGenToolCall(Item, discriminator='image_generation_call'): + id: str + result: str + status: Literal["in_progress", "completed", "generating", "failed"] + type: Literal[ItemType.IMAGE_GENERATION_CALL] + + @overload + def __init__( + self, + *, + id: str, + result: str, + status: Literal["in_progress", "completed", "generating", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemLocalShellToolCall(Item, discriminator='local_shell_call'): + action: LocalShellExecAction + call_id: str + id: str + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[ItemType.LOCAL_SHELL_CALL] + + @overload + def __init__( + self, + *, + action: LocalShellExecAction, + call_id: str, + id: str, + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemLocalShellToolCallOutput(Item, discriminator='local_shell_call_output'): + id: str + output: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[ItemType.LOCAL_SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + id: str, + output: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemMcpApprovalRequest(Item, discriminator='mcp_approval_request'): + arguments: str + id: str + name: str + server_label: str + type: Literal[ItemType.MCP_APPROVAL_REQUEST] + + @overload + def __init__( + self, + *, + arguments: str, + id: str, + name: str, + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemMcpListTools(Item, discriminator='mcp_list_tools'): + error: Optional[str] + id: str + server_label: str + tools: list[MCPListToolsTool] + type: Literal[ItemType.MCP_LIST_TOOLS] + + @overload + def __init__( + self, + *, + error: Optional[str] = ..., + id: str, + server_label: str, + tools: list[MCPListToolsTool] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemMcpToolCall(Item, discriminator='mcp_call'): + approval_request_id: Optional[str] + arguments: str + error: Optional[dict[str, Any]] + id: str + name: str + output: Optional[str] + server_label: str + status: Optional[Union[str, MCPToolCallStatus]] + type: Literal[ItemType.MCP_CALL] + + @overload + def __init__( + self, + *, + approval_request_id: Optional[str] = ..., + arguments: str, + error: Optional[dict[str, Any]] = ..., + id: str, + name: str, + output: Optional[str] = ..., + server_label: str, + status: Optional[Union[str, MCPToolCallStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemMessage(Item, discriminator='message'): + content: Union[str, list[MessageContent]] + role: Union[str, MessageRole] + type: Literal[ItemType.MESSAGE] + + @overload + def __init__( + self, + *, + content: Union[str, list[MessageContent]], + role: Union[str, MessageRole] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemOutputMessage(Item, discriminator='output_message'): + content: list[OutputMessageContent] + id: str + role: Literal["assistant"] + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[ItemType.OUTPUT_MESSAGE] + + @overload + def __init__( + self, + *, + content: list[OutputMessageContent], + id: str, + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemReasoningItem(Item, discriminator='reasoning'): + content: Optional[list[ReasoningTextContent]] + encrypted_content: Optional[str] + id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + summary: list[SummaryTextContent] + type: Literal[ItemType.REASONING] + + @overload + def __init__( + self, + *, + content: Optional[list[ReasoningTextContent]] = ..., + encrypted_content: Optional[str] = ..., + id: str, + status: Optional[Literal[in_progress, completed, incomplete]] = ..., + summary: list[SummaryTextContent] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemReferenceParam(Item, discriminator='item_reference'): + id: str + type: Literal[ItemType.ITEM_REFERENCE] + + @overload + def __init__( + self, + *, + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2_A_PREVIEW_CALL = "a2a_preview_call" + A2_A_PREVIEW_CALL_OUTPUT = "a2a_preview_call_output" + APPLY_PATCH_CALL = "apply_patch_call" + APPLY_PATCH_CALL_OUTPUT = "apply_patch_call_output" + AZURE_AI_SEARCH_CALL = "azure_ai_search_call" + AZURE_AI_SEARCH_CALL_OUTPUT = "azure_ai_search_call_output" + AZURE_FUNCTION_CALL = "azure_function_call" + AZURE_FUNCTION_CALL_OUTPUT = "azure_function_call_output" + BING_CUSTOM_SEARCH_PREVIEW_CALL = "bing_custom_search_preview_call" + BING_CUSTOM_SEARCH_PREVIEW_CALL_OUTPUT = "bing_custom_search_preview_call_output" + BING_GROUNDING_CALL = "bing_grounding_call" + BING_GROUNDING_CALL_OUTPUT = "bing_grounding_call_output" + BROWSER_AUTOMATION_PREVIEW_CALL = "browser_automation_preview_call" + BROWSER_AUTOMATION_PREVIEW_CALL_OUTPUT = "browser_automation_preview_call_output" + CODE_INTERPRETER_CALL = "code_interpreter_call" + COMPACTION = "compaction" + COMPUTER_CALL = "computer_call" + COMPUTER_CALL_OUTPUT = "computer_call_output" + CUSTOM_TOOL_CALL = "custom_tool_call" + CUSTOM_TOOL_CALL_OUTPUT = "custom_tool_call_output" + FABRIC_DATAAGENT_PREVIEW_CALL = "fabric_dataagent_preview_call" + FABRIC_DATAAGENT_PREVIEW_CALL_OUTPUT = "fabric_dataagent_preview_call_output" + FILE_SEARCH_CALL = "file_search_call" + FUNCTION_CALL = "function_call" + FUNCTION_CALL_OUTPUT = "function_call_output" + IMAGE_GENERATION_CALL = "image_generation_call" + ITEM_REFERENCE = "item_reference" + LOCAL_SHELL_CALL = "local_shell_call" + LOCAL_SHELL_CALL_OUTPUT = "local_shell_call_output" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + MCP_CALL = "mcp_call" + MCP_LIST_TOOLS = "mcp_list_tools" + MEMORY_SEARCH_CALL = "memory_search_call" + MESSAGE = "message" + OAUTH_CONSENT_REQUEST = "oauth_consent_request" + OPENAPI_CALL = "openapi_call" + OPENAPI_CALL_OUTPUT = "openapi_call_output" + OUTPUT_MESSAGE = "output_message" + REASONING = "reasoning" + SHAREPOINT_GROUNDING_PREVIEW_CALL = "sharepoint_grounding_preview_call" + SHAREPOINT_GROUNDING_PREVIEW_CALL_OUTPUT = "sharepoint_grounding_preview_call_output" + SHELL_CALL = "shell_call" + SHELL_CALL_OUTPUT = "shell_call_output" + STRUCTURED_OUTPUTS = "structured_outputs" + WEB_SEARCH_CALL = "web_search_call" + WORKFLOW_ACTION = "workflow_action" + + + class azure.ai.agentserver.responses.models.ItemWebSearchToolCall(Item, discriminator='web_search_call'): + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind] + id: str + status: Literal["in_progress", "searching", "completed", "failed"] + type: Literal[ItemType.WEB_SEARCH_CALL] + + @overload + def __init__( + self, + *, + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind], + id: str, + status: Literal["in_progress", "searching", "completed", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.KeyPressAction(ComputerAction, discriminator='keypress'): + keys_property: list[str] + type: Literal[ComputerActionType.KEYPRESS] + + @overload + def __init__( + self, + *, + keys_property: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.LocalEnvironmentResource(FunctionShellCallEnvironment, discriminator='local'): + type: Literal[FunctionShellCallEnvironmentType.LOCAL] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.LocalShellCallOutputStatusEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.LocalShellCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.LocalShellExecAction(_Model): + command: list[str] + env: dict[str, str] + timeout_ms: Optional[int] + type: Literal["exec"] + user: Optional[str] + working_directory: Optional[str] + + @overload + def __init__( + self, + *, + command: list[str], + env: dict[str, str], + timeout_ms: Optional[int] = ..., + user: Optional[str] = ..., + working_directory: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.LocalShellToolParam(Tool, discriminator='local_shell'): + description: Optional[str] + name: Optional[str] + type: Literal[ToolType.LOCAL_SHELL] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.LocalSkillParam(_Model): + description: str + name: str + path: str + + @overload + def __init__( + self, + *, + description: str, + name: str, + path: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.LogProb(_Model): + bytes: list[int] + logprob: int + token: str + top_logprobs: list[TopLogProb] + + @overload + def __init__( + self, + *, + bytes: list[int], + logprob: int, + token: str, + top_logprobs: list[TopLogProb] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MCPApprovalResponse(Item, discriminator='mcp_approval_response'): + approval_request_id: str + approve: bool + id: Optional[str] + reason: Optional[str] + type: Literal[ItemType.MCP_APPROVAL_RESPONSE] + + @overload + def __init__( + self, + *, + approval_request_id: str, + approve: bool, + id: Optional[str] = ..., + reason: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MCPListToolsTool(_Model): + annotations: Optional[MCPListToolsToolAnnotations] + description: Optional[str] + input_schema: MCPListToolsToolInputSchema + name: str + + @overload + def __init__( + self, + *, + annotations: Optional[MCPListToolsToolAnnotations] = ..., + description: Optional[str] = ..., + input_schema: MCPListToolsToolInputSchema, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MCPListToolsToolAnnotations(_Model): + + + class azure.ai.agentserver.responses.models.MCPListToolsToolInputSchema(_Model): + + + class azure.ai.agentserver.responses.models.MCPTool(Tool, discriminator='mcp'): + allowed_tools: Optional[Union[list[str], MCPToolFilter]] + authorization: Optional[str] + connector_id: Optional[Literal["connector_dropbox", "connector_gmail", "connector_googlecalendar", "connector_googledrive", "connector_microsoftteams", "connector_outlookcalendar", "connector_outlookemail", "connector_sharepoint"]] + headers: Optional[dict[str, str]] + project_connection_id: Optional[str] + require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] + server_description: Optional[str] + server_label: str + server_url: Optional[str] + type: Literal[ToolType.MCP] + + @overload + def __init__( + self, + *, + allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., + authorization: Optional[str] = ..., + connector_id: Optional[Literal[connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, connector_sharepoint]] = ..., + headers: Optional[dict[str, str]] = ..., + project_connection_id: Optional[str] = ..., + require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., + server_description: Optional[str] = ..., + server_label: str, + server_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MCPToolCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CALLING = "calling" + COMPLETED = "completed" + FAILED = "failed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.MCPToolFilter(_Model): + read_only: Optional[bool] + tool_names: Optional[list[str]] + + @overload + def __init__( + self, + *, + read_only: Optional[bool] = ..., + tool_names: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MCPToolRequireApproval(_Model): + always: Optional[MCPToolFilter] + never: Optional[MCPToolFilter] + + @overload + def __init__( + self, + *, + always: Optional[MCPToolFilter] = ..., + never: Optional[MCPToolFilter] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemoryItem(_Model): + content: str + kind: str + memory_id: str + scope: str + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + kind: str, + memory_id: str, + scope: str, + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemoryItemKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHAT_SUMMARY = "chat_summary" + USER_PROFILE = "user_profile" + + + class azure.ai.agentserver.responses.models.MemorySearchItem(_Model): + memory_item: MemoryItem + + @overload + def __init__( + self, + *, + memory_item: MemoryItem + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemorySearchOptions(_Model): + max_memories: Optional[int] + + @overload + def __init__( + self, + *, + max_memories: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemorySearchPreviewTool(Tool, discriminator='memory_search_preview'): + description: Optional[str] + memory_store_name: str + name: Optional[str] + scope: str + search_options: Optional[MemorySearchOptions] + type: Literal[ToolType.MEMORY_SEARCH_PREVIEW] + update_delay: Optional[int] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + memory_store_name: str, + name: Optional[str] = ..., + scope: str, + search_options: Optional[MemorySearchOptions] = ..., + update_delay: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemorySearchToolCallItemParam(Item, discriminator='memory_search_call'): + results: Optional[list[MemorySearchItem]] + type: Literal[ItemType.MEMORY_SEARCH_CALL] + + @overload + def __init__( + self, + *, + results: Optional[list[MemorySearchItem]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MemorySearchToolCallItemResource(OutputItem, discriminator='memory_search_call'): + agent_reference: AgentReference + id: str + response_id: str + results: Optional[list[MemorySearchItem]] + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + type: Literal[OutputItemType.MEMORY_SEARCH_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + id: str, + response_id: Optional[str] = ..., + results: Optional[list[MemorySearchItem]] = ..., + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContent(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentInputFileContent(MessageContent, discriminator='input_file'): + file_data: Optional[str] + file_id: Optional[str] + file_url: Optional[str] + filename: Optional[str] + type: Literal[MessageContentType.INPUT_FILE] + + @overload + def __init__( + self, + *, + file_data: Optional[str] = ..., + file_id: Optional[str] = ..., + file_url: Optional[str] = ..., + filename: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentInputImageContent(MessageContent, discriminator='input_image'): + detail: Union[str, ImageDetail] + file_id: Optional[str] + image_url: Optional[str] + type: Literal[MessageContentType.INPUT_IMAGE] + + @overload + def __init__( + self, + *, + detail: Union[str, ImageDetail], + file_id: Optional[str] = ..., + image_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentInputTextContent(MessageContent, discriminator='input_text'): + text: str + type: Literal[MessageContentType.INPUT_TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentOutputTextContent(MessageContent, discriminator='output_text'): + annotations: list[Annotation] + logprobs: list[LogProb] + text: str + type: Literal[MessageContentType.OUTPUT_TEXT] + + @overload + def __init__( + self, + *, + annotations: list[Annotation], + logprobs: list[LogProb], + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentReasoningTextContent(MessageContent, discriminator='reasoning_text'): + text: str + type: Literal[MessageContentType.REASONING_TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentRefusalContent(MessageContent, discriminator='refusal'): + refusal: str + type: Literal[MessageContentType.REFUSAL] + + @overload + def __init__( + self, + *, + refusal: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.MessageContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPUTER_SCREENSHOT = "computer_screenshot" + INPUT_FILE = "input_file" + INPUT_IMAGE = "input_image" + INPUT_TEXT = "input_text" + OUTPUT_TEXT = "output_text" + REASONING_TEXT = "reasoning_text" + REFUSAL = "refusal" + SUMMARY_TEXT = "summary_text" + TEXT = "text" + + + class azure.ai.agentserver.responses.models.MessageRole(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASSISTANT = "assistant" + CRITIC = "critic" + DEVELOPER = "developer" + DISCRIMINATOR = "discriminator" + SYSTEM = "system" + TOOL = "tool" + UNKNOWN = "unknown" + USER = "user" + + + class azure.ai.agentserver.responses.models.MessageStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.Metadata(_Model): + + + class azure.ai.agentserver.responses.models.MicrosoftFabricPreviewTool(Tool, discriminator='fabric_dataagent_preview'): + description: Optional[str] + fabric_dataagent_preview: FabricDataAgentToolParameters + name: Optional[str] + type: Literal[ToolType.FABRIC_DATAAGENT_PREVIEW] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + fabric_dataagent_preview: FabricDataAgentToolParameters, + name: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ModelIdsCompaction(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHATGPT4_O_LATEST = "chatgpt-4o-latest" + CODEX_MINI_LATEST = "codex-mini-latest" + COMPUTER_USE_PREVIEW = "computer-use-preview" + COMPUTER_USE_PREVIEW2025_03_11 = "computer-use-preview-2025-03-11" + GPT3_5_TURBO = "gpt-3.5-turbo" + GPT3_5_TURBO0125 = "gpt-3.5-turbo-0125" + GPT3_5_TURBO0301 = "gpt-3.5-turbo-0301" + GPT3_5_TURBO0613 = "gpt-3.5-turbo-0613" + GPT3_5_TURBO1106 = "gpt-3.5-turbo-1106" + GPT3_5_TURBO16_K = "gpt-3.5-turbo-16k" + GPT3_5_TURBO16_K0613 = "gpt-3.5-turbo-16k-0613" + GPT4 = "gpt-4" + GPT4_0125_PREVIEW = "gpt-4-0125-preview" + GPT4_0314 = "gpt-4-0314" + GPT4_0613 = "gpt-4-0613" + GPT4_1 = "gpt-4.1" + GPT4_1106_PREVIEW = "gpt-4-1106-preview" + GPT4_1_2025_04_14 = "gpt-4.1-2025-04-14" + GPT4_1_MINI = "gpt-4.1-mini" + GPT4_1_MINI2025_04_14 = "gpt-4.1-mini-2025-04-14" + GPT4_1_NANO = "gpt-4.1-nano" + GPT4_1_NANO2025_04_14 = "gpt-4.1-nano-2025-04-14" + GPT4_32_K = "gpt-4-32k" + GPT4_32_K0314 = "gpt-4-32k-0314" + GPT4_32_K0613 = "gpt-4-32k-0613" + GPT4_O = "gpt-4o" + GPT4_O2024_05_13 = "gpt-4o-2024-05-13" + GPT4_O2024_08_06 = "gpt-4o-2024-08-06" + GPT4_O2024_11_20 = "gpt-4o-2024-11-20" + GPT4_O_AUDIO_PREVIEW = "gpt-4o-audio-preview" + GPT4_O_AUDIO_PREVIEW2024_10_01 = "gpt-4o-audio-preview-2024-10-01" + GPT4_O_AUDIO_PREVIEW2024_12_17 = "gpt-4o-audio-preview-2024-12-17" + GPT4_O_AUDIO_PREVIEW2025_06_03 = "gpt-4o-audio-preview-2025-06-03" + GPT4_O_MINI = "gpt-4o-mini" + GPT4_O_MINI2024_07_18 = "gpt-4o-mini-2024-07-18" + GPT4_O_MINI_AUDIO_PREVIEW = "gpt-4o-mini-audio-preview" + GPT4_O_MINI_AUDIO_PREVIEW2024_12_17 = "gpt-4o-mini-audio-preview-2024-12-17" + GPT4_O_MINI_SEARCH_PREVIEW = "gpt-4o-mini-search-preview" + GPT4_O_MINI_SEARCH_PREVIEW2025_03_11 = "gpt-4o-mini-search-preview-2025-03-11" + GPT4_O_SEARCH_PREVIEW = "gpt-4o-search-preview" + GPT4_O_SEARCH_PREVIEW2025_03_11 = "gpt-4o-search-preview-2025-03-11" + GPT4_TURBO = "gpt-4-turbo" + GPT4_TURBO2024_04_09 = "gpt-4-turbo-2024-04-09" + GPT4_TURBO_PREVIEW = "gpt-4-turbo-preview" + GPT4_VISION_PREVIEW = "gpt-4-vision-preview" + GPT5 = "gpt-5" + GPT5_1 = "gpt-5.1" + GPT5_1_2025_11_13 = "gpt-5.1-2025-11-13" + GPT5_1_CHAT_LATEST = "gpt-5.1-chat-latest" + GPT5_1_CODEX = "gpt-5.1-codex" + GPT5_1_CODEX_MAX = "gpt-5.1-codex-max" + GPT5_1_MINI = "gpt-5.1-mini" + GPT5_2 = "gpt-5.2" + GPT5_2025_08_07 = "gpt-5-2025-08-07" + GPT5_2_2025_12_11 = "gpt-5.2-2025-12-11" + GPT5_2_CHAT_LATEST = "gpt-5.2-chat-latest" + GPT5_2_PRO = "gpt-5.2-pro" + GPT5_2_PRO2025_12_11 = "gpt-5.2-pro-2025-12-11" + GPT5_CHAT_LATEST = "gpt-5-chat-latest" + GPT5_CODEX = "gpt-5-codex" + GPT5_MINI = "gpt-5-mini" + GPT5_MINI2025_08_07 = "gpt-5-mini-2025-08-07" + GPT5_NANO = "gpt-5-nano" + GPT5_NANO2025_08_07 = "gpt-5-nano-2025-08-07" + GPT5_PRO = "gpt-5-pro" + GPT5_PRO2025_10_06 = "gpt-5-pro-2025-10-06" + O1 = "o1" + O1_2024_12_17 = "o1-2024-12-17" + O1_MINI = "o1-mini" + O1_MINI2024_09_12 = "o1-mini-2024-09-12" + O1_PREVIEW = "o1-preview" + O1_PREVIEW2024_09_12 = "o1-preview-2024-09-12" + O1_PRO = "o1-pro" + O1_PRO2025_03_19 = "o1-pro-2025-03-19" + O3 = "o3" + O3_2025_04_16 = "o3-2025-04-16" + O3_DEEP_RESEARCH = "o3-deep-research" + O3_DEEP_RESEARCH2025_06_26 = "o3-deep-research-2025-06-26" + O3_MINI = "o3-mini" + O3_MINI2025_01_31 = "o3-mini-2025-01-31" + O3_PRO = "o3-pro" + O3_PRO2025_06_10 = "o3-pro-2025-06-10" + O4_MINI = "o4-mini" + O4_MINI2025_04_16 = "o4-mini-2025-04-16" + O4_MINI_DEEP_RESEARCH = "o4-mini-deep-research" + O4_MINI_DEEP_RESEARCH2025_06_26 = "o4-mini-deep-research-2025-06-26" + + + class azure.ai.agentserver.responses.models.MoveParam(ComputerAction, discriminator='move'): + type: Literal[ComputerActionType.MOVE] + x: int + y: int + + @overload + def __init__( + self, + *, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OAuthConsentRequestOutputItem(OutputItem, discriminator='oauth_consent_request'): + agent_reference: AgentReference + consent_link: str + id: str + response_id: str + server_label: str + type: Literal[OutputItemType.OAUTH_CONSENT_REQUEST] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + consent_link: str, + id: str, + response_id: Optional[str] = ..., + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiAnonymousAuthDetails(OpenApiAuthDetails, discriminator='anonymous'): + type: Literal[OpenApiAuthType.ANONYMOUS] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiAuthDetails(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANONYMOUS = "anonymous" + MANAGED_IDENTITY = "managed_identity" + PROJECT_CONNECTION = "project_connection" + + + class azure.ai.agentserver.responses.models.OpenApiFunctionDefinition(_Model): + auth: OpenApiAuthDetails + default_params: Optional[list[str]] + description: Optional[str] + functions: Optional[list[OpenApiFunctionDefinitionFunction]] + name: str + spec: dict[str, Any] + + @overload + def __init__( + self, + *, + auth: OpenApiAuthDetails, + default_params: Optional[list[str]] = ..., + description: Optional[str] = ..., + name: str, + spec: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiFunctionDefinitionFunction(_Model): + description: Optional[str] + name: str + parameters: dict[str, Any] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiManagedAuthDetails(OpenApiAuthDetails, discriminator='managed_identity'): + security_scheme: OpenApiManagedSecurityScheme + type: Literal[OpenApiAuthType.MANAGED_IDENTITY] + + @overload + def __init__( + self, + *, + security_scheme: OpenApiManagedSecurityScheme + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiManagedSecurityScheme(_Model): + audience: str + + @overload + def __init__( + self, + *, + audience: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiProjectConnectionAuthDetails(OpenApiAuthDetails, discriminator='project_connection'): + security_scheme: OpenApiProjectConnectionSecurityScheme + type: Literal[OpenApiAuthType.PROJECT_CONNECTION] + + @overload + def __init__( + self, + *, + security_scheme: OpenApiProjectConnectionSecurityScheme + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiProjectConnectionSecurityScheme(_Model): + project_connection_id: str + + @overload + def __init__( + self, + *, + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiTool(Tool, discriminator='openapi'): + openapi: OpenApiFunctionDefinition + type: Literal[ToolType.OPENAPI] + + @overload + def __init__( + self, + *, + openapi: OpenApiFunctionDefinition + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiToolCall(OutputItem, discriminator='openapi_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + name: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.OPENAPI_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + name: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OpenApiToolCallOutput(OutputItem, discriminator='openapi_call_output'): + agent_reference: AgentReference + call_id: str + id: str + name: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.OPENAPI_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + name: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputContent(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputContentOutputTextContent(OutputContent, discriminator='output_text'): + annotations: list[Annotation] + logprobs: list[LogProb] + text: str + type: Literal[OutputContentType.OUTPUT_TEXT] + + @overload + def __init__( + self, + *, + annotations: list[Annotation], + logprobs: list[LogProb], + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputContentReasoningTextContent(OutputContent, discriminator='reasoning_text'): + text: str + type: Literal[OutputContentType.REASONING_TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputContentRefusalContent(OutputContent, discriminator='refusal'): + refusal: str + type: Literal[OutputContentType.REFUSAL] + + @overload + def __init__( + self, + *, + refusal: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + OUTPUT_TEXT = "output_text" + REASONING_TEXT = "reasoning_text" + REFUSAL = "refusal" + + + class azure.ai.agentserver.responses.models.OutputItem(_Model): + agent_reference: Optional[AgentReference] + response_id: Optional[str] + type: str + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + response_id: Optional[str] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemApplyPatchToolCall(OutputItem, discriminator='apply_patch_call'): + agent_reference: AgentReference + call_id: str + id: str + operation: ApplyPatchFileOperation + response_id: str + status: Union[str, ApplyPatchCallStatus] + type: Literal[OutputItemType.APPLY_PATCH_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + operation: ApplyPatchFileOperation, + response_id: Optional[str] = ..., + status: Union[str, ApplyPatchCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemApplyPatchToolCallOutput(OutputItem, discriminator='apply_patch_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[str] + response_id: str + status: Union[str, ApplyPatchCallOutputStatus] + type: Literal[OutputItemType.APPLY_PATCH_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[str] = ..., + response_id: Optional[str] = ..., + status: Union[str, ApplyPatchCallOutputStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemCodeInterpreterToolCall(OutputItem, discriminator='code_interpreter_call'): + agent_reference: AgentReference + code: str + container_id: str + id: str + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]] + response_id: str + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + type: Literal[OutputItemType.CODE_INTERPRETER_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + code: str, + container_id: str, + id: str, + outputs: list[Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage]], + response_id: Optional[str] = ..., + status: Literal["in_progress", "completed", "incomplete", "interpreting", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemCompactionBody(OutputItem, discriminator='compaction'): + agent_reference: AgentReference + encrypted_content: str + id: str + response_id: str + type: Literal[OutputItemType.COMPACTION] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + encrypted_content: str, + id: str, + response_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemComputerToolCall(OutputItem, discriminator='computer_call'): + action: ComputerAction + agent_reference: AgentReference + call_id: str + id: str + pending_safety_checks: list[ComputerCallSafetyCheckParam] + response_id: str + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[OutputItemType.COMPUTER_CALL] + + @overload + def __init__( + self, + *, + action: ComputerAction, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + pending_safety_checks: list[ComputerCallSafetyCheckParam], + response_id: Optional[str] = ..., + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemComputerToolCallOutputResource(OutputItem, discriminator='computer_call_output'): + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] + agent_reference: AgentReference + call_id: str + id: Optional[str] + output: ComputerScreenshotImage + response_id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[OutputItemType.COMPUTER_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + acknowledged_safety_checks: Optional[list[ComputerCallSafetyCheckParam]] = ..., + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: Optional[str] = ..., + output: ComputerScreenshotImage, + response_id: Optional[str] = ..., + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemCustomToolCall(OutputItem, discriminator='custom_tool_call'): + agent_reference: AgentReference + call_id: str + id: Optional[str] + input: str + name: str + response_id: str + type: Literal[OutputItemType.CUSTOM_TOOL_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: Optional[str] = ..., + input: str, + name: str, + response_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemCustomToolCallOutput(OutputItem, discriminator='custom_tool_call_output'): + agent_reference: AgentReference + call_id: str + id: Optional[str] + output: Union[str, list[FunctionAndCustomToolCallOutput]] + response_id: str + type: Literal[OutputItemType.CUSTOM_TOOL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: Optional[str] = ..., + output: Union[str, list[FunctionAndCustomToolCallOutput]], + response_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemFileSearchToolCall(OutputItem, discriminator='file_search_call'): + agent_reference: AgentReference + id: str + queries: list[str] + response_id: str + results: Optional[list[FileSearchToolCallResults]] + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + type: Literal[OutputItemType.FILE_SEARCH_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + id: str, + queries: list[str], + response_id: Optional[str] = ..., + results: Optional[list[FileSearchToolCallResults]] = ..., + status: Literal["in_progress", "searching", "completed", "incomplete", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemFunctionShellCall(OutputItem, discriminator='shell_call'): + action: FunctionShellAction + agent_reference: AgentReference + call_id: str + environment: FunctionShellCallEnvironment + id: str + response_id: str + status: Union[str, LocalShellCallStatus] + type: Literal[OutputItemType.SHELL_CALL] + + @overload + def __init__( + self, + *, + action: FunctionShellAction, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + environment: FunctionShellCallEnvironment, + id: str, + response_id: Optional[str] = ..., + status: Union[str, LocalShellCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemFunctionShellCallOutput(OutputItem, discriminator='shell_call_output'): + agent_reference: AgentReference + call_id: str + id: str + max_output_length: int + output: list[FunctionShellCallOutputContent] + response_id: str + status: Union[str, LocalShellCallOutputStatusEnum] + type: Literal[OutputItemType.SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + max_output_length: int, + output: list[FunctionShellCallOutputContent], + response_id: Optional[str] = ..., + status: Union[str, LocalShellCallOutputStatusEnum] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemFunctionToolCall(OutputItem, discriminator='function_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: Optional[str] + name: str + response_id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[OutputItemType.FUNCTION_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: Optional[str] = ..., + name: str, + response_id: Optional[str] = ..., + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemImageGenToolCall(OutputItem, discriminator='image_generation_call'): + agent_reference: AgentReference + id: str + response_id: str + result: str + status: Literal["in_progress", "completed", "generating", "failed"] + type: Literal[OutputItemType.IMAGE_GENERATION_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + id: str, + response_id: Optional[str] = ..., + result: str, + status: Literal["in_progress", "completed", "generating", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemLocalShellToolCall(OutputItem, discriminator='local_shell_call'): + action: LocalShellExecAction + agent_reference: AgentReference + call_id: str + id: str + response_id: str + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[OutputItemType.LOCAL_SHELL_CALL] + + @overload + def __init__( + self, + *, + action: LocalShellExecAction, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemLocalShellToolCallOutput(OutputItem, discriminator='local_shell_call_output'): + agent_reference: AgentReference + id: str + output: str + response_id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + type: Literal[OutputItemType.LOCAL_SHELL_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + id: str, + output: str, + response_id: Optional[str] = ..., + status: Optional[Literal[in_progress, completed, incomplete]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemMcpApprovalRequest(OutputItem, discriminator='mcp_approval_request'): + agent_reference: AgentReference + arguments: str + id: str + name: str + response_id: str + server_label: str + type: Literal[OutputItemType.MCP_APPROVAL_REQUEST] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + id: str, + name: str, + response_id: Optional[str] = ..., + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemMcpApprovalResponseResource(OutputItem, discriminator='mcp_approval_response'): + agent_reference: AgentReference + approval_request_id: str + approve: bool + id: str + reason: Optional[str] + response_id: str + type: Literal[OutputItemType.MCP_APPROVAL_RESPONSE] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + approval_request_id: str, + approve: bool, + id: str, + reason: Optional[str] = ..., + response_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemMcpListTools(OutputItem, discriminator='mcp_list_tools'): + agent_reference: AgentReference + error: Optional[str] + id: str + response_id: str + server_label: str + tools: list[MCPListToolsTool] + type: Literal[OutputItemType.MCP_LIST_TOOLS] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + error: Optional[str] = ..., + id: str, + response_id: Optional[str] = ..., + server_label: str, + tools: list[MCPListToolsTool] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemMcpToolCall(OutputItem, discriminator='mcp_call'): + agent_reference: AgentReference + approval_request_id: Optional[str] + arguments: str + error: Optional[dict[str, Any]] + id: str + name: str + output: Optional[str] + response_id: str + server_label: str + status: Optional[Union[str, MCPToolCallStatus]] + type: Literal[OutputItemType.MCP_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + approval_request_id: Optional[str] = ..., + arguments: str, + error: Optional[dict[str, Any]] = ..., + id: str, + name: str, + output: Optional[str] = ..., + response_id: Optional[str] = ..., + server_label: str, + status: Optional[Union[str, MCPToolCallStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemMessage(OutputItem, discriminator='message'): + agent_reference: AgentReference + content: list[MessageContent] + id: str + response_id: str + role: Union[str, MessageRole] + status: Union[str, MessageStatus] + type: Literal[OutputItemType.MESSAGE] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + content: list[MessageContent], + id: str, + response_id: Optional[str] = ..., + role: Union[str, MessageRole], + status: Union[str, MessageStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemOutputMessage(OutputItem, discriminator='output_message'): + agent_reference: AgentReference + content: list[OutputMessageContent] + id: str + response_id: str + role: Literal["assistant"] + status: Literal["in_progress", "completed", "incomplete"] + type: Literal[OutputItemType.OUTPUT_MESSAGE] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + content: list[OutputMessageContent], + id: str, + response_id: Optional[str] = ..., + status: Literal["in_progress", "completed", "incomplete"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemReasoningItem(OutputItem, discriminator='reasoning'): + agent_reference: AgentReference + content: Optional[list[ReasoningTextContent]] + encrypted_content: Optional[str] + id: str + response_id: str + status: Optional[Literal["in_progress", "completed", "incomplete"]] + summary: list[SummaryTextContent] + type: Literal[OutputItemType.REASONING] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + content: Optional[list[ReasoningTextContent]] = ..., + encrypted_content: Optional[str] = ..., + id: str, + response_id: Optional[str] = ..., + status: Optional[Literal[in_progress, completed, incomplete]] = ..., + summary: list[SummaryTextContent] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2_A_PREVIEW_CALL = "a2a_preview_call" + A2_A_PREVIEW_CALL_OUTPUT = "a2a_preview_call_output" + APPLY_PATCH_CALL = "apply_patch_call" + APPLY_PATCH_CALL_OUTPUT = "apply_patch_call_output" + AZURE_AI_SEARCH_CALL = "azure_ai_search_call" + AZURE_AI_SEARCH_CALL_OUTPUT = "azure_ai_search_call_output" + AZURE_FUNCTION_CALL = "azure_function_call" + AZURE_FUNCTION_CALL_OUTPUT = "azure_function_call_output" + BING_CUSTOM_SEARCH_PREVIEW_CALL = "bing_custom_search_preview_call" + BING_CUSTOM_SEARCH_PREVIEW_CALL_OUTPUT = "bing_custom_search_preview_call_output" + BING_GROUNDING_CALL = "bing_grounding_call" + BING_GROUNDING_CALL_OUTPUT = "bing_grounding_call_output" + BROWSER_AUTOMATION_PREVIEW_CALL = "browser_automation_preview_call" + BROWSER_AUTOMATION_PREVIEW_CALL_OUTPUT = "browser_automation_preview_call_output" + CODE_INTERPRETER_CALL = "code_interpreter_call" + COMPACTION = "compaction" + COMPUTER_CALL = "computer_call" + COMPUTER_CALL_OUTPUT = "computer_call_output" + CUSTOM_TOOL_CALL = "custom_tool_call" + CUSTOM_TOOL_CALL_OUTPUT = "custom_tool_call_output" + FABRIC_DATAAGENT_PREVIEW_CALL = "fabric_dataagent_preview_call" + FABRIC_DATAAGENT_PREVIEW_CALL_OUTPUT = "fabric_dataagent_preview_call_output" + FILE_SEARCH_CALL = "file_search_call" + FUNCTION_CALL = "function_call" + FUNCTION_CALL_OUTPUT = "function_call_output" + IMAGE_GENERATION_CALL = "image_generation_call" + LOCAL_SHELL_CALL = "local_shell_call" + LOCAL_SHELL_CALL_OUTPUT = "local_shell_call_output" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + MCP_CALL = "mcp_call" + MCP_LIST_TOOLS = "mcp_list_tools" + MEMORY_SEARCH_CALL = "memory_search_call" + MESSAGE = "message" + OAUTH_CONSENT_REQUEST = "oauth_consent_request" + OPENAPI_CALL = "openapi_call" + OPENAPI_CALL_OUTPUT = "openapi_call_output" + OUTPUT_MESSAGE = "output_message" + REASONING = "reasoning" + SHAREPOINT_GROUNDING_PREVIEW_CALL = "sharepoint_grounding_preview_call" + SHAREPOINT_GROUNDING_PREVIEW_CALL_OUTPUT = "sharepoint_grounding_preview_call_output" + SHELL_CALL = "shell_call" + SHELL_CALL_OUTPUT = "shell_call_output" + STRUCTURED_OUTPUTS = "structured_outputs" + WEB_SEARCH_CALL = "web_search_call" + WORKFLOW_ACTION = "workflow_action" + + + class azure.ai.agentserver.responses.models.OutputItemWebSearchToolCall(OutputItem, discriminator='web_search_call'): + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind] + agent_reference: AgentReference + id: str + response_id: str + status: Literal["in_progress", "searching", "completed", "failed"] + type: Literal[OutputItemType.WEB_SEARCH_CALL] + + @overload + def __init__( + self, + *, + action: Union[WebSearchActionSearch, WebSearchActionOpenPage, WebSearchActionFind], + agent_reference: Optional[AgentReference] = ..., + id: str, + response_id: Optional[str] = ..., + status: Literal["in_progress", "searching", "completed", "failed"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputMessageContent(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputMessageContentOutputTextContent(OutputMessageContent, discriminator='output_text'): + annotations: list[Annotation] + logprobs: list[LogProb] + text: str + type: Literal[OutputMessageContentType.OUTPUT_TEXT] + + @overload + def __init__( + self, + *, + annotations: list[Annotation], + logprobs: list[LogProb], + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputMessageContentRefusalContent(OutputMessageContent, discriminator='refusal'): + refusal: str + type: Literal[OutputMessageContentType.REFUSAL] + + @overload + def __init__( + self, + *, + refusal: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.OutputMessageContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + OUTPUT_TEXT = "output_text" + REFUSAL = "refusal" + + + class azure.ai.agentserver.responses.models.PageOrder(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASC = "asc" + DESC = "desc" + + + class azure.ai.agentserver.responses.models.Prompt(_Model): + id: str + variables: Optional[ResponsePromptVariables] + version: Optional[str] + + @overload + def __init__( + self, + *, + id: str, + variables: Optional[ResponsePromptVariables] = ..., + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + DEFAULT2024_11_15 = "default-2024-11-15" + + + class azure.ai.agentserver.responses.models.RankingOptions(_Model): + hybrid_search: Optional[HybridSearchOptions] + ranker: Optional[Union[str, RankerVersionType]] + score_threshold: Optional[int] + + @overload + def __init__( + self, + *, + hybrid_search: Optional[HybridSearchOptions] = ..., + ranker: Optional[Union[str, RankerVersionType]] = ..., + score_threshold: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.Reasoning(_Model): + effort: Optional[Literal["none", "minimal", "low", "medium", "high", "xhigh"]] + generate_summary: Optional[Literal["auto", "concise", "detailed"]] + summary: Optional[Literal["auto", "concise", "detailed"]] + + @overload + def __init__( + self, + *, + effort: Optional[Literal[none, minimal, low, medium, high, xhigh]] = ..., + generate_summary: Optional[Literal[auto, concise, detailed]] = ..., + summary: Optional[Literal[auto, concise, detailed]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ReasoningTextContent(_Model): + text: str + type: Literal["reasoning_text"] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseAudioDeltaEvent(ResponseStreamEvent, discriminator='response.audio.delta'): + delta: bytes + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_AUDIO_DELTA] + + @overload + def __init__( + self, + *, + delta: bytes, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseAudioDoneEvent(ResponseStreamEvent, discriminator='response.audio.done'): + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_AUDIO_DONE] + + @overload + def __init__( + self, + *, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseAudioTranscriptDeltaEvent(ResponseStreamEvent, discriminator='response.audio.transcript.delta'): + delta: str + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_AUDIO_TRANSCRIPT_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseAudioTranscriptDoneEvent(ResponseStreamEvent, discriminator='response.audio.transcript.done'): + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_AUDIO_TRANSCRIPT_DONE] + + @overload + def __init__( + self, + *, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCodeInterpreterCallCodeDeltaEvent(ResponseStreamEvent, discriminator='response.code_interpreter_call_code.delta'): + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CODE_INTERPRETER_CALL_CODE_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCodeInterpreterCallCodeDoneEvent(ResponseStreamEvent, discriminator='response.code_interpreter_call_code.done'): + code: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CODE_INTERPRETER_CALL_CODE_DONE] + + @overload + def __init__( + self, + *, + code: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCodeInterpreterCallCompletedEvent(ResponseStreamEvent, discriminator='response.code_interpreter_call.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CODE_INTERPRETER_CALL_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCodeInterpreterCallInProgressEvent(ResponseStreamEvent, discriminator='response.code_interpreter_call.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CODE_INTERPRETER_CALL_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCodeInterpreterCallInterpretingEvent(ResponseStreamEvent, discriminator='response.code_interpreter_call.interpreting'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CODE_INTERPRETER_CALL_INTERPRETING] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCompletedEvent(ResponseStreamEvent, discriminator='response.completed'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_COMPLETED] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseContentPartAddedEvent(ResponseStreamEvent, discriminator='response.content_part.added'): + content_index: int + item_id: str + output_index: int + part: OutputContent + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CONTENT_PART_ADDED] + + @overload + def __init__( + self, + *, + content_index: int, + item_id: str, + output_index: int, + part: OutputContent, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseContentPartDoneEvent(ResponseStreamEvent, discriminator='response.content_part.done'): + content_index: int + item_id: str + output_index: int + part: OutputContent + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CONTENT_PART_DONE] + + @overload + def __init__( + self, + *, + content_index: int, + item_id: str, + output_index: int, + part: OutputContent, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCreatedEvent(ResponseStreamEvent, discriminator='response.created'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CREATED] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCustomToolCallInputDeltaEvent(ResponseStreamEvent, discriminator='response.custom_tool_call_input.delta'): + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CUSTOM_TOOL_CALL_INPUT_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseCustomToolCallInputDoneEvent(ResponseStreamEvent, discriminator='response.custom_tool_call_input.done'): + input: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_CUSTOM_TOOL_CALL_INPUT_DONE] + + @overload + def __init__( + self, + *, + input: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseErrorCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EMPTY_IMAGE_FILE = "empty_image_file" + FAILED_TO_DOWNLOAD_IMAGE = "failed_to_download_image" + IMAGE_CONTENT_POLICY_VIOLATION = "image_content_policy_violation" + IMAGE_FILE_NOT_FOUND = "image_file_not_found" + IMAGE_FILE_TOO_LARGE = "image_file_too_large" + IMAGE_PARSE_ERROR = "image_parse_error" + IMAGE_TOO_LARGE = "image_too_large" + IMAGE_TOO_SMALL = "image_too_small" + INVALID_BASE64_IMAGE = "invalid_base64_image" + INVALID_IMAGE = "invalid_image" + INVALID_IMAGE_FORMAT = "invalid_image_format" + INVALID_IMAGE_MODE = "invalid_image_mode" + INVALID_IMAGE_URL = "invalid_image_url" + INVALID_PROMPT = "invalid_prompt" + RATE_LIMIT_EXCEEDED = "rate_limit_exceeded" + SERVER_ERROR = "server_error" + UNSUPPORTED_IMAGE_MEDIA_TYPE = "unsupported_image_media_type" + VECTOR_STORE_TIMEOUT = "vector_store_timeout" + + + class azure.ai.agentserver.responses.models.ResponseErrorEvent(ResponseStreamEvent, discriminator='error'): + code: str + message: str + param: str + sequence_number: int + type: Literal[ResponseStreamEventType.ERROR] + + @overload + def __init__( + self, + *, + code: str, + message: str, + param: str, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseErrorInfo(_Model): + code: Union[str, ResponseErrorCode] + message: str + + @overload + def __init__( + self, + *, + code: Union[str, ResponseErrorCode], + message: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFailedEvent(ResponseStreamEvent, discriminator='response.failed'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FAILED] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFileSearchCallCompletedEvent(ResponseStreamEvent, discriminator='response.file_search_call.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FILE_SEARCH_CALL_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFileSearchCallInProgressEvent(ResponseStreamEvent, discriminator='response.file_search_call.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FILE_SEARCH_CALL_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFileSearchCallSearchingEvent(ResponseStreamEvent, discriminator='response.file_search_call.searching'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FILE_SEARCH_CALL_SEARCHING] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFormatJsonSchemaSchema(_Model): + + + class azure.ai.agentserver.responses.models.ResponseFunctionCallArgumentsDeltaEvent(ResponseStreamEvent, discriminator='response.function_call_arguments.delta'): + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseFunctionCallArgumentsDoneEvent(ResponseStreamEvent, discriminator='response.function_call_arguments.done'): + arguments: str + item_id: str + name: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE] + + @overload + def __init__( + self, + *, + arguments: str, + item_id: str, + name: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseImageGenCallCompletedEvent(ResponseStreamEvent, discriminator='response.image_generation_call.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_IMAGE_GENERATION_CALL_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseImageGenCallGeneratingEvent(ResponseStreamEvent, discriminator='response.image_generation_call.generating'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_IMAGE_GENERATION_CALL_GENERATING] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseImageGenCallInProgressEvent(ResponseStreamEvent, discriminator='response.image_generation_call.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_IMAGE_GENERATION_CALL_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseImageGenCallPartialImageEvent(ResponseStreamEvent, discriminator='response.image_generation_call.partial_image'): + item_id: str + output_index: int + partial_image_b64: str + partial_image_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_IMAGE_GENERATION_CALL_PARTIAL_IMAGE] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + partial_image_b64: str, + partial_image_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseInProgressEvent(ResponseStreamEvent, discriminator='response.in_progress'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_IN_PROGRESS] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseIncompleteDetails(_Model): + reason: Optional[Literal["max_output_tokens", "content_filter"]] + + @overload + def __init__( + self, + *, + reason: Optional[Literal[max_output_tokens, content_filter]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseIncompleteEvent(ResponseStreamEvent, discriminator='response.incomplete'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_INCOMPLETE] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseIncompleteReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTENT_FILTER = "content_filter" + MAX_OUTPUT_TOKENS = "max_output_tokens" + + + class azure.ai.agentserver.responses.models.ResponseLogProb(_Model): + logprob: int + token: str + top_logprobs: Optional[list[ResponseLogProbTopLogprobs]] + + @overload + def __init__( + self, + *, + logprob: int, + token: str, + top_logprobs: Optional[list[ResponseLogProbTopLogprobs]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseLogProbTopLogprobs(_Model): + logprob: Optional[int] + token: Optional[str] + + @overload + def __init__( + self, + *, + logprob: Optional[int] = ..., + token: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPCallArgumentsDeltaEvent(ResponseStreamEvent, discriminator='response.mcp_call_arguments.delta'): + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPCallArgumentsDoneEvent(ResponseStreamEvent, discriminator='response.mcp_call_arguments.done'): + arguments: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE] + + @overload + def __init__( + self, + *, + arguments: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPCallCompletedEvent(ResponseStreamEvent, discriminator='response.mcp_call.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_CALL_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPCallFailedEvent(ResponseStreamEvent, discriminator='response.mcp_call.failed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_CALL_FAILED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPCallInProgressEvent(ResponseStreamEvent, discriminator='response.mcp_call.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_CALL_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPListToolsCompletedEvent(ResponseStreamEvent, discriminator='response.mcp_list_tools.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_LIST_TOOLS_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPListToolsFailedEvent(ResponseStreamEvent, discriminator='response.mcp_list_tools.failed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_LIST_TOOLS_FAILED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseMCPListToolsInProgressEvent(ResponseStreamEvent, discriminator='response.mcp_list_tools.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_MCP_LIST_TOOLS_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseObject(ResponseObjectGenerated): + output: list[OutputItem] + prompt_cache_key: Optional[str] + safety_identifier: Optional[str] + temperature: Optional[float] + top_p: Optional[float] + user: Optional[str] + + @overload + def __init__( + self, + *, + agent_reference: AgentReference, + background: Optional[bool] = ..., + completed_at: Optional[datetime] = ..., + conversation: Optional[ConversationReference] = ..., + created_at: datetime, + error: ResponseErrorInfo, + id: str, + incomplete_details: ResponseIncompleteDetails, + instructions: Union[str, list[Item]], + max_output_tokens: Optional[int] = ..., + max_tool_calls: Optional[int] = ..., + metadata: Optional[Metadata] = ..., + model: Optional[str] = ..., + output: list[OutputItem], + output_text: Optional[str] = ..., + parallel_tool_calls: bool, + previous_response_id: Optional[str] = ..., + prompt: Optional[Prompt] = ..., + prompt_cache_key: Optional[str] = ..., + prompt_cache_retention: Optional[Literal[in-memory, 24h]] = ..., + reasoning: Optional[Reasoning] = ..., + safety_identifier: Optional[str] = ..., + service_tier: Optional[Literal[auto, default, flex, scale, priority]] = ..., + status: Optional[Literal[completed, failed, in_progress, cancelled, queued, incomplete]] = ..., + temperature: Optional[int] = ..., + text: Optional[ResponseTextParam] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_logprobs: Optional[int] = ..., + top_p: Optional[int] = ..., + truncation: Optional[Literal[auto, disabled]] = ..., + usage: Optional[ResponseUsage] = ..., + user: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseOutputItemAddedEvent(ResponseStreamEvent, discriminator='response.output_item.added'): + item: OutputItem + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_OUTPUT_ITEM_ADDED] + + @overload + def __init__( + self, + *, + item: OutputItem, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseOutputItemDoneEvent(ResponseStreamEvent, discriminator='response.output_item.done'): + item: OutputItem + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_OUTPUT_ITEM_DONE] + + @overload + def __init__( + self, + *, + item: OutputItem, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseOutputTextAnnotationAddedEvent(ResponseStreamEvent, discriminator='response.output_text.annotation.added'): + annotation: Annotation + annotation_index: int + content_index: int + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_OUTPUT_TEXT_ANNOTATION_ADDED] + + @overload + def __init__( + self, + *, + annotation: Annotation, + annotation_index: int, + content_index: int, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponsePromptVariables(_Model): + + + class azure.ai.agentserver.responses.models.ResponseQueuedEvent(ResponseStreamEvent, discriminator='response.queued'): + response: ResponseObject + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_QUEUED] + + @overload + def __init__( + self, + *, + response: ResponseObject, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryPartAddedEvent(ResponseStreamEvent, discriminator='response.reasoning_summary_part.added'): + item_id: str + output_index: int + part: ResponseReasoningSummaryPartAddedEventPart + sequence_number: int + summary_index: int + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_SUMMARY_PART_ADDED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + part: ResponseReasoningSummaryPartAddedEventPart, + sequence_number: int, + summary_index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryPartAddedEventPart(_Model): + text: str + type: Literal["summary_text"] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryPartDoneEvent(ResponseStreamEvent, discriminator='response.reasoning_summary_part.done'): + item_id: str + output_index: int + part: ResponseReasoningSummaryPartDoneEventPart + sequence_number: int + summary_index: int + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_SUMMARY_PART_DONE] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + part: ResponseReasoningSummaryPartDoneEventPart, + sequence_number: int, + summary_index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryPartDoneEventPart(_Model): + text: str + type: Literal["summary_text"] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryTextDeltaEvent(ResponseStreamEvent, discriminator='response.reasoning_summary_text.delta'): + delta: str + item_id: str + output_index: int + sequence_number: int + summary_index: int + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_SUMMARY_TEXT_DELTA] + + @overload + def __init__( + self, + *, + delta: str, + item_id: str, + output_index: int, + sequence_number: int, + summary_index: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningSummaryTextDoneEvent(ResponseStreamEvent, discriminator='response.reasoning_summary_text.done'): + item_id: str + output_index: int + sequence_number: int + summary_index: int + text: str + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_SUMMARY_TEXT_DONE] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int, + summary_index: int, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningTextDeltaEvent(ResponseStreamEvent, discriminator='response.reasoning_text.delta'): + content_index: int + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_TEXT_DELTA] + + @overload + def __init__( + self, + *, + content_index: int, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseReasoningTextDoneEvent(ResponseStreamEvent, discriminator='response.reasoning_text.done'): + content_index: int + item_id: str + output_index: int + sequence_number: int + text: str + type: Literal[ResponseStreamEventType.RESPONSE_REASONING_TEXT_DONE] + + @overload + def __init__( + self, + *, + content_index: int, + item_id: str, + output_index: int, + sequence_number: int, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseRefusalDeltaEvent(ResponseStreamEvent, discriminator='response.refusal.delta'): + content_index: int + delta: str + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_REFUSAL_DELTA] + + @overload + def __init__( + self, + *, + content_index: int, + delta: str, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseRefusalDoneEvent(ResponseStreamEvent, discriminator='response.refusal.done'): + content_index: int + item_id: str + output_index: int + refusal: str + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_REFUSAL_DONE] + + @overload + def __init__( + self, + *, + content_index: int, + item_id: str, + output_index: int, + refusal: str, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseStreamEvent(_Model): + sequence_number: int + type: str + + @overload + def __init__( + self, + *, + sequence_number: int, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseStreamEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ERROR = "error" + RESPONSE_AUDIO_DELTA = "response.audio.delta" + RESPONSE_AUDIO_DONE = "response.audio.done" + RESPONSE_AUDIO_TRANSCRIPT_DELTA = "response.audio.transcript.delta" + RESPONSE_AUDIO_TRANSCRIPT_DONE = "response.audio.transcript.done" + RESPONSE_CODE_INTERPRETER_CALL_CODE_DELTA = "response.code_interpreter_call_code.delta" + RESPONSE_CODE_INTERPRETER_CALL_CODE_DONE = "response.code_interpreter_call_code.done" + RESPONSE_CODE_INTERPRETER_CALL_COMPLETED = "response.code_interpreter_call.completed" + RESPONSE_CODE_INTERPRETER_CALL_INTERPRETING = "response.code_interpreter_call.interpreting" + RESPONSE_CODE_INTERPRETER_CALL_IN_PROGRESS = "response.code_interpreter_call.in_progress" + RESPONSE_COMPLETED = "response.completed" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + RESPONSE_CREATED = "response.created" + RESPONSE_CUSTOM_TOOL_CALL_INPUT_DELTA = "response.custom_tool_call_input.delta" + RESPONSE_CUSTOM_TOOL_CALL_INPUT_DONE = "response.custom_tool_call_input.done" + RESPONSE_FAILED = "response.failed" + RESPONSE_FILE_SEARCH_CALL_COMPLETED = "response.file_search_call.completed" + RESPONSE_FILE_SEARCH_CALL_IN_PROGRESS = "response.file_search_call.in_progress" + RESPONSE_FILE_SEARCH_CALL_SEARCHING = "response.file_search_call.searching" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + RESPONSE_IMAGE_GENERATION_CALL_COMPLETED = "response.image_generation_call.completed" + RESPONSE_IMAGE_GENERATION_CALL_GENERATING = "response.image_generation_call.generating" + RESPONSE_IMAGE_GENERATION_CALL_IN_PROGRESS = "response.image_generation_call.in_progress" + RESPONSE_IMAGE_GENERATION_CALL_PARTIAL_IMAGE = "response.image_generation_call.partial_image" + RESPONSE_INCOMPLETE = "response.incomplete" + RESPONSE_IN_PROGRESS = "response.in_progress" + RESPONSE_MCP_CALL_ARGUMENTS_DELTA = "response.mcp_call_arguments.delta" + RESPONSE_MCP_CALL_ARGUMENTS_DONE = "response.mcp_call_arguments.done" + RESPONSE_MCP_CALL_COMPLETED = "response.mcp_call.completed" + RESPONSE_MCP_CALL_FAILED = "response.mcp_call.failed" + RESPONSE_MCP_CALL_IN_PROGRESS = "response.mcp_call.in_progress" + RESPONSE_MCP_LIST_TOOLS_COMPLETED = "response.mcp_list_tools.completed" + RESPONSE_MCP_LIST_TOOLS_FAILED = "response.mcp_list_tools.failed" + RESPONSE_MCP_LIST_TOOLS_IN_PROGRESS = "response.mcp_list_tools.in_progress" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + RESPONSE_OUTPUT_TEXT_ANNOTATION_ADDED = "response.output_text.annotation.added" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + RESPONSE_QUEUED = "response.queued" + RESPONSE_REASONING_SUMMARY_PART_ADDED = "response.reasoning_summary_part.added" + RESPONSE_REASONING_SUMMARY_PART_DONE = "response.reasoning_summary_part.done" + RESPONSE_REASONING_SUMMARY_TEXT_DELTA = "response.reasoning_summary_text.delta" + RESPONSE_REASONING_SUMMARY_TEXT_DONE = "response.reasoning_summary_text.done" + RESPONSE_REASONING_TEXT_DELTA = "response.reasoning_text.delta" + RESPONSE_REASONING_TEXT_DONE = "response.reasoning_text.done" + RESPONSE_REFUSAL_DELTA = "response.refusal.delta" + RESPONSE_REFUSAL_DONE = "response.refusal.done" + RESPONSE_WEB_SEARCH_CALL_COMPLETED = "response.web_search_call.completed" + RESPONSE_WEB_SEARCH_CALL_IN_PROGRESS = "response.web_search_call.in_progress" + RESPONSE_WEB_SEARCH_CALL_SEARCHING = "response.web_search_call.searching" + + + class azure.ai.agentserver.responses.models.ResponseStreamOptions(_Model): + include_obfuscation: Optional[bool] + + @overload + def __init__( + self, + *, + include_obfuscation: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseTextDeltaEvent(ResponseStreamEvent, discriminator='response.output_text.delta'): + content_index: int + delta: str + item_id: str + logprobs: list[ResponseLogProb] + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_OUTPUT_TEXT_DELTA] + + @overload + def __init__( + self, + *, + content_index: int, + delta: str, + item_id: str, + logprobs: list[ResponseLogProb], + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseTextDoneEvent(ResponseStreamEvent, discriminator='response.output_text.done'): + content_index: int + item_id: str + logprobs: list[ResponseLogProb] + output_index: int + sequence_number: int + text: str + type: Literal[ResponseStreamEventType.RESPONSE_OUTPUT_TEXT_DONE] + + @overload + def __init__( + self, + *, + content_index: int, + item_id: str, + logprobs: list[ResponseLogProb], + output_index: int, + sequence_number: int, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseTextParam(_Model): + format: Optional[TextResponseFormatConfiguration] + verbosity: Optional[Literal["low", "medium", "high"]] + + @overload + def __init__( + self, + *, + format: Optional[TextResponseFormatConfiguration] = ..., + verbosity: Optional[Literal[low, medium, high]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseUsage(_Model): + input_tokens: int + input_tokens_details: ResponseUsageInputTokensDetails + output_tokens: int + output_tokens_details: ResponseUsageOutputTokensDetails + total_tokens: int + + @overload + def __init__( + self, + *, + input_tokens: int, + input_tokens_details: ResponseUsageInputTokensDetails, + output_tokens: int, + output_tokens_details: ResponseUsageOutputTokensDetails, + total_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseUsageInputTokensDetails(_Model): + cached_tokens: int + + @overload + def __init__( + self, + *, + cached_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseUsageOutputTokensDetails(_Model): + reasoning_tokens: int + + @overload + def __init__( + self, + *, + reasoning_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseWebSearchCallCompletedEvent(ResponseStreamEvent, discriminator='response.web_search_call.completed'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_WEB_SEARCH_CALL_COMPLETED] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseWebSearchCallInProgressEvent(ResponseStreamEvent, discriminator='response.web_search_call.in_progress'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_WEB_SEARCH_CALL_IN_PROGRESS] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ResponseWebSearchCallSearchingEvent(ResponseStreamEvent, discriminator='response.web_search_call.searching'): + item_id: str + output_index: int + sequence_number: int + type: Literal[ResponseStreamEventType.RESPONSE_WEB_SEARCH_CALL_SEARCHING] + + @overload + def __init__( + self, + *, + item_id: str, + output_index: int, + sequence_number: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ScreenshotParam(ComputerAction, discriminator='screenshot'): + type: Literal[ComputerActionType.SCREENSHOT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ScrollParam(ComputerAction, discriminator='scroll'): + scroll_x: int + scroll_y: int + type: Literal[ComputerActionType.SCROLL] + x: int + y: int + + @overload + def __init__( + self, + *, + scroll_x: int, + scroll_y: int, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SearchContextSize(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + + + class azure.ai.agentserver.responses.models.SharepointGroundingToolCall(OutputItem, discriminator='sharepoint_grounding_preview_call'): + agent_reference: AgentReference + arguments: str + call_id: str + id: str + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.SHAREPOINT_GROUNDING_PREVIEW_CALL] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + arguments: str, + call_id: str, + id: str, + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SharepointGroundingToolCallOutput(OutputItem, discriminator='sharepoint_grounding_preview_call_output'): + agent_reference: AgentReference + call_id: str + id: str + output: Optional[ToolCallOutputContent] + response_id: str + status: Union[str, ToolCallStatus] + type: Literal[OutputItemType.SHAREPOINT_GROUNDING_PREVIEW_CALL_OUTPUT] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + call_id: str, + id: str, + output: Optional[ToolCallOutputContent] = ..., + response_id: Optional[str] = ..., + status: Union[str, ToolCallStatus] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SharepointGroundingToolParameters(_Model): + description: Optional[str] + name: Optional[str] + project_connections: Optional[list[ToolProjectConnection]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connections: Optional[list[ToolProjectConnection]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SharepointPreviewTool(Tool, discriminator='sharepoint_grounding_preview'): + description: Optional[str] + name: Optional[str] + sharepoint_grounding_preview: SharepointGroundingToolParameters + type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + sharepoint_grounding_preview: SharepointGroundingToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SkillReferenceParam(ContainerSkill, discriminator='skill_reference'): + skill_id: str + type: Literal[ContainerSkillType.SKILL_REFERENCE] + version: Optional[str] + + @overload + def __init__( + self, + *, + skill_id: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SpecificApplyPatchParam(ToolChoiceParam, discriminator='apply_patch'): + type: Literal[ToolChoiceParamType.APPLY_PATCH] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SpecificFunctionShellParam(ToolChoiceParam, discriminator='shell'): + type: Literal[ToolChoiceParamType.SHELL] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.StructuredOutputDefinition(_Model): + description: str + name: str + schema: dict[str, Any] + strict: bool + + @overload + def __init__( + self, + *, + description: str, + name: str, + schema: dict[str, Any], + strict: bool + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.StructuredOutputsOutputItem(OutputItem, discriminator='structured_outputs'): + agent_reference: AgentReference + id: str + output: Any + response_id: str + type: Literal[OutputItemType.STRUCTURED_OUTPUTS] + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + id: str, + output: Any, + response_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.SummaryTextContent(MessageContent, discriminator='summary_text'): + text: str + type: Literal[MessageContentType.SUMMARY_TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TextContent(MessageContent, discriminator='text'): + text: str + type: Literal[MessageContentType.TEXT] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TextResponseFormatConfiguration(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TextResponseFormatConfigurationResponseFormatJsonObject(TextResponseFormatConfiguration, discriminator='json_object'): + type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TextResponseFormatConfigurationResponseFormatText(TextResponseFormatConfiguration, discriminator='text'): + type: Literal[TextResponseFormatConfigurationType.TEXT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + JSON_OBJECT = "json_object" + JSON_SCHEMA = "json_schema" + TEXT = "text" + + + class azure.ai.agentserver.responses.models.TextResponseFormatJsonSchema(TextResponseFormatConfiguration, discriminator='json_schema'): + description: Optional[str] + name: str + schema: ResponseFormatJsonSchemaSchema + strict: Optional[bool] + type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + schema: ResponseFormatJsonSchemaSchema, + strict: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.Tool(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + INCOMPLETE = "incomplete" + IN_PROGRESS = "in_progress" + + + class azure.ai.agentserver.responses.models.ToolChoiceAllowed(ToolChoiceAllowedGenerated): + tools: list[dict[str, Any]] + + @overload + def __init__( + self, + *, + mode: Literal["auto", "required"], + tools: list[dict[str, Any]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator='code_interpreter'): + type: Literal[ToolChoiceParamType.CODE_INTERPRETER] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator='computer_use_preview'): + type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceCustom(ToolChoiceParam, discriminator='custom'): + name: str + type: Literal[ToolChoiceParamType.CUSTOM] + + @overload + def __init__( + self, + *, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceFileSearch(ToolChoiceParam, discriminator='file_search'): + type: Literal[ToolChoiceParamType.FILE_SEARCH] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceFunction(ToolChoiceParam, discriminator='function'): + name: str + type: Literal[ToolChoiceParamType.FUNCTION] + + @overload + def __init__( + self, + *, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceImageGeneration(ToolChoiceParam, discriminator='image_generation'): + type: Literal[ToolChoiceParamType.IMAGE_GENERATION] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceMCP(ToolChoiceParam, discriminator='mcp'): + name: Optional[str] + server_label: str + type: Literal[ToolChoiceParamType.MCP] + + @overload + def __init__( + self, + *, + name: Optional[str] = ..., + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceOptions(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + NONE = "none" + REQUIRED = "required" + + + class azure.ai.agentserver.responses.models.ToolChoiceParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWED_TOOLS = "allowed_tools" + APPLY_PATCH = "apply_patch" + CODE_INTERPRETER = "code_interpreter" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FILE_SEARCH = "file_search" + FUNCTION = "function" + IMAGE_GENERATION = "image_generation" + MCP = "mcp" + SHELL = "shell" + WEB_SEARCH_PREVIEW = "web_search_preview" + WEB_SEARCH_PREVIEW2025_03_11 = "web_search_preview_2025_03_11" + + + class azure.ai.agentserver.responses.models.ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator='web_search_preview'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator='web_search_preview_2025_03_11'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW2025_03_11] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolProjectConnection(_Model): + description: Optional[str] + name: Optional[str] + project_connection_id: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2_A_PREVIEW = "a2a_preview" + APPLY_PATCH = "apply_patch" + AZURE_AI_SEARCH = "azure_ai_search" + AZURE_FUNCTION = "azure_function" + BING_CUSTOM_SEARCH_PREVIEW = "bing_custom_search_preview" + BING_GROUNDING = "bing_grounding" + BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" + CAPTURE_STRUCTURED_OUTPUTS = "capture_structured_outputs" + CODE_INTERPRETER = "code_interpreter" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FABRIC_DATAAGENT_PREVIEW = "fabric_dataagent_preview" + FILE_SEARCH = "file_search" + FUNCTION = "function" + IMAGE_GENERATION = "image_generation" + LOCAL_SHELL = "local_shell" + MCP = "mcp" + MEMORY_SEARCH_PREVIEW = "memory_search_preview" + OPENAPI = "openapi" + SHAREPOINT_GROUNDING_PREVIEW = "sharepoint_grounding_preview" + SHELL = "shell" + WEB_SEARCH = "web_search" + WEB_SEARCH_PREVIEW = "web_search_preview" + WORK_IQ_PREVIEW = "work_iq_preview" + + + class azure.ai.agentserver.responses.models.TopLogProb(_Model): + bytes: list[int] + logprob: int + token: str + + @overload + def __init__( + self, + *, + bytes: list[int], + logprob: int, + token: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.TypeParam(ComputerAction, discriminator='type'): + text: str + type: Literal[ComputerActionType.TYPE] + + @overload + def __init__( + self, + *, + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.UrlCitationBody(Annotation, discriminator='url_citation'): + end_index: int + start_index: int + title: str + type: Literal[AnnotationType.URL_CITATION] + url: str + + @overload + def __init__( + self, + *, + end_index: int, + start_index: int, + title: str, + url: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.UserProfileMemoryItem(MemoryItem, discriminator='user_profile'): + content: str + kind: Literal[MemoryItemKind.USER_PROFILE] + memory_id: str + scope: str + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + memory_id: str, + scope: str, + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.VectorStoreFileAttributes(_Model): + + + class azure.ai.agentserver.responses.models.WaitParam(ComputerAction, discriminator='wait'): + type: Literal[ComputerActionType.WAIT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchActionFind(_Model): + pattern: str + type: Literal["find_in_page"] + url: str + + @overload + def __init__( + self, + *, + pattern: str, + url: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchActionOpenPage(_Model): + type: Literal["open_page"] + url: Optional[str] + + @overload + def __init__( + self, + *, + url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchActionSearch(_Model): + queries: Optional[list[str]] + query: str + sources: Optional[list[WebSearchActionSearchSources]] + type: Literal["search"] + + @overload + def __init__( + self, + *, + queries: Optional[list[str]] = ..., + query: str, + sources: Optional[list[WebSearchActionSearchSources]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchActionSearchSources(_Model): + type: Literal["url"] + url: str + + @overload + def __init__( + self, + *, + url: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchApproximateLocation(_Model): + city: Optional[str] + country: Optional[str] + region: Optional[str] + timezone: Optional[str] + type: Literal["approximate"] + + @overload + def __init__( + self, + *, + city: Optional[str] = ..., + country: Optional[str] = ..., + region: Optional[str] = ..., + timezone: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchConfiguration(_Model): + description: Optional[str] + instance_name: str + name: Optional[str] + project_connection_id: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + instance_name: str, + name: Optional[str] = ..., + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchPreviewTool(Tool, discriminator='web_search_preview'): + search_context_size: Optional[Union[str, SearchContextSize]] + type: Literal[ToolType.WEB_SEARCH_PREVIEW] + user_location: Optional[ApproximateLocation] + + @overload + def __init__( + self, + *, + search_context_size: Optional[Union[str, SearchContextSize]] = ..., + user_location: Optional[ApproximateLocation] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchTool(Tool, discriminator='web_search'): + custom_search_configuration: Optional[WebSearchConfiguration] + description: Optional[str] + filters: Optional[WebSearchToolFilters] + name: Optional[str] + search_context_size: Optional[Literal["low", "medium", "high"]] + type: Literal[ToolType.WEB_SEARCH] + user_location: Optional[WebSearchApproximateLocation] + + @overload + def __init__( + self, + *, + custom_search_configuration: Optional[WebSearchConfiguration] = ..., + description: Optional[str] = ..., + filters: Optional[WebSearchToolFilters] = ..., + name: Optional[str] = ..., + search_context_size: Optional[Literal[low, medium, high]] = ..., + user_location: Optional[WebSearchApproximateLocation] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WebSearchToolFilters(_Model): + allowed_domains: Optional[list[str]] + + @overload + def __init__( + self, + *, + allowed_domains: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WorkIQPreviewTool(Tool, discriminator='work_iq_preview'): + type: Literal[ToolType.WORK_IQ_PREVIEW] + work_iq_preview: WorkIQPreviewToolParameters + + @overload + def __init__( + self, + *, + work_iq_preview: WorkIQPreviewToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WorkIQPreviewToolParameters(_Model): + project_connection_id: str + + @overload + def __init__( + self, + *, + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.WorkflowActionOutputItem(OutputItem, discriminator='workflow_action'): + action_id: str + agent_reference: AgentReference + id: str + kind: str + parent_action_id: Optional[str] + previous_action_id: Optional[str] + response_id: str + status: Literal["completed", "failed", "in_progress", "cancelled"] + type: Literal[OutputItemType.WORKFLOW_ACTION] + + @overload + def __init__( + self, + *, + action_id: str, + agent_reference: Optional[AgentReference] = ..., + id: str, + kind: str, + parent_action_id: Optional[str] = ..., + previous_action_id: Optional[str] = ..., + response_id: Optional[str] = ..., + status: Literal["completed", "failed", "in_progress", "cancelled"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + +namespace azure.ai.agentserver.responses.models.errors + + class azure.ai.agentserver.responses.models.errors.ApiErrorResponse(_Model): + error: Error + + @overload + def __init__( + self, + *, + error: Error + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.errors.Error(_Model): + additional_info: Optional[dict[str, Any]] + code: str + debug_info: Optional[dict[str, Any]] + details: Optional[list[Error]] + message: str + param: Optional[str] + type: Optional[str] + + @overload + def __init__( + self, + *, + additional_info: Optional[dict[str, Any]] = ..., + code: str, + debug_info: Optional[dict[str, Any]] = ..., + details: Optional[list[Error]] = ..., + message: str, + param: Optional[str] = ..., + type: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.errors.RequestValidationError(ValueError): + + def __init__( + self, + message: str, + *, + code: str = "invalid_request_error", + debug_info: dict[str, Any] | None = ..., + details: list[dict[str, str]] | None = ..., + error_type: str = "invalid_request_error", + param: str | None = ... + ) -> None: ... + + def to_api_error_response(self) -> ApiErrorResponse: ... + + def to_error(self) -> Error: ... + + +namespace azure.ai.agentserver.responses.models.runtime + + def azure.ai.agentserver.responses.models.runtime.build_cancelled_response( + response_id: str, + agent_reference: AgentReference | dict[str, Any], + model: str | None, + created_at: datetime | None = None + ) -> ResponseObject: ... + + + def azure.ai.agentserver.responses.models.runtime.build_failed_response( + response_id: str, + agent_reference: AgentReference | dict[str, Any], + model: str | None, + created_at: datetime | None = None, + error_message: str = "An internal server error occurred.", + error_code: str = "server_error" + ) -> ResponseObject: ... + + + class azure.ai.agentserver.responses.models.runtime.AgentReference(_Model): + name: str + type: Literal["agent_reference"] + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.OutputItem(_Model): + agent_reference: Optional[AgentReference] + response_id: Optional[str] + type: str + + @overload + def __init__( + self, + *, + agent_reference: Optional[AgentReference] = ..., + response_id: Optional[str] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.ResponseExecution: + property agent_reference: AgentReference | dict[str, Any] # Read-only + property is_terminal: bool # Read-only + property model: str | None # Read-only + property replay_enabled: bool # Read-only + property visible_via_get: bool # Read-only + + def __init__( + self, + *, + agent_session_id: str | None = ..., + cancel_requested: bool = False, + cancel_signal: Event | None = ..., + client_disconnected: bool = False, + completed_at: datetime | None = ..., + conversation_id: str | None = ..., + created_at: datetime | None = ..., + execution_task: Task[Any] | None = ..., + initial_agent_reference: AgentReference | dict[str, Any] | None = ..., + initial_model: str | None = ..., + input_items: list[OutputItem] | None = ..., + mode_flags: ResponseModeFlags, + previous_response_id: str | None = ..., + response: ResponseObject | None = ..., + response_context: ResponseContext | None = ..., + response_created_seen: bool = False, + response_id: str, + status: ResponseStatus = "in_progress", + subject: _ResponseEventSubject | None = ..., + updated_at: datetime | None = ..., + user_id_key: str | None = ... + ) -> None: ... + + def apply_event( + self, + normalized: ResponseStreamEvent, + all_events: list[ResponseStreamEvent] + ) -> None: ... + + def set_response_snapshot(self, response: ResponseObject) -> None: ... + + def transition_to(self, next_status: ResponseStatus) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.ResponseModeFlags: + + def __init__( + self, + *, + background: bool, + store: bool, + stream: bool + ) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.ResponseObject(ResponseObjectGenerated): + output: list[OutputItem] + prompt_cache_key: Optional[str] + safety_identifier: Optional[str] + temperature: Optional[float] + top_p: Optional[float] + user: Optional[str] + + @overload + def __init__( + self, + *, + agent_reference: AgentReference, + background: Optional[bool] = ..., + completed_at: Optional[datetime] = ..., + conversation: Optional[ConversationReference] = ..., + created_at: datetime, + error: ResponseErrorInfo, + id: str, + incomplete_details: ResponseIncompleteDetails, + instructions: Union[str, list[Item]], + max_output_tokens: Optional[int] = ..., + max_tool_calls: Optional[int] = ..., + metadata: Optional[Metadata] = ..., + model: Optional[str] = ..., + output: list[OutputItem], + output_text: Optional[str] = ..., + parallel_tool_calls: bool, + previous_response_id: Optional[str] = ..., + prompt: Optional[Prompt] = ..., + prompt_cache_key: Optional[str] = ..., + prompt_cache_retention: Optional[Literal[in-memory, 24h]] = ..., + reasoning: Optional[Reasoning] = ..., + safety_identifier: Optional[str] = ..., + service_tier: Optional[Literal[auto, default, flex, scale, priority]] = ..., + status: Optional[Literal[completed, failed, in_progress, cancelled, queued, incomplete]] = ..., + temperature: Optional[int] = ..., + text: Optional[ResponseTextParam] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_logprobs: Optional[int] = ..., + top_p: Optional[int] = ..., + truncation: Optional[Literal[auto, disabled]] = ..., + usage: Optional[ResponseUsage] = ..., + user: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.ResponseStreamEvent(_Model): + sequence_number: int + type: str + + @overload + def __init__( + self, + *, + sequence_number: int, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.agentserver.responses.models.runtime.ResponseStreamEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ERROR = "error" + RESPONSE_AUDIO_DELTA = "response.audio.delta" + RESPONSE_AUDIO_DONE = "response.audio.done" + RESPONSE_AUDIO_TRANSCRIPT_DELTA = "response.audio.transcript.delta" + RESPONSE_AUDIO_TRANSCRIPT_DONE = "response.audio.transcript.done" + RESPONSE_CODE_INTERPRETER_CALL_CODE_DELTA = "response.code_interpreter_call_code.delta" + RESPONSE_CODE_INTERPRETER_CALL_CODE_DONE = "response.code_interpreter_call_code.done" + RESPONSE_CODE_INTERPRETER_CALL_COMPLETED = "response.code_interpreter_call.completed" + RESPONSE_CODE_INTERPRETER_CALL_INTERPRETING = "response.code_interpreter_call.interpreting" + RESPONSE_CODE_INTERPRETER_CALL_IN_PROGRESS = "response.code_interpreter_call.in_progress" + RESPONSE_COMPLETED = "response.completed" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + RESPONSE_CREATED = "response.created" + RESPONSE_CUSTOM_TOOL_CALL_INPUT_DELTA = "response.custom_tool_call_input.delta" + RESPONSE_CUSTOM_TOOL_CALL_INPUT_DONE = "response.custom_tool_call_input.done" + RESPONSE_FAILED = "response.failed" + RESPONSE_FILE_SEARCH_CALL_COMPLETED = "response.file_search_call.completed" + RESPONSE_FILE_SEARCH_CALL_IN_PROGRESS = "response.file_search_call.in_progress" + RESPONSE_FILE_SEARCH_CALL_SEARCHING = "response.file_search_call.searching" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + RESPONSE_IMAGE_GENERATION_CALL_COMPLETED = "response.image_generation_call.completed" + RESPONSE_IMAGE_GENERATION_CALL_GENERATING = "response.image_generation_call.generating" + RESPONSE_IMAGE_GENERATION_CALL_IN_PROGRESS = "response.image_generation_call.in_progress" + RESPONSE_IMAGE_GENERATION_CALL_PARTIAL_IMAGE = "response.image_generation_call.partial_image" + RESPONSE_INCOMPLETE = "response.incomplete" + RESPONSE_IN_PROGRESS = "response.in_progress" + RESPONSE_MCP_CALL_ARGUMENTS_DELTA = "response.mcp_call_arguments.delta" + RESPONSE_MCP_CALL_ARGUMENTS_DONE = "response.mcp_call_arguments.done" + RESPONSE_MCP_CALL_COMPLETED = "response.mcp_call.completed" + RESPONSE_MCP_CALL_FAILED = "response.mcp_call.failed" + RESPONSE_MCP_CALL_IN_PROGRESS = "response.mcp_call.in_progress" + RESPONSE_MCP_LIST_TOOLS_COMPLETED = "response.mcp_list_tools.completed" + RESPONSE_MCP_LIST_TOOLS_FAILED = "response.mcp_list_tools.failed" + RESPONSE_MCP_LIST_TOOLS_IN_PROGRESS = "response.mcp_list_tools.in_progress" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + RESPONSE_OUTPUT_TEXT_ANNOTATION_ADDED = "response.output_text.annotation.added" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + RESPONSE_QUEUED = "response.queued" + RESPONSE_REASONING_SUMMARY_PART_ADDED = "response.reasoning_summary_part.added" + RESPONSE_REASONING_SUMMARY_PART_DONE = "response.reasoning_summary_part.done" + RESPONSE_REASONING_SUMMARY_TEXT_DELTA = "response.reasoning_summary_text.delta" + RESPONSE_REASONING_SUMMARY_TEXT_DONE = "response.reasoning_summary_text.done" + RESPONSE_REASONING_TEXT_DELTA = "response.reasoning_text.delta" + RESPONSE_REASONING_TEXT_DONE = "response.reasoning_text.done" + RESPONSE_REFUSAL_DELTA = "response.refusal.delta" + RESPONSE_REFUSAL_DONE = "response.refusal.done" + RESPONSE_WEB_SEARCH_CALL_COMPLETED = "response.web_search_call.completed" + RESPONSE_WEB_SEARCH_CALL_IN_PROGRESS = "response.web_search_call.in_progress" + RESPONSE_WEB_SEARCH_CALL_SEARCHING = "response.web_search_call.searching" + + + class azure.ai.agentserver.responses.models.runtime.StreamEventRecord: + property terminal: bool # Read-only + + def __init__( + self, + *, + emitted_at: datetime | None = ..., + event_type: str, + payload: Mapping[str, Any], + sequence_number: int + ) -> None: ... + + @classmethod + def from_generated( + cls, + event: ResponseStreamEvent, + payload: Mapping[str, Any] + ) -> StreamEventRecord: ... + + + class azure.ai.agentserver.responses.models.runtime.StreamReplayState: + property terminal_event_seen: bool # Read-only + + def __init__( + self, + *, + events: list[StreamEventRecord] | None = ..., + response_id: str + ) -> None: ... + + def append(self, event: StreamEventRecord) -> None: ... + + +namespace azure.ai.agentserver.responses.streaming + + class azure.ai.agentserver.responses.streaming.OutputItemBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def emit_added(self, item: OutputItem) -> ResponseOutputItemAddedEvent: ... + + def emit_done(self, item: OutputItem) -> ResponseOutputItemDoneEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemCodeInterpreterCallBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + async def acode(self, code_text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def code(self, code_text: str) -> Iterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_code_delta(self, delta: str) -> ResponseCodeInterpreterCallCodeDeltaEvent: ... + + def emit_code_done(self, code: str) -> ResponseCodeInterpreterCallCodeDoneEvent: ... + + def emit_completed(self) -> ResponseCodeInterpreterCallCompletedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def emit_in_progress(self) -> ResponseCodeInterpreterCallInProgressEvent: ... + + def emit_interpreting(self) -> ResponseCodeInterpreterCallInterpretingEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemCustomToolCallBuilder(BaseOutputItemBuilder): + property call_id: str # Read-only + property item_id: str # Read-only + property name: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str, + call_id: str, + name: str + ) -> None: ... + + async def ainput(self, input_text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def emit_input_delta(self, delta: str) -> ResponseCustomToolCallInputDeltaEvent: ... + + def emit_input_done(self, input_text: str) -> ResponseCustomToolCallInputDoneEvent: ... + + def input(self, input_text: str) -> Iterator[ResponseStreamEvent]: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemFileSearchCallBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_completed(self) -> ResponseFileSearchCallCompletedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def emit_in_progress(self) -> ResponseFileSearchCallInProgressEvent: ... + + def emit_searching(self) -> ResponseFileSearchCallSearchingEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemFunctionCallBuilder(BaseOutputItemBuilder): + property call_id: str # Read-only + property item_id: str # Read-only + property name: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str, + name: str, + call_id: str + ) -> None: ... + + async def aarguments(self, args: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def arguments(self, args: str) -> Iterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_arguments_delta(self, delta: str) -> ResponseFunctionCallArgumentsDeltaEvent: ... + + def emit_arguments_done(self, arguments: str) -> ResponseFunctionCallArgumentsDoneEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemFunctionCallOutputBuilder(BaseOutputItemBuilder): + property call_id: str # Read-only + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str, + call_id: str + ) -> None: ... + + def emit_added(self, output: str | list[InputTextContentParam | InputImageContentParamAutoParam | InputFileContentParam] | None = None) -> ResponseOutputItemAddedEvent: ... + + def emit_done(self, output: str | list[InputTextContentParam | InputImageContentParamAutoParam | InputFileContentParam] | None = None) -> ResponseOutputItemDoneEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemImageGenCallBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_completed(self) -> ResponseImageGenCallCompletedEvent: ... + + def emit_done(self, result: str) -> ResponseOutputItemDoneEvent: ... + + def emit_generating(self) -> ResponseImageGenCallGeneratingEvent: ... + + def emit_in_progress(self) -> ResponseImageGenCallInProgressEvent: ... + + def emit_partial_image(self, partial_image_b64: str) -> ResponseImageGenCallPartialImageEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemMcpCallBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property name: str # Read-only + property output_index: int # Read-only + property server_label: str # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str, + server_label: str, + name: str + ) -> None: ... + + async def aarguments(self, args: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def arguments(self, args: str) -> Iterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_arguments_delta(self, delta: str) -> ResponseMCPCallArgumentsDeltaEvent: ... + + def emit_arguments_done(self, arguments: str) -> ResponseMCPCallArgumentsDoneEvent: ... + + def emit_completed(self) -> ResponseMCPCallCompletedEvent: ... + + def emit_done( + self, + *, + error: dict[str, Any] | None = ..., + output: str | None = ... + ) -> ResponseOutputItemDoneEvent: ... + + def emit_failed(self) -> ResponseMCPCallFailedEvent: ... + + def emit_in_progress(self) -> ResponseMCPCallInProgressEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemMcpListToolsBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + property server_label: str # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str, + server_label: str + ) -> None: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_completed(self) -> ResponseMCPListToolsCompletedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def emit_failed(self) -> ResponseMCPListToolsFailedEvent: ... + + def emit_in_progress(self) -> ResponseMCPListToolsInProgressEvent: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemMessageBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def add_refusal_content(self) -> RefusalContentBuilder: ... + + def add_text_content(self) -> TextContentBuilder: ... + + async def arefusal_content(self, text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + async def atext_content(self, text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def refusal_content(self, text: str) -> Iterator[ResponseStreamEvent]: ... + + def text_content(self, text: str) -> Iterator[ResponseStreamEvent]: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemReasoningItemBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def add_summary_part(self) -> ReasoningSummaryPartBuilder: ... + + async def asummary_part(self, text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def summary_part(self, text: str) -> Iterator[ResponseStreamEvent]: ... + + + class azure.ai.agentserver.responses.streaming.OutputItemWebSearchCallBuilder(BaseOutputItemBuilder): + property item_id: str # Read-only + property output_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseOutputItemAddedEvent: ... + + def emit_completed(self) -> ResponseWebSearchCallCompletedEvent: ... + + def emit_done(self) -> ResponseOutputItemDoneEvent: ... + + def emit_in_progress(self) -> ResponseWebSearchCallInProgressEvent: ... + + def emit_searching(self) -> ResponseWebSearchCallSearchingEvent: ... + + + class azure.ai.agentserver.responses.streaming.ReasoningSummaryPartBuilder: + property final_text: str | None # Read-only + property summary_index: int # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + summary_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseReasoningSummaryPartAddedEvent: ... + + def emit_done(self) -> ResponseReasoningSummaryPartDoneEvent: ... + + def emit_text_delta(self, text: str) -> ResponseReasoningSummaryTextDeltaEvent: ... + + def emit_text_done(self, final_text: str) -> ResponseReasoningSummaryTextDoneEvent: ... + + + class azure.ai.agentserver.responses.streaming.RefusalContentBuilder: + property content_index: int # Read-only + property final_refusal: str | None # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + content_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseContentPartAddedEvent: ... + + def emit_delta(self, text: str) -> ResponseRefusalDeltaEvent: ... + + def emit_done(self) -> ResponseContentPartDoneEvent: ... + + def emit_refusal_done(self, final_refusal: str) -> ResponseRefusalDoneEvent: ... + + + class azure.ai.agentserver.responses.streaming.ResponseEventStream: + property response: ResponseObject # Read-only + + def __init__( + self, + *, + agent_reference: AgentReference | None = ..., + model: str | None = ..., + request: CreateResponse | None = ..., + response: ResponseObject | None = ..., + response_id: str | None = ... + ) -> None: ... + + def add_output_item(self, item_id: str) -> OutputItemBuilder: ... + + def add_output_item_apply_patch_call(self) -> OutputItemBuilder: ... + + def add_output_item_apply_patch_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_code_interpreter_call(self) -> OutputItemCodeInterpreterCallBuilder: ... + + def add_output_item_compaction(self) -> OutputItemBuilder: ... + + def add_output_item_computer_call(self) -> OutputItemBuilder: ... + + def add_output_item_computer_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_custom_tool_call( + self, + call_id: str, + name: str + ) -> OutputItemCustomToolCallBuilder: ... + + def add_output_item_custom_tool_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_file_search_call(self) -> OutputItemFileSearchCallBuilder: ... + + def add_output_item_function_call( + self, + name: str, + call_id: str + ) -> OutputItemFunctionCallBuilder: ... + + def add_output_item_function_call_output(self, call_id: str) -> OutputItemFunctionCallOutputBuilder: ... + + def add_output_item_function_shell_call(self) -> OutputItemBuilder: ... + + def add_output_item_function_shell_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_image_gen_call(self) -> OutputItemImageGenCallBuilder: ... + + def add_output_item_local_shell_call(self) -> OutputItemBuilder: ... + + def add_output_item_local_shell_call_output(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_approval_request(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_approval_response(self) -> OutputItemBuilder: ... + + def add_output_item_mcp_call( + self, + server_label: str, + name: str, + *, + item_id: str | None = ... + ) -> OutputItemMcpCallBuilder: ... + + def add_output_item_mcp_list_tools(self, server_label: str) -> OutputItemMcpListToolsBuilder: ... + + def add_output_item_message(self) -> OutputItemMessageBuilder: ... + + def add_output_item_reasoning_item(self) -> OutputItemReasoningItemBuilder: ... + + def add_output_item_structured_outputs(self) -> OutputItemBuilder: ... + + def add_output_item_web_search_call(self) -> OutputItemWebSearchCallBuilder: ... + + async def aoutput_item_apply_patch_call( + self, + call_id: str, + operation: ApplyPatchFileOperation, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_apply_patch_call_output( + self, + call_id: str, + *, + output: str | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_compaction(self, encrypted_content: str) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_computer_call( + self, + call_id: str, + action: ComputerAction, + *, + pending_safety_checks: list[ComputerCallSafetyCheckParam] | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_computer_call_output( + self, + call_id: str, + output: ComputerScreenshotImage, + *, + acknowledged_safety_checks: list[ComputerCallSafetyCheckParam] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_custom_tool_call_output( + self, + call_id: str, + output: str | list[FunctionAndCustomToolCallOutput] + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_call( + self, + name: str, + call_id: str, + arguments: str | AsyncIterable[str] + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_call_output( + self, + call_id: str, + output: str + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_shell_call( + self, + call_id: str, + action: FunctionShellAction, + environment: FunctionShellCallEnvironment, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_function_shell_call_output( + self, + call_id: str, + output: list[FunctionShellCallOutputContent], + *, + max_output_length: int | None = ..., + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_image_gen_call( + self, + result_base64: str, + *, + partials: AsyncIterable[str] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_local_shell_call( + self, + call_id: str, + action: LocalShellExecAction, + *, + status: str = "completed" + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_local_shell_call_output(self, output: str) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_mcp_approval_request( + self, + server_label: str, + name: str, + arguments: str + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_mcp_approval_response( + self, + approval_request_id: str, + approve: bool = False, + *, + reason: str | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_message( + self, + text: str | AsyncIterable[str], + *, + annotations: Sequence[Annotation] | None = ... + ) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_reasoning_item(self, summary_text: str | AsyncIterable[str]) -> AsyncIterator[ResponseStreamEvent]: ... + + async def aoutput_item_structured_outputs(self, output: Any) -> AsyncIterator[ResponseStreamEvent]: ... + + def emit_completed( + self, + *, + usage: ResponseUsage | None = ... + ) -> ResponseCompletedEvent: ... + + def emit_created( + self, + *, + status: str = "in_progress" + ) -> ResponseCreatedEvent: ... + + def emit_failed( + self, + *, + code: str | ResponseErrorCode = "server_error", + message: str = "An internal server error occurred.", + usage: ResponseUsage | None = ... + ) -> ResponseFailedEvent: ... + + def emit_in_progress(self) -> ResponseInProgressEvent: ... + + def emit_incomplete( + self, + *, + reason: str | None = ..., + usage: ResponseUsage | None = ... + ) -> ResponseIncompleteEvent: ... + + def emit_queued(self) -> ResponseQueuedEvent: ... + + def events(self) -> list[ResponseStreamEvent]: ... + + def output_item_apply_patch_call( + self, + call_id: str, + operation: ApplyPatchFileOperation, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_apply_patch_call_output( + self, + call_id: str, + *, + output: str | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_compaction(self, encrypted_content: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_computer_call( + self, + call_id: str, + action: ComputerAction, + *, + pending_safety_checks: list[ComputerCallSafetyCheckParam] | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_computer_call_output( + self, + call_id: str, + output: ComputerScreenshotImage, + *, + acknowledged_safety_checks: list[ComputerCallSafetyCheckParam] | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_custom_tool_call_output( + self, + call_id: str, + output: str | list[FunctionAndCustomToolCallOutput] + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_call( + self, + name: str, + call_id: str, + arguments: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_call_output( + self, + call_id: str, + output: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_shell_call( + self, + call_id: str, + action: FunctionShellAction, + environment: FunctionShellCallEnvironment, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_function_shell_call_output( + self, + call_id: str, + output: list[FunctionShellCallOutputContent], + *, + max_output_length: int | None = ..., + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_image_gen_call(self, result_base64: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_local_shell_call( + self, + call_id: str, + action: LocalShellExecAction, + *, + status: str = "completed" + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_local_shell_call_output(self, output: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_mcp_approval_request( + self, + server_label: str, + name: str, + arguments: str + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_mcp_approval_response( + self, + approval_request_id: str, + approve: bool = False, + *, + reason: str | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_message( + self, + text: str, + *, + annotations: Sequence[Annotation] | None = ... + ) -> Iterator[ResponseStreamEvent]: ... + + def output_item_reasoning_item(self, summary_text: str) -> Iterator[ResponseStreamEvent]: ... + + def output_item_structured_outputs(self, output: Any) -> Iterator[ResponseStreamEvent]: ... + + + class azure.ai.agentserver.responses.streaming.TextContentBuilder: + property content_index: int # Read-only + property final_text: str | None # Read-only + + def __init__( + self, + stream: ResponseEventStream, + output_index: int, + content_index: int, + item_id: str + ) -> None: ... + + def emit_added(self) -> ResponseContentPartAddedEvent: ... + + def emit_annotation_added(self, annotation: Annotation) -> ResponseOutputTextAnnotationAddedEvent: ... + + def emit_delta(self, text: str) -> ResponseTextDeltaEvent: ... + + def emit_done(self) -> ResponseContentPartDoneEvent: ... + + def emit_text_done(self, final_text: str | None = None) -> ResponseTextDoneEvent: ... + + +``` \ No newline at end of file diff --git a/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml b/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml new file mode 100644 index 000000000000..ffc55b19dbca --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml @@ -0,0 +1,3 @@ +apiMdSha256: 1e263f94f166c4b1c33d3e4a0e95dc264a79559df9cc5cdccfeb9b989ad21e81 +parserVersion: 0.3.28 +pythonVersion: 3.11.9 diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/__init__.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/__init__.py index 06ca699d9e16..c0b53ae1ad5b 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/__init__.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/__init__.py @@ -8,7 +8,7 @@ from . import _data_url as data_url from ._options import ResponsesServerOptions -from ._response_context import IsolationContext, ResponseContext +from ._response_context import PlatformContext, ResponseContext from .hosting._routing import ResponsesAgentServerHost from .models import CreateResponse, ResponseObject from .models._helpers import ( @@ -34,7 +34,7 @@ "data_url", # pylint: disable=naming-mismatch "ResponsesAgentServerHost", "ResponseContext", - "IsolationContext", + "PlatformContext", "ResponsesServerOptions", "ResponseProviderProtocol", "ResponseStreamProviderProtocol", diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_response_context.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_response_context.py index 055cac67c6ca..3072bc3c5488 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_response_context.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_response_context.py @@ -24,30 +24,34 @@ from .store._base import ResponseProviderProtocol -class IsolationContext: - """Platform-injected isolation keys for multi-tenant state partitioning. - - The Foundry hosting platform injects ``x-agent-user-isolation-key`` and - ``x-agent-chat-isolation-key`` headers on every protocol request (not on - health probes). These opaque strings serve as partition keys: - - - ``user_key`` — unique per user across all sessions; use for user-private state. - - ``chat_key`` — represents where conversation state lives; in 1:1 chats the - two keys are equal. - - When the headers are absent (e.g. local development), both keys are ``None``. - When the platform sends the header with an empty value, the key is an empty - string. Use ``is None`` to detect whether the header was present at all. +class PlatformContext: + """Platform-injected identity context for multi-tenant state partitioning. + + The Foundry hosting platform injects ``x-agent-user-id`` and (on container + protocol version ``2.0.0``) ``x-agent-foundry-call-id`` headers on every + protocol request (not on health probes): + + - ``user_id_key`` — global, cross-agent per-user partition key; the same user + yields the same value regardless of which agent they interact with. Use it + as the primary partition key for per-user state. + - ``call_id`` — opaque per-request call identifier (protocol ``2.0.0`` only). + Providers **MUST** forward it on outbound Foundry API calls so 1P services + can resolve the server-side-stored caller context. Never parse it. + + When a header is absent (e.g. local development, or ``call_id`` under protocol + version ``1.0.0``), the corresponding field is ``None``. When the platform + sends the header with an empty value, the field is an empty string. Use + ``is None`` to detect whether the header was present at all. """ - def __init__(self, *, user_key: str | None = None, chat_key: str | None = None) -> None: - self.user_key = user_key - """Partition key for user-private state (from ``x-agent-user-isolation-key``). + def __init__(self, *, user_id_key: str | None = None, call_id: str | None = None) -> None: + self.user_id_key = user_id_key + """Partition key for per-user state (from ``x-agent-user-id``). ``None`` when the header was not sent.""" - self.chat_key = chat_key - """Partition key for conversation/shared state (from ``x-agent-chat-isolation-key``). - ``None`` when the header was not sent.""" + self.call_id = call_id + """Opaque per-request call identifier (from ``x-agent-foundry-call-id``). + ``None`` when the header was not sent (protocol ``1.0.0`` or local dev).""" class ResponseContext: # pylint: disable=too-many-instance-attributes @@ -72,7 +76,7 @@ def __init__( history_limit: int = 100, client_headers: dict[str, str] | None = None, query_parameters: dict[str, str] | None = None, - isolation: IsolationContext | None = None, + platform_context: PlatformContext | None = None, prefetched_history_ids: list[str] | None = None, ) -> None: self.response_id = response_id @@ -82,7 +86,9 @@ def __init__( self.is_shutdown_requested: bool = False self.client_headers: dict[str, str] = client_headers or {} self.query_parameters: dict[str, str] = query_parameters or {} - self.isolation: IsolationContext = isolation if isolation is not None else IsolationContext() + self.platform_context: PlatformContext = ( + platform_context if platform_context is not None else PlatformContext() + ) self._provider: "ResponseProviderProtocol | None" = provider _items: list[Any] if input_items is not None: @@ -193,7 +199,7 @@ async def _get_input_items_resolved(self) -> Sequence[Item]: # Batch-resolve references if we have a provider and pending refs. if reference_ids and self._provider is not None: - resolved = await self._provider.get_items(reference_ids, isolation=self.isolation) + resolved = await self._provider.get_items(reference_ids, context=self.platform_context) for idx, pos in enumerate(reference_positions): if idx < len(resolved) and resolved[idx] is not None: converted = to_item(resolved[idx]) # type: ignore[arg-type] @@ -257,12 +263,12 @@ async def get_history(self) -> Sequence[OutputItem]: self._previous_response_id, self.conversation_id, self._history_limit, - isolation=self.isolation, + context=self.platform_context, ) if not item_ids: self._history_cache = () return self._history_cache - items = await self._provider.get_items(item_ids, isolation=self.isolation) + items = await self._provider.get_items(item_ids, context=self.platform_context) self._history_cache = tuple(item for item in items if item is not None) return self._history_cache diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_version.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_version.py index f2e49b063730..2392dd2c2c03 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_version.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/_version.py @@ -4,4 +4,4 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # --------------------------------------------------------- -VERSION = "1.0.0b7" +VERSION = "1.0.0b8" diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_endpoint_handler.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_endpoint_handler.py index aa1517eb1fda..0f9cbfe39ee6 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_endpoint_handler.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_endpoint_handler.py @@ -22,13 +22,16 @@ from starlette.responses import JSONResponse, Response, StreamingResponse from azure.ai.agentserver.core import ( # pylint: disable=import-error,no-name-in-module + FoundryAgentRequestContext, flush_spans, + reset_request_context, + set_request_context, ) from azure.ai.agentserver.core._platform_headers import ( # pylint: disable=import-error,no-name-in-module - CHAT_ISOLATION_KEY, CLIENT_HEADER_PREFIX, + FOUNDRY_CALL_ID, SESSION_ID, - USER_ISOLATION_KEY, + USER_ID, ) from azure.ai.agentserver.core._request_id import REQUEST_ID_STATE_KEY # pylint: disable=import-error,no-name-in-module from azure.ai.agentserver.responses.models._generated import ( @@ -39,7 +42,7 @@ from .._id_generator import IdGenerator from .._options import ResponsesServerOptions -from .._response_context import IsolationContext, ResponseContext +from .._response_context import PlatformContext, ResponseContext from ..models._helpers import get_input_expanded, to_output_item from ..models.runtime import ResponseExecution, ResponseModeFlags, build_cancelled_response, build_failed_response from ..store._base import ResponseProviderProtocol, ResponseStreamProviderProtocol @@ -101,22 +104,22 @@ logger = logging.getLogger("azure.ai.agentserver") -def _extract_isolation(request: Request) -> IsolationContext: - """Build an ``IsolationContext`` from platform-injected request headers. +def _extract_platform_context(request: Request) -> PlatformContext: + """Build a ``PlatformContext`` from platform-injected request headers. - Returns the isolation keys from ``x-agent-user-isolation-key`` and - ``x-agent-chat-isolation-key``. Keys are ``None`` when the header - is absent (e.g. local development) and empty string when sent - with no value. + Returns the per-user key from ``x-agent-user-id`` and the per-request call + ID from ``x-agent-foundry-call-id`` (protocol ``2.0.0`` only). Fields are + ``None`` when the header is absent (e.g. local development) and empty string + when sent with no value. :param request: The incoming Starlette HTTP request. :type request: Request - :return: An isolation context with user and chat keys. - :rtype: IsolationContext + :return: A platform context with the user ID key and call ID. + :rtype: PlatformContext """ - return IsolationContext( - user_key=request.headers.get(USER_ISOLATION_KEY), - chat_key=request.headers.get(CHAT_ISOLATION_KEY), + return PlatformContext( + user_id_key=request.headers.get(USER_ID), + call_id=request.headers.get(FOUNDRY_CALL_ID), ) @@ -415,8 +418,8 @@ def _build_execution_context( agent_session_id=agent_session_id, span=span, parsed=parsed, - user_isolation_key=request.headers.get(USER_ISOLATION_KEY), - chat_isolation_key=request.headers.get(CHAT_ISOLATION_KEY), + user_id=request.headers.get(USER_ID), + call_id=request.headers.get(FOUNDRY_CALL_ID), ) # Derive the public ResponseContext from the execution context. @@ -458,9 +461,9 @@ def _create_response_context( history_limit=self._runtime_options.default_fetch_history_count, client_headers=client_headers, query_parameters=dict(request.query_params), - isolation=IsolationContext( - user_key=ctx.user_isolation_key, - chat_key=ctx.chat_isolation_key, + platform_context=PlatformContext( + user_id_key=ctx.user_id, + call_id=ctx.call_id, ), prefetched_history_ids=ctx.prefetched_history_ids, ) @@ -497,12 +500,12 @@ async def _prefetch_history_ids( _hdrs = self._session_headers(agent_session_id) try: - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None prefetched = await self._provider.get_history_item_ids( ctx.previous_response_id, ctx.conversation_id, self._runtime_options.default_fetch_history_count, - isolation=_isolation, + context=_context, ) ctx.prefetched_history_ids = prefetched if ctx.context is not None: @@ -613,7 +616,7 @@ async def handle_create(self, request: Request) -> Response: # pylint: disable= logger.info( "Creating response %s: streaming=%s background=%s store=%s model=%s " "conversation_id=%s previous_response_id=%s " - "has_user_isolation_key=%s has_chat_isolation_key=%s", + "has_user_id=%s has_call_id=%s", ctx.response_id, ctx.stream, ctx.background, @@ -621,8 +624,8 @@ async def handle_create(self, request: Request) -> Response: # pylint: disable= ctx.model, ctx.conversation_id, ctx.previous_response_id, - ctx.user_isolation_key is not None, - ctx.chat_isolation_key is not None, + ctx.user_id is not None, + ctx.call_id is not None, ) # Eagerly validate conversation references before the handler runs. @@ -656,31 +659,44 @@ async def handle_create(self, request: Request) -> Response: # pylint: disable= rid_token = _response_id_var.set(response_id) cid_token = _conversation_id_var.set(ctx.conversation_id or "") str_token = _streaming_var.set(str(ctx.stream).lower()) + # Bind platform context so handler/tool code making raw outbound 1P calls + # can forward the per-request call ID and user ID (protocol 2.0.0). + platform_context = FoundryAgentRequestContext( + call_id=ctx.call_id or None, + user_id=ctx.user_id or None, + session_id=agent_session_id, + ) + platform_ctx_token = set_request_context(platform_context) disconnect_task: asyncio.Task[None] | None = None try: if ctx.stream: - body_iter = self._orchestrator.run_stream(ctx) + raw_iter = self._orchestrator.run_stream(ctx) # B17: monitor client disconnect for non-background streams if not ctx.background: disconnect_task = asyncio.create_task( self._monitor_disconnect(request, ctx.cancellation_signal) ) - raw_iter = body_iter - - async def _iter_with_cleanup(): # type: ignore[return] - try: - async for chunk in raw_iter: - yield chunk - finally: - if disconnect_task and not disconnect_task.done(): - disconnect_task.cancel() - body_iter = _iter_with_cleanup() + # The handler runs lazily while Starlette iterates this body, which + # happens after handle_create returns (line below) and the `finally` + # has already reset the request context. Re-establish the platform + # context inside the streaming task so handler/tool code can still + # forward the per-request call ID / user ID (protocol 2.0.0), and + # fold in disconnect-task cleanup. + async def _iter_with_context(): # type: ignore[return] + stream_ctx_token = set_request_context(platform_context) + try: + async for chunk in raw_iter: + yield chunk + finally: + reset_request_context(stream_ctx_token) + if disconnect_task and not disconnect_task.done(): + disconnect_task.cancel() sse_response = StreamingResponse( - body_iter, + _iter_with_context(), media_type="text/event-stream", headers={**self._sse_headers, **self._session_headers(agent_session_id)}, ) @@ -754,6 +770,7 @@ async def _iter_with_cleanup(): # type: ignore[return] _response_id_var.reset(rid_token) _conversation_id_var.reset(cid_token) _streaming_var.reset(str_token) + reset_request_context(platform_ctx_token) # Flush pending spans before the response is sent. # BatchSpanProcessor exports on a timer; in hosted sandboxes # the platform may freeze the process after the HTTP response, @@ -782,20 +799,20 @@ async def handle_get(self, request: Request) -> Response: # pylint: disable=too return format_error stream_replay_param = request.query_params.get("stream", "false").lower() == "true" - _isolation = _extract_isolation(request) + _context = _extract_platform_context(request) if stream_replay_param: logger.info( - "Getting response %s with SSE replay, has_user_isolation_key=%s has_chat_isolation_key=%s", + "Getting response %s with SSE replay, has_user_id=%s has_call_id=%s", response_id, - _isolation.user_key is not None, - _isolation.chat_key is not None, + _context.user_id_key is not None, + _context.call_id is not None, ) else: logger.info( - "Getting response %s, has_user_isolation_key=%s has_chat_isolation_key=%s", + "Getting response %s, has_user_id=%s has_call_id=%s", response_id, - _isolation.user_key is not None, - _isolation.chat_key is not None, + _context.user_id_key is not None, + _context.call_id is not None, ) record = await self._runtime_state.get(response_id) if record is None: @@ -803,12 +820,12 @@ async def handle_get(self, request: Request) -> Response: # pylint: disable=too request, response_id, stream_replay_param, - _isolation, + _context, _hdrs, ) - # Chat isolation enforcement on in-flight response - if not _RuntimeState.check_chat_isolation(record.chat_isolation_key, _isolation.chat_key): + # User isolation enforcement on in-flight response + if not _RuntimeState.check_user_isolation(record.user_id_key, _context.user_id_key): return _not_found(response_id, _hdrs) _refresh_background_status(record) @@ -873,7 +890,7 @@ async def _handle_get_fallback( # pylint: disable=too-many-return-statements request: Request, response_id: str, stream_replay: bool, - _isolation: "IsolationContext", + _context: "PlatformContext", _hdrs: dict[str, str], ) -> Response: """Provider fallback for GET when the record is not in runtime state. @@ -887,8 +904,8 @@ async def _handle_get_fallback( # pylint: disable=too-many-return-statements :type response_id: str :param stream_replay: Whether the client requested SSE replay. :type stream_replay: bool - :param _isolation: Isolation context from the request. - :type _isolation: IsolationContext + :param _context: Platform context from the request. + :type _context: PlatformContext :param _hdrs: Session headers to include on the response. :type _hdrs: dict[str, str] :return: Response. @@ -901,7 +918,7 @@ async def _handle_get_fallback( # pylint: disable=too-many-return-statements # Provider fallback: serve completed responses that are no longer in runtime state # (e.g., after a process restart). try: - response_obj = await self._provider.get_response(response_id, isolation=_isolation) + response_obj = await self._provider.get_response(response_id, context=_context) snapshot = response_obj.as_dict() logger.info( "Retrieved response %s: status=%s output_count=%d", @@ -930,7 +947,7 @@ async def _handle_get_fallback( # pylint: disable=too-many-return-statements replay_response = await self._try_replay_persisted_stream( request, response_id, - isolation=_isolation, + context=_context, headers=_hdrs, ) if replay_response is not None: @@ -942,7 +959,7 @@ async def _handle_get_fallback( # pylint: disable=too-many-return-statements # bg+stream-with-expired-TTL (we don't persist the stream flag), # so use a combined message. try: - persisted = await self._provider.get_response(response_id, isolation=_isolation) + persisted = await self._provider.get_response(response_id, context=_context) persisted_dict = persisted.as_dict() # B2: SSE replay requires background mode. if persisted_dict.get("background") is not True: @@ -1036,7 +1053,7 @@ async def _try_replay_persisted_stream( request: Request, response_id: str, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, headers: dict[str, str] | None = None, ) -> Response | None: """Try to replay persisted SSE events from the stream provider. @@ -1049,8 +1066,8 @@ async def _try_replay_persisted_stream( :type request: Request :param response_id: The response identifier to replay. :type response_id: str - :keyword isolation: Optional isolation context for multi-tenant filtering. - :paramtype isolation: IsolationContext | None + :keyword context: Optional platform context for multi-tenant filtering. + :paramtype context: PlatformContext | None :keyword headers: Optional extra headers (e.g. session headers) to merge with SSE headers. :paramtype headers: dict[str, str] | None :return: A streaming replay response, an error response, or ``None``. @@ -1059,7 +1076,7 @@ async def _try_replay_persisted_stream( if self._stream_provider is None: return None try: - replay_events = await self._stream_provider.get_stream_events(response_id, isolation=isolation) + replay_events = await self._stream_provider.get_stream_events(response_id, context=context) if replay_events is None: return None parsed_cursor = self._parse_starting_after(request, headers) @@ -1090,12 +1107,12 @@ async def handle_delete(self, request: Request) -> Response: if format_error is not None: return format_error - _isolation = _extract_isolation(request) + _context = _extract_platform_context(request) logger.info( - "Deleting response %s, has_user_isolation_key=%s has_chat_isolation_key=%s", + "Deleting response %s, has_user_id=%s has_call_id=%s", response_id, - _isolation.user_key is not None, - _isolation.chat_key is not None, + _context.user_id_key is not None, + _context.call_id is not None, ) record = await self._runtime_state.get(response_id) if record is None: @@ -1104,14 +1121,14 @@ async def handle_delete(self, request: Request) -> Response: if await self._runtime_state.is_deleted(response_id): return _not_found(response_id, _hdrs) - result = await self._provider_delete_response(response_id, _isolation, _hdrs) + result = await self._provider_delete_response(response_id, _context, _hdrs) if result is not None: return result return _not_found(response_id, _hdrs) - # Chat isolation enforcement - if not _RuntimeState.check_chat_isolation(record.chat_isolation_key, _isolation.chat_key): + # User isolation enforcement + if not _RuntimeState.check_user_isolation(record.user_id_key, _context.user_id_key): return _not_found(response_id, _hdrs) # store=false responses are not deletable (FR-014) @@ -1135,14 +1152,14 @@ async def handle_delete(self, request: Request) -> Response: # persistence attempt, but persistence is best-effort and may not # have succeeded, so delegate to the provider path as a fallback. if record.mode_flags.store: - result = await self._provider_delete_response(response_id, _isolation, _hdrs) + result = await self._provider_delete_response(response_id, _context, _hdrs) if result is not None: return result return _not_found(response_id, _hdrs) if record.mode_flags.store: try: - await self._provider.delete_response(response_id, isolation=_extract_isolation(request)) + await self._provider.delete_response(response_id, context=_extract_platform_context(request)) except Exception: # pylint: disable=broad-exception-caught logger.warning("Best-effort provider delete failed for response_id=%s", response_id, exc_info=True) # Clean up persisted stream events @@ -1150,7 +1167,7 @@ async def handle_delete(self, request: Request) -> Response: try: await self._stream_provider.delete_stream_events( response_id, - isolation=_extract_isolation(request), + context=_extract_platform_context(request), ) except Exception: # pylint: disable=broad-exception-caught logger.debug( @@ -1169,7 +1186,7 @@ async def handle_delete(self, request: Request) -> Response: async def _provider_delete_response( self, response_id: str, - isolation: "IsolationContext", + context: "PlatformContext", headers: dict[str, str], ) -> Response | None: """Delete a response from the durable provider (storage). @@ -1185,19 +1202,19 @@ async def _provider_delete_response( :param response_id: The response ID to delete. :type response_id: str - :param isolation: Isolation context extracted from the request. - :type isolation: IsolationContext + :param context: Platform context extracted from the request. + :type context: PlatformContext :param headers: Session headers to include on the response. :type headers: dict[str, str] :return: A success/error response, or ``None`` if not found. :rtype: Response | None """ try: - await self._provider.delete_response(response_id, isolation=isolation) + await self._provider.delete_response(response_id, context=context) # Clean up persisted stream events if self._stream_provider is not None: try: - await self._stream_provider.delete_stream_events(response_id, isolation=isolation) + await self._stream_provider.delete_stream_events(response_id, context=context) except Exception: # pylint: disable=broad-exception-caught logger.debug( "Best-effort stream event delete failed for response_id=%s", @@ -1241,19 +1258,19 @@ async def handle_cancel(self, request: Request) -> Response: if format_error is not None: return format_error - _isolation = _extract_isolation(request) + _context = _extract_platform_context(request) logger.info( - "Cancelling response %s, has_user_isolation_key=%s has_chat_isolation_key=%s", + "Cancelling response %s, has_user_id=%s has_call_id=%s", response_id, - _isolation.user_key is not None, - _isolation.chat_key is not None, + _context.user_id_key is not None, + _context.call_id is not None, ) record = await self._runtime_state.get(response_id) if record is None: - return await self._handle_cancel_fallback(response_id, _isolation, _hdrs) + return await self._handle_cancel_fallback(response_id, _context, _hdrs) - # Chat isolation enforcement on in-flight response - if not _RuntimeState.check_chat_isolation(record.chat_isolation_key, _isolation.chat_key): + # User isolation enforcement on in-flight response + if not _RuntimeState.check_user_isolation(record.user_id_key, _context.user_id_key): return _not_found(response_id, _hdrs) _refresh_background_status(record) @@ -1296,7 +1313,7 @@ async def handle_cancel(self, request: Request) -> Response: # Persist cancelled state to durable store (B11: cancellation always wins) try: if record.response is not None: - await self._provider.update_response(record.response, isolation=_extract_isolation(request)) + await self._provider.update_response(record.response, context=_extract_platform_context(request)) except Exception: # pylint: disable=broad-exception-caught logger.debug("Best-effort cancel persist failed for response_id=%s", record.response_id, exc_info=True) @@ -1312,7 +1329,7 @@ async def handle_cancel(self, request: Request) -> Response: async def _handle_cancel_fallback( self, response_id: str, - _isolation: "IsolationContext", + _context: "PlatformContext", _hdrs: dict[str, str], ) -> Response: """Provider fallback for cancel when the record is not in runtime state. @@ -1323,15 +1340,15 @@ async def _handle_cancel_fallback( :param response_id: The response ID to cancel. :type response_id: str - :param _isolation: Isolation context from the request. - :type _isolation: IsolationContext + :param _context: Platform context from the request. + :type _context: PlatformContext :param _hdrs: Session headers to include on the response. :type _hdrs: dict[str, str] :return: Error or idempotent response. :rtype: Response """ try: - response_obj = await self._provider.get_response(response_id, isolation=_isolation) + response_obj = await self._provider.get_response(response_id, context=_context) persisted = response_obj.as_dict() # B1: background check comes first — non-bg responses always @@ -1380,19 +1397,19 @@ async def handle_input_items(self, request: Request) -> Response: if format_error is not None: return format_error - _isolation = _extract_isolation(request) + _context = _extract_platform_context(request) logger.info( - "Getting input items for response %s, has_user_isolation_key=%s has_chat_isolation_key=%s", + "Getting input items for response %s, has_user_id=%s has_call_id=%s", response_id, - _isolation.user_key is not None, - _isolation.chat_key is not None, + _context.user_id_key is not None, + _context.call_id is not None, ) - # Chat isolation enforcement for in-flight responses. After eviction, - # the provider (Foundry storage) enforces isolation server-side. + # User isolation enforcement for in-flight responses. After eviction, + # the provider (Foundry storage) enforces partitioning server-side. record = await self._runtime_state.get(response_id) if record is not None: - if not _RuntimeState.check_chat_isolation(record.chat_isolation_key, _isolation.chat_key): + if not _RuntimeState.check_user_isolation(record.user_id_key, _context.user_id_key): return _not_found(response_id, _hdrs) limit_raw = request.query_params.get("limit", "20") @@ -1412,7 +1429,7 @@ async def handle_input_items(self, request: Request) -> Response: before = request.query_params.get("before") try: - items = await self._provider.get_input_items(response_id, limit=100, ascending=True, isolation=_isolation) + items = await self._provider.get_input_items(response_id, limit=100, ascending=True, context=_context) except ValueError: return _deleted_response(response_id, _hdrs) except FoundryResourceNotFoundError: @@ -1424,7 +1441,7 @@ async def handle_input_items(self, request: Request) -> Response: return _error_response(exc, _hdrs) except KeyError: # Fall back to runtime_state for in-flight responses not yet persisted to provider. - # Chat isolation was already checked above when the record is in-flight. + # User isolation was already checked above when the record is in-flight. try: items = await self._runtime_state.get_input_items(response_id) except ValueError: diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_execution_context.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_execution_context.py index c27b7acb18e4..89e18252d305 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_execution_context.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_execution_context.py @@ -38,8 +38,8 @@ def __init__( parsed: CreateResponse, agent_session_id: str | None = None, context: ResponseContext | None = None, - user_isolation_key: str | None = None, - chat_isolation_key: str | None = None, + user_id: str | None = None, + call_id: str | None = None, prefetched_history_ids: list[str] | None = None, ) -> None: self.response_id = response_id @@ -56,6 +56,6 @@ def __init__( self.parsed = parsed self.agent_session_id = agent_session_id self.context = context - self.user_isolation_key = user_isolation_key - self.chat_isolation_key = chat_isolation_key + self.user_id = user_id + self.call_id = call_id self.prefetched_history_ids = prefetched_history_ids diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_orchestrator.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_orchestrator.py index 99a26a17ccb2..999d5d641105 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_orchestrator.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_orchestrator.py @@ -326,21 +326,21 @@ async def _run_background_non_stream( # pylint: disable=too-many-locals,too-man # Persist at response.created time for bg+store (FR-003) if store and provider is not None: try: - _isolation = context.isolation if context else None + _context = context.platform_context if context else None _response_obj = generated_models.ResponseObject(_initial_snapshot) _history_ids = ( await provider.get_history_item_ids( record.previous_response_id, None, history_limit, - isolation=_isolation, + context=_context, ) if record.previous_response_id else None ) _resolved_items = await _resolve_input_items_for_persistence(context, record.input_items) await provider.create_response( - _response_obj, _resolved_items, _history_ids, isolation=_isolation + _response_obj, _resolved_items, _history_ids, context=_context ) _provider_created = True except Exception as persist_exc: # pylint: disable=broad-exception-caught @@ -501,15 +501,15 @@ async def _run_background_non_stream( # pylint: disable=too-many-locals,too-man record.set_response_snapshot(storage_error_response) record.status = "failed" # type: ignore[assignment] else: - _isolation = context.isolation if context else None + _context = context.platform_context if context else None try: if _provider_created: - await provider.update_response(record.response, isolation=_isolation) + await provider.update_response(record.response, context=_context) else: # Response was never created (handler yielded nothing or # failed before response.created) — create instead of update. _resolved_items = await _resolve_input_items_for_persistence(context, record.input_items) - await provider.create_response(record.response, _resolved_items, None, isolation=_isolation) + await provider.create_response(record.response, _resolved_items, None, context=_context) except Exception as persist_exc: # pylint: disable=broad-exception-caught setattr(persist_exc, PLATFORM_ERROR_TAG, True) logger.error( @@ -602,7 +602,7 @@ def _make_ephemeral_record(ctx: "_ExecutionContext", state: "_PipelineState") -> previous_response_id=ctx.previous_response_id, agent_session_id=ctx.agent_session_id, conversation_id=ctx.conversation_id, - chat_isolation_key=ctx.chat_isolation_key, + user_id_key=ctx.user_id, ) # Stash on state so _finalize_stream can access persistence_failed state.bg_record = record @@ -919,11 +919,11 @@ async def _persist_and_resolve_terminal( self._apply_storage_error_replacement(ctx, state, record) else: record.response.background = record.mode_flags.background - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None try: if state.provider_created: # bg+stream: initial create already done at response.created — use update - await self._provider.update_response(record.response, isolation=_isolation) + await self._provider.update_response(record.response, context=_context) else: # non-bg stream or bg stream where initial create was never registered: # full create @@ -932,7 +932,7 @@ async def _persist_and_resolve_terminal( ctx.previous_response_id, None, self._runtime_options.default_fetch_history_count, - isolation=_isolation, + context=_context, ) if ctx.previous_response_id else None @@ -942,7 +942,7 @@ async def _persist_and_resolve_terminal( generated_models.ResponseObject(response_payload), _resolved_items, _history_ids, - isolation=_isolation, + context=_context, ) except Exception as persist_exc: # pylint: disable=broad-exception-caught setattr(persist_exc, PLATFORM_ERROR_TAG, True) @@ -1003,7 +1003,7 @@ async def _register_bg_execution( cancel_signal=ctx.cancellation_signal, agent_session_id=ctx.agent_session_id, conversation_id=ctx.conversation_id, - chat_isolation_key=ctx.chat_isolation_key, + user_id_key=ctx.user_id, ) execution.set_response_snapshot(generated_models.ResponseObject(initial_payload)) execution.subject = _ResponseEventSubject() @@ -1012,14 +1012,14 @@ async def _register_bg_execution( await state.bg_record.subject.publish(first_normalized) await self._runtime_state.add(execution) if ctx.store: - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None _initial_response_obj = generated_models.ResponseObject(initial_payload) _history_ids = ( await self._provider.get_history_item_ids( ctx.previous_response_id, None, self._runtime_options.default_fetch_history_count, - isolation=_isolation, + context=_context, ) if ctx.previous_response_id else None @@ -1027,7 +1027,7 @@ async def _register_bg_execution( _resolved_items = await _resolve_input_items_for_persistence(ctx.context, ctx.input_items) try: await self._provider.create_response( - _initial_response_obj, _resolved_items, _history_ids, isolation=_isolation + _initial_response_obj, _resolved_items, _history_ids, context=_context ) state.provider_created = True except Exception as persist_exc: # pylint: disable=broad-exception-caught @@ -1336,10 +1336,10 @@ async def _finalize_stream(self, ctx: _ExecutionContext, state: _PipelineState) # Persist SSE events for replay after process restart (not needed for cancelled). if record.status != "cancelled" and self._stream_provider is not None and state.handler_events: - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None try: await self._stream_provider.save_stream_events( - ctx.response_id, state.handler_events, isolation=_isolation + ctx.response_id, state.handler_events, context=_context ) except Exception: # pylint: disable=broad-exception-caught logger.warning( @@ -1419,7 +1419,7 @@ async def _finalize_stream(self, ctx: _ExecutionContext, state: _PipelineState) cancel_signal=ctx.cancellation_signal if ctx.background else None, agent_session_id=ctx.agent_session_id, conversation_id=ctx.conversation_id, - chat_isolation_key=ctx.chat_isolation_key, + user_id_key=ctx.user_id, ) execution.set_response_snapshot(generated_models.ResponseObject(response_payload)) # Copy persistence_failed from the ephemeral record if one was used @@ -1430,9 +1430,9 @@ async def _finalize_stream(self, ctx: _ExecutionContext, state: _PipelineState) # Persist SSE events for replay after eager eviction (bg+stream only). if ctx.background and ctx.store and self._stream_provider is not None and events: - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None try: - await self._stream_provider.save_stream_events(ctx.response_id, events, isolation=_isolation) + await self._stream_provider.save_stream_events(ctx.response_id, events, context=_context) except Exception: # pylint: disable=broad-exception-caught logger.warning( "Best-effort stream event persistence failed (response_id=%s)", @@ -1720,7 +1720,7 @@ async def run_sync(self, ctx: _ExecutionContext) -> dict[str, Any]: response_context=ctx.context, agent_session_id=ctx.agent_session_id, conversation_id=ctx.conversation_id, - chat_isolation_key=ctx.chat_isolation_key, + user_id_key=ctx.user_id, ) record.set_response_snapshot(generated_models.ResponseObject(response_payload)) @@ -1733,14 +1733,14 @@ async def run_sync(self, ctx: _ExecutionContext) -> dict[str, Any]: # Persist via provider (non-bg sync: single create at terminal state). # §3.1: Persistence failure replaces the response body with storage_error. try: - _isolation = ctx.context.isolation if ctx.context else None + _context = ctx.context.platform_context if ctx.context else None _response_obj = generated_models.ResponseObject(response_payload) _history_ids = ( await self._provider.get_history_item_ids( ctx.previous_response_id, None, self._runtime_options.default_fetch_history_count, - isolation=_isolation, + context=_context, ) if ctx.previous_response_id else None @@ -1750,7 +1750,7 @@ async def run_sync(self, ctx: _ExecutionContext) -> dict[str, Any]: _response_obj, _resolved_items, _history_ids, - isolation=_isolation, + context=_context, ) except Exception as persist_exc: # pylint: disable=broad-exception-caught logger.error( @@ -1818,7 +1818,7 @@ async def run_background(self, ctx: _ExecutionContext) -> dict[str, Any]: initial_agent_reference=ctx.agent_reference, agent_session_id=ctx.agent_session_id, conversation_id=ctx.conversation_id, - chat_isolation_key=ctx.chat_isolation_key, + user_id_key=ctx.user_id, ) # Register so GET can observe in-flight state diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_runtime_state.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_runtime_state.py index dfe14e77abf5..66faac3eb560 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_runtime_state.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_runtime_state.py @@ -112,24 +112,24 @@ async def mark_deleted(self, response_id: str) -> None: self._deleted_response_ids.add(response_id) @staticmethod - def check_chat_isolation(stored_key: str | None, request_chat_key: str | None) -> bool: - """Check whether the request chat key matches the creation-time key. + def check_user_isolation(stored_key: str | None, request_user_id_key: str | None) -> bool: + """Check whether the request user ID matches the creation-time key. Returns ``True`` if the request is allowed, ``False`` if it should be - rejected as not-found to prevent cross-chat information leakage. + rejected as not-found to prevent cross-user information leakage. No enforcement when the response was created without a key (backward compat). - :param stored_key: The chat isolation key stored at creation time, or ``None``. + :param stored_key: The user ID key stored at creation time, or ``None``. :type stored_key: str | None - :param request_chat_key: The chat key from the incoming request, or ``None``. - :type request_chat_key: str | None + :param request_user_id_key: The user ID key from the incoming request, or ``None``. + :type request_user_id_key: str | None :return: ``True`` if allowed, ``False`` if isolation mismatch. :rtype: bool """ if stored_key is None: return True # No enforcement when created without a key - return stored_key == request_chat_key + return stored_key == request_user_id_key async def get_input_items(self, response_id: str) -> list[OutputItem]: """Retrieve the full input item chain for a response, including ancestors. diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/runtime.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/runtime.py index 15dbf69f4810..b5fe56b32387 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/runtime.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/runtime.py @@ -101,7 +101,7 @@ def __init__( initial_agent_reference: AgentReference | dict[str, Any] | None = None, agent_session_id: str | None = None, conversation_id: str | None = None, - chat_isolation_key: str | None = None, + user_id_key: str | None = None, ) -> None: self.response_id = response_id self.mode_flags = mode_flags @@ -123,7 +123,7 @@ def __init__( self.initial_agent_reference = initial_agent_reference or {} self.agent_session_id = agent_session_id self.conversation_id = conversation_id - self.chat_isolation_key = chat_isolation_key + self.user_id_key = user_id_key self.response_created_signal: asyncio.Event = asyncio.Event() self.response_failed_before_events: bool = False self.persistence_failed: bool = False diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_base.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_base.py index 83adfe6bed52..92da541e2ea8 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_base.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_base.py @@ -9,7 +9,7 @@ from ..models._generated import OutputItem, ResponseObject, ResponseStreamEvent if TYPE_CHECKING: - from .._response_context import IsolationContext + from .._response_context import PlatformContext @runtime_checkable @@ -18,7 +18,7 @@ class ResponseProviderProtocol(Protocol): Implementations provide response envelope storage plus input/history item lookup. - Every operation accepts an optional ``isolation`` parameter (S-018). + Every operation accepts an optional ``context`` parameter (S-018). Implementations MUST use it to partition data in multi-tenant deployments. When ``None``, the provider operates without tenant scoping (suitable for local development). @@ -30,7 +30,7 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Persist a new response envelope and optional input/history references. @@ -40,41 +40,41 @@ async def create_response( :type input_items: Iterable[OutputItem] | None :param history_item_ids: Optional history item IDs to link to the response. :type history_item_ids: Iterable[str] | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ - async def get_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> ResponseObject: + async def get_response(self, response_id: str, *, context: PlatformContext | None = None) -> ResponseObject: """Load one response envelope by ID. :param response_id: The unique identifier of the response to retrieve. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: The response envelope matching the given ID. :rtype: ~azure.ai.agentserver.responses.models._generated.ResponseObject :raises KeyError: If the response does not exist. """ ... - async def update_response(self, response: ResponseObject, *, isolation: IsolationContext | None = None) -> None: + async def update_response(self, response: ResponseObject, *, context: PlatformContext | None = None) -> None: """Persist an updated response envelope. :param response: The response envelope with updated fields to persist. :type response: ~azure.ai.agentserver.responses.models._generated.ResponseObject - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ - async def delete_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> None: + async def delete_response(self, response_id: str, *, context: PlatformContext | None = None) -> None: """Delete a response envelope by ID. :param response_id: The unique identifier of the response to delete. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None :raises KeyError: If the response does not exist. """ @@ -87,7 +87,7 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[OutputItem]: """Get response input/history items for one response ID using cursor pagination. @@ -101,22 +101,22 @@ async def get_input_items( :type after: str | None :param before: Cursor ID; only return items before this ID. :type before: str | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of output items matching the pagination criteria. :rtype: list[OutputItem] """ ... async def get_items( - self, item_ids: Iterable[str], *, isolation: IsolationContext | None = None + self, item_ids: Iterable[str], *, context: PlatformContext | None = None ) -> list[OutputItem | None]: """Get items by ID (missing IDs produce ``None`` entries). :param item_ids: The item identifiers to look up. :type item_ids: Iterable[str] - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of output items in the same order as *item_ids*; missing items are ``None``. :rtype: list[OutputItem | None] """ @@ -128,7 +128,7 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[str]: """Get history item IDs for a conversation chain scope. @@ -138,8 +138,8 @@ async def get_history_item_ids( :type conversation_id: str | None :param limit: Maximum number of history item IDs to return. :type limit: int - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of history item IDs within the given scope. :rtype: list[str] """ @@ -160,7 +160,7 @@ async def save_stream_events( response_id: str, events: list[ResponseStreamEvent], *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Persist the complete ordered list of SSE events for a response. @@ -171,8 +171,8 @@ async def save_stream_events( :type response_id: str :param events: Ordered list of event instances to persist. :type events: list[ResponseStreamEvent] - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ @@ -180,14 +180,14 @@ async def get_stream_events( self, response_id: str, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[ResponseStreamEvent] | None: """Retrieve the persisted SSE events for a response. :param response_id: The unique identifier of the response whose events to retrieve. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: The ordered list of event instances, or ``None`` if not found. :rtype: list[ResponseStreamEvent] | None """ @@ -196,7 +196,7 @@ async def delete_stream_events( self, response_id: str, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Delete persisted SSE events for a response. @@ -206,7 +206,7 @@ async def delete_stream_events( :param response_id: The unique identifier of the response whose events to remove. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_logging_policy.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_logging_policy.py index fefe8960038a..06ac956eb451 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_logging_policy.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_logging_policy.py @@ -17,11 +17,10 @@ from azure.ai.agentserver.core._platform_headers import ( # pylint: disable=import-error,no-name-in-module APIM_REQUEST_ID, - CHAT_ISOLATION_KEY, CLIENT_REQUEST_ID, + FOUNDRY_CALL_ID, REQUEST_ID, TRACEPARENT, - USER_ISOLATION_KEY, ) from azure.core.pipeline import PipelineRequest, PipelineResponse from azure.core.pipeline.policies import AsyncHTTPPolicy @@ -95,8 +94,7 @@ async def send(self, request: PipelineRequest) -> PipelineResponse: client_request_id = http_request.headers.get(CLIENT_REQUEST_ID, "") traceparent = http_request.headers.get(TRACEPARENT, "") - has_user_isolation_key = USER_ISOLATION_KEY in http_request.headers - has_chat_isolation_key = CHAT_ISOLATION_KEY in http_request.headers + has_call_id = FOUNDRY_CALL_ID in http_request.headers logger.debug( "Foundry storage %s %s starting " @@ -136,7 +134,7 @@ async def send(self, request: PipelineRequest) -> PipelineResponse: "Foundry storage %s %s -> %d (%.1fms, " "x-ms-client-request-id=%s, traceparent=%s, " "x-request-id=%s, apim-request-id=%s, " - "has_user_isolation_key=%s, has_chat_isolation_key=%s)", + "has_call_id=%s)", method, url, status_code, @@ -145,8 +143,7 @@ async def send(self, request: PipelineRequest) -> PipelineResponse: traceparent, x_request_id, apim_request_id, - has_user_isolation_key, - has_chat_isolation_key, + has_call_id, ) return response diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_provider.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_provider.py index c37942e2e83c..5ef23ccc9630 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_provider.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_foundry_provider.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, Callable, Iterable from urllib.parse import quote as _url_quote -from azure.ai.agentserver.core._platform_headers import CHAT_ISOLATION_KEY, PLATFORM_ERROR_TAG, USER_ISOLATION_KEY # pylint: disable=import-error,no-name-in-module +from azure.ai.agentserver.core._platform_headers import FOUNDRY_CALL_ID, PLATFORM_ERROR_TAG # pylint: disable=import-error,no-name-in-module from azure.core import AsyncPipelineClient from azure.core.credentials_async import AsyncTokenCredential from azure.core.exceptions import ServiceRequestError, ServiceResponseError @@ -31,7 +31,7 @@ from ._foundry_settings import FoundryStorageSettings if TYPE_CHECKING: - from .._response_context import IsolationContext + from .._response_context import PlatformContext _FOUNDRY_TOKEN_SCOPE = "https://ai.azure.com/.default" _JSON_CONTENT_TYPE = "application/json; charset=utf-8" @@ -68,20 +68,24 @@ def _encode(value: str) -> str: return _url_quote(value, safe="") -def _apply_isolation_headers(request: HttpRequest, isolation: IsolationContext | None) -> None: - """Add isolation key headers to an outbound HTTP request when present. +def _apply_platform_headers(request: HttpRequest, context: PlatformContext | None) -> None: + """Forward the per-request call ID on an outbound HTTP request when present. + + On protocol version ``2.0.0`` the container forwards the per-request call ID + (``x-agent-foundry-call-id``) on outbound calls to Foundry platform services; + the storage service resolves the caller context server-side from it. The + ``x-agent-user-id`` header is **not** forwarded — it is not accepted/trusted + by 1P services and is used only for container-side state partitioning. :param request: The outbound HTTP request to modify. :type request: ~azure.core.rest.HttpRequest - :param isolation: Isolation context containing user/chat keys, or ``None``. - :type isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :param context: Platform context containing the call ID, or ``None``. + :type context: ~azure.ai.agentserver.responses.PlatformContext | None """ - if isolation is None: + if context is None: return - if isolation.user_key is not None: - request.headers[USER_ISOLATION_KEY] = isolation.user_key - if isolation.chat_key is not None: - request.headers[CHAT_ISOLATION_KEY] = isolation.chat_key + if context.call_id is not None: + request.headers[FOUNDRY_CALL_ID] = context.call_id class FoundryStorageProvider: @@ -202,7 +206,7 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Persist a new response with its associated input items and history. @@ -212,23 +216,23 @@ async def create_response( :type input_items: Iterable[OutputItem] | None :param history_item_ids: Item IDs from the prior conversation turn, if any. :type history_item_ids: Iterable[str] | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :raises FoundryApiError: On non-success HTTP response. """ body = serialize_create_request(response, input_items, history_item_ids) url = self._settings.build_url("responses") request = HttpRequest("POST", url, content=body, headers={"Content-Type": _JSON_CONTENT_TYPE}) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) await self._send_storage_request(request) - async def get_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> ResponseObject: + async def get_response(self, response_id: str, *, context: PlatformContext | None = None) -> ResponseObject: """Retrieve a stored response by its ID. :param response_id: The response identifier. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: The deserialized :class:`ResponseObject` model. :rtype: ResponseObject :raises FoundryResourceNotFoundError: If the response does not exist. @@ -236,17 +240,17 @@ async def get_response(self, response_id: str, *, isolation: IsolationContext | """ url = self._settings.build_url(f"responses/{_encode(response_id)}") request = HttpRequest("GET", url) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) http_resp = await self._send_storage_request(request) return deserialize_response(http_resp.text()) - async def update_response(self, response: ResponseObject, *, isolation: IsolationContext | None = None) -> None: + async def update_response(self, response: ResponseObject, *, context: PlatformContext | None = None) -> None: """Persist an updated response snapshot. :param response: The updated response model. Must contain a valid ``id`` field. :type response: ResponseObject - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :raises FoundryResourceNotFoundError: If the response does not exist. :raises FoundryApiError: On other non-success HTTP response. """ @@ -254,22 +258,22 @@ async def update_response(self, response: ResponseObject, *, isolation: Isolatio body = serialize_response(response) url = self._settings.build_url(f"responses/{_encode(response_id)}") request = HttpRequest("POST", url, content=body, headers={"Content-Type": _JSON_CONTENT_TYPE}) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) await self._send_storage_request(request) - async def delete_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> None: + async def delete_response(self, response_id: str, *, context: PlatformContext | None = None) -> None: """Delete a stored response and its associated data. :param response_id: The response identifier. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :raises FoundryResourceNotFoundError: If the response does not exist. :raises FoundryApiError: On other non-success HTTP response. """ url = self._settings.build_url(f"responses/{_encode(response_id)}") request = HttpRequest("DELETE", url) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) await self._send_storage_request(request) async def get_input_items( @@ -280,7 +284,7 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[OutputItem]: """Retrieve a page of input items for the given response. @@ -294,8 +298,8 @@ async def get_input_items( :type after: str | None :param before: End the page before this item ID (cursor-based pagination). :type before: str | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of deserialized :class:`OutputItem` instances. :rtype: list[OutputItem] :raises FoundryResourceNotFoundError: If the response does not exist. @@ -312,12 +316,12 @@ async def get_input_items( url = self._settings.build_url(f"responses/{_encode(response_id)}/input_items", **extra) request = HttpRequest("GET", url) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) http_resp = await self._send_storage_request(request) return deserialize_paged_items(http_resp.text()) async def get_items( - self, item_ids: Iterable[str], *, isolation: IsolationContext | None = None + self, item_ids: Iterable[str], *, context: PlatformContext | None = None ) -> list[OutputItem | None]: """Retrieve multiple items by their IDs in a single batch request. @@ -326,8 +330,8 @@ async def get_items( :param item_ids: The item identifiers to retrieve. :type item_ids: Iterable[str] - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of :class:`OutputItem` instances (or ``None`` for missing items). :rtype: list[OutputItem | None] :raises FoundryApiError: On non-success HTTP response. @@ -336,7 +340,7 @@ async def get_items( body = serialize_batch_request(ids) url = self._settings.build_url("items/batch/retrieve") request = HttpRequest("POST", url, content=body, headers={"Content-Type": _JSON_CONTENT_TYPE}) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) http_resp = await self._send_storage_request(request) return deserialize_items_array(http_resp.text()) @@ -346,7 +350,7 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[str]: """Retrieve the ordered list of item IDs that form the conversation history. @@ -356,8 +360,8 @@ async def get_history_item_ids( :type conversation_id: str | None :param limit: Maximum number of item IDs to return. :type limit: int - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: Ordered list of item ID strings. :rtype: list[str] :raises FoundryApiError: On non-success HTTP response. @@ -370,6 +374,6 @@ async def get_history_item_ids( url = self._settings.build_url("history/item_ids", **extra) request = HttpRequest("GET", url) - _apply_isolation_headers(request, isolation) + _apply_platform_headers(request, context) http_resp = await self._send_storage_request(request) return deserialize_history_ids(http_resp.text()) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_memory.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_memory.py index 03bce1659b30..8e8969922d6f 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_memory.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/store/_memory.py @@ -11,7 +11,7 @@ from datetime import datetime, timedelta, timezone from typing import Any, AsyncIterator, Dict, Iterable -from .._response_context import IsolationContext +from .._response_context import PlatformContext from ..models._generated import OutputItem, ResponseObject, ResponseStreamEvent from ..models._helpers import get_conversation_id from ..models.runtime import ResponseExecution, ResponseModeFlags, ResponseStatus, StreamEventRecord, StreamReplayState @@ -76,7 +76,7 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Persist a new response envelope and optional input/history references. @@ -89,8 +89,8 @@ async def create_response( :type input_items: Iterable[OutputItem] | None :param history_item_ids: Optional history item IDs to link to the response. :type history_item_ids: Iterable[str] | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None :raises ValueError: If a non-deleted response with the same ID already exists. """ @@ -128,13 +128,13 @@ async def create_response( if conversation_id is not None: self._conversation_responses[conversation_id].append(response_id) - async def get_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> ResponseObject: + async def get_response(self, response_id: str, *, context: PlatformContext | None = None) -> ResponseObject: """Retrieve one response envelope by identifier. :param response_id: The unique identifier of the response to retrieve. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A deep copy of the stored response envelope. :rtype: ~azure.ai.agentserver.responses.models._generated.Response :raises KeyError: If the response does not exist or has been deleted. @@ -145,7 +145,7 @@ async def get_response(self, response_id: str, *, isolation: IsolationContext | raise KeyError(f"response '{response_id}' not found") return deepcopy(entry.response) - async def update_response(self, response: ResponseObject, *, isolation: IsolationContext | None = None) -> None: + async def update_response(self, response: ResponseObject, *, context: PlatformContext | None = None) -> None: """Update a stored response envelope. Replaces the stored response with a deep copy and updates @@ -153,8 +153,8 @@ async def update_response(self, response: ResponseObject, *, isolation: Isolatio :param response: The response envelope with updated fields. :type response: ~azure.ai.agentserver.responses.models._generated.Response - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None :raises KeyError: If the response does not exist or has been deleted. """ @@ -168,15 +168,15 @@ async def update_response(self, response: ResponseObject, *, isolation: Isolatio entry.execution.set_response_snapshot(deepcopy(response)) entry.output_item_ids = self._store_output_items_unlocked(response) - async def delete_response(self, response_id: str, *, isolation: IsolationContext | None = None) -> None: + async def delete_response(self, response_id: str, *, context: PlatformContext | None = None) -> None: """Delete a stored response envelope by identifier. Marks the entry as deleted and clears the response payload. :param response_id: The unique identifier of the response to delete. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None :raises KeyError: If the response does not exist or has already been deleted. """ @@ -195,7 +195,7 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[OutputItem]: """Retrieve input/history items for a response with basic cursor paging. @@ -212,8 +212,8 @@ async def get_input_items( :type after: str | None :param before: Cursor ID; only return items before this ID. :type before: str | None - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of input/history items matching the pagination criteria. :rtype: list[OutputItem] :raises KeyError: If the response does not exist. @@ -254,7 +254,7 @@ async def get_items( self, item_ids: Iterable[str], *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[OutputItem | None]: """Retrieve items by ID, preserving request order. @@ -262,8 +262,8 @@ async def get_items( :param item_ids: The item identifiers to look up. :type item_ids: Iterable[str] - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of output items in the same order as *item_ids*; missing items are ``None``. :rtype: list[OutputItem | None] """ @@ -278,7 +278,7 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[str]: """Resolve history item IDs from previous response and/or conversation scope. @@ -291,8 +291,8 @@ async def get_history_item_ids( :type conversation_id: str | None :param limit: Maximum number of history item IDs to return. :type limit: int - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A list of history item IDs within the given scope. :rtype: list[str] """ @@ -518,7 +518,7 @@ async def save_stream_events( response_id: str, events: list[ResponseStreamEvent], *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Persist the complete ordered list of SSE events for ``response_id``. @@ -529,8 +529,8 @@ async def save_stream_events( :type response_id: str :param events: Ordered list of event instances. :type events: list[ResponseStreamEvent] - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ now = datetime.now(timezone.utc) @@ -546,7 +546,7 @@ async def get_stream_events( self, response_id: str, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> list[ResponseStreamEvent] | None: """Retrieve the persisted SSE events for ``response_id``, excluding expired events. @@ -555,8 +555,8 @@ async def get_stream_events( :param response_id: The unique identifier of the response whose events to retrieve. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :returns: A deep-copied list of event instances, or ``None`` if not found. :rtype: list[ResponseStreamEvent] | None """ @@ -574,14 +574,14 @@ async def delete_stream_events( self, response_id: str, *, - isolation: IsolationContext | None = None, + context: PlatformContext | None = None, ) -> None: """Delete persisted SSE events for ``response_id``. :param response_id: The unique identifier of the response whose events to remove. :type response_id: str - :keyword isolation: Isolation context for multi-tenant partitioning. - :paramtype isolation: ~azure.ai.agentserver.responses.IsolationContext | None + :keyword context: Platform context for multi-tenant partitioning. + :paramtype context: ~azure.ai.agentserver.responses.PlatformContext | None :rtype: None """ async with self._locked(): diff --git a/sdk/agentserver/azure-ai-agentserver-responses/cspell.json b/sdk/agentserver/azure-ai-agentserver-responses/cspell.json index 69f59055e4b8..bac7572be985 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/cspell.json +++ b/sdk/agentserver/azure-ai-agentserver-responses/cspell.json @@ -23,7 +23,8 @@ "myproj", "myhost", "bkey", - "bval" + "bval", + "xhigh" ], "ignorePaths": [ "*.csv", diff --git a/sdk/agentserver/azure-ai-agentserver-responses/pyproject.toml b/sdk/agentserver/azure-ai-agentserver-responses/pyproject.toml index 2e51d7728bfd..8d86e6e143a1 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/pyproject.toml +++ b/sdk/agentserver/azure-ai-agentserver-responses/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ "Programming Language :: Python :: 3.14", ] dependencies = [ - "azure-ai-agentserver-core>=2.0.0b4", + "azure-ai-agentserver-core>=2.0.0b7", "azure-core>=1.30.0", "isodate>=0.6.1", "aiohttp>=3.10.0,<4.0.0", @@ -44,7 +44,7 @@ exclude = [ "doc*", "azure", "azure.ai", - "scripts*", + "_scripts*", ] [tool.setuptools.package-data] @@ -69,3 +69,4 @@ azure-sdk-tools = { path = "../../../eng/tools/azure-sdk-tools" } [tool.azure-sdk-build] verifytypes = false latestdependency = false +mindependency = false diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_bg_isolation_propagation.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_bg_isolation_propagation.py index 0f5d7887692f..d9ce0b6f30d8 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_bg_isolation_propagation.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_bg_isolation_propagation.py @@ -1,15 +1,15 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. -"""Contract test: isolation keys propagate to update_response in bg non-stream finalization. +"""Contract test: platform context propagates to update_response in bg non-stream finalization. -When a background non-stream response is created with isolation headers -(``x-agent-user-isolation-key`` / ``x-agent-chat-isolation-key``), the +When a background non-stream response is created with platform identity headers +(``x-agent-user-id`` / ``x-agent-foundry-call-id``), the finalization ``update_response`` call in :func:`_run_background_non_stream` -must forward the same isolation context. A missing ``isolation=`` kwarg +must forward the same platform context. A missing ``context=`` kwarg causes Foundry storage to return 404 (response exists in a different partition) and the response is stuck at ``in_progress`` forever. -Regression test for: missing isolation on update_response in +Regression test for: missing context on update_response in _run_background_non_stream finally block. """ @@ -20,7 +20,7 @@ from starlette.testclient import TestClient from azure.ai.agentserver.responses import ResponsesAgentServerHost -from azure.ai.agentserver.responses._response_context import IsolationContext +from azure.ai.agentserver.responses._response_context import PlatformContext from azure.ai.agentserver.responses.models._generated import OutputItem, ResponseObject from azure.ai.agentserver.responses.store._memory import InMemoryResponseProvider from azure.ai.agentserver.responses.streaming import ResponseEventStream @@ -30,12 +30,12 @@ # ─── Recording provider ─────────────────────────────────── class _RecordingProvider: - """Wraps InMemoryResponseProvider and records isolation kwargs on every call.""" + """Wraps InMemoryResponseProvider and records context kwargs on every call.""" def __init__(self) -> None: self._inner = InMemoryResponseProvider() - self.create_calls: list[IsolationContext | None] = [] - self.update_calls: list[IsolationContext | None] = [] + self.create_calls: list[PlatformContext | None] = [] + self.update_calls: list[PlatformContext | None] = [] async def create_response( self, @@ -43,20 +43,20 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: Any = None, + context: Any = None, ) -> None: - self.create_calls.append(isolation) - await self._inner.create_response(response, input_items, history_item_ids, isolation=isolation) + self.create_calls.append(context) + await self._inner.create_response(response, input_items, history_item_ids, context=context) - async def get_response(self, response_id: str, *, isolation: Any = None) -> ResponseObject: - return await self._inner.get_response(response_id, isolation=isolation) + async def get_response(self, response_id: str, *, context: Any = None) -> ResponseObject: + return await self._inner.get_response(response_id, context=context) - async def update_response(self, response: ResponseObject, *, isolation: Any = None) -> None: - self.update_calls.append(isolation) - await self._inner.update_response(response, isolation=isolation) + async def update_response(self, response: ResponseObject, *, context: Any = None) -> None: + self.update_calls.append(context) + await self._inner.update_response(response, context=context) - async def delete_response(self, response_id: str, *, isolation: Any = None) -> None: - await self._inner.delete_response(response_id, isolation=isolation) + async def delete_response(self, response_id: str, *, context: Any = None) -> None: + await self._inner.delete_response(response_id, context=context) async def get_input_items( self, @@ -66,17 +66,17 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem]: - return await self._inner.get_input_items(response_id, limit, ascending, after, before, isolation=isolation) + return await self._inner.get_input_items(response_id, limit, ascending, after, before, context=context) async def get_items( self, item_ids: Iterable[str], *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem | None]: - return await self._inner.get_items(item_ids, isolation=isolation) + return await self._inner.get_items(item_ids, context=context) async def get_history_item_ids( self, @@ -84,10 +84,10 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: Any = None, + context: Any = None, ) -> list[str]: return await self._inner.get_history_item_ids( - previous_response_id, conversation_id, limit, isolation=isolation + previous_response_id, conversation_id, limit, context=context ) @@ -136,16 +136,16 @@ def _is_terminal() -> bool: # ─── Tests ──────────────────────────────────────────────── class TestBgNonStreamIsolationPropagation: - """Verify that isolation keys reach update_response during bg non-stream finalization.""" + """Verify that the platform context reaches update_response during bg non-stream finalization.""" def test_update_response_receives_isolation_with_both_keys(self) -> None: - """Both user and chat isolation keys must be forwarded to update_response.""" + """Both user ID and call ID must be forwarded to update_response.""" provider = _RecordingProvider() client = _build_client(provider) headers = { - "x-agent-user-isolation-key": "user_123", - "x-agent-chat-isolation-key": "chat_456", + "x-agent-user-id": "user_123", + "x-agent-foundry-call-id": "call_456", } r = client.post( "/responses", @@ -157,27 +157,27 @@ def test_update_response_receives_isolation_with_both_keys(self) -> None: _wait_for_terminal(client, response_id, headers=headers) - # FR-003: create_response at response.created time should have isolation + # FR-003: create_response at response.created time should have platform context assert len(provider.create_calls) >= 1 create_iso = provider.create_calls[0] - assert isinstance(create_iso, IsolationContext) - assert create_iso.user_key == "user_123" - assert create_iso.chat_key == "chat_456" + assert isinstance(create_iso, PlatformContext) + assert create_iso.user_id_key == "user_123" + assert create_iso.call_id == "call_456" - # Finalization: update_response must also have isolation + # Finalization: update_response must also have platform context assert len(provider.update_calls) >= 1, "update_response was never called" update_iso = provider.update_calls[0] - assert update_iso is not None, "update_response called without isolation (was None)" - assert isinstance(update_iso, IsolationContext) - assert update_iso.user_key == "user_123" - assert update_iso.chat_key == "chat_456" + assert update_iso is not None, "update_response called without context (was None)" + assert isinstance(update_iso, PlatformContext) + assert update_iso.user_id_key == "user_123" + assert update_iso.call_id == "call_456" def test_update_response_receives_isolation_with_user_key_only(self) -> None: - """Only user isolation key — should still propagate.""" + """Only user ID — should still propagate.""" provider = _RecordingProvider() client = _build_client(provider) - headers = {"x-agent-user-isolation-key": "user_only"} + headers = {"x-agent-user-id": "user_only"} r = client.post( "/responses", json={"model": "m", "input": "hi", "stream": False, "store": True, "background": True}, @@ -191,11 +191,11 @@ def test_update_response_receives_isolation_with_user_key_only(self) -> None: assert len(provider.update_calls) >= 1, "update_response was never called" update_iso = provider.update_calls[0] assert update_iso is not None - assert isinstance(update_iso, IsolationContext) - assert update_iso.user_key == "user_only" + assert isinstance(update_iso, PlatformContext) + assert update_iso.user_id_key == "user_only" def test_update_response_without_isolation_headers_passes_none_keys(self) -> None: - """No isolation headers — isolation context has None keys (but is still passed).""" + """No platform identity headers — platform context has None keys (but is still passed).""" provider = _RecordingProvider() client = _build_client(provider) @@ -210,7 +210,7 @@ def test_update_response_without_isolation_headers_passes_none_keys(self) -> Non assert len(provider.update_calls) >= 1, "update_response was never called" update_iso = provider.update_calls[0] - # Isolation context is passed but keys are None when headers absent - assert isinstance(update_iso, IsolationContext) - assert update_iso.user_key is None - assert update_iso.chat_key is None + # Platform context is passed but fields are None when headers absent + assert isinstance(update_iso, PlatformContext) + assert update_iso.user_id_key is None + assert update_iso.call_id is None diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_delete_eviction_race.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_delete_eviction_race.py index f7021fe6ede5..8beea7e0adef 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_delete_eviction_race.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_delete_eviction_race.py @@ -149,10 +149,10 @@ def test_delete_after_natural_eviction_succeeds_via_provider(self, monkeypatch: _fallback_delete_called = False _original_provider_delete = _ResponseEndpointHandler._provider_delete_response - async def _recording_fallback(self_handler: Any, response_id: str, isolation: Any, headers: Any) -> Any: + async def _recording_fallback(self_handler: Any, response_id: str, context: Any, headers: Any) -> Any: nonlocal _fallback_delete_called _fallback_delete_called = True - return await _original_provider_delete(self_handler, response_id, isolation, headers) + return await _original_provider_delete(self_handler, response_id, context, headers) monkeypatch.setattr(_ResponseEndpointHandler, "_provider_delete_response", _recording_fallback) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_eager_eviction.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_eager_eviction.py index a4bc8a50c5ad..7ae133e1ef4f 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_eager_eviction.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_eager_eviction.py @@ -390,14 +390,14 @@ async def test_try_evict_removes_record_so_isolation_falls_to_storage(self) -> N response_id=rid, mode_flags=ResponseModeFlags(stream=False, store=True, background=False), status="completed", - chat_isolation_key="my_key", + user_id_key="my_key", ) await state.add(record) # In-flight: static helper enforces isolation via the record's key - assert _RuntimeState.check_chat_isolation(record.chat_isolation_key, "my_key") is True - assert _RuntimeState.check_chat_isolation(record.chat_isolation_key, "wrong") is False - assert _RuntimeState.check_chat_isolation(record.chat_isolation_key, None) is False + assert _RuntimeState.check_user_isolation(record.user_id_key, "my_key") is True + assert _RuntimeState.check_user_isolation(record.user_id_key, "wrong") is False + assert _RuntimeState.check_user_isolation(record.user_id_key, None) is False await state.try_evict(rid) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_persistence_failure.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_persistence_failure.py index 7b18a651ffaa..7c969ef2d79f 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_persistence_failure.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_persistence_failure.py @@ -63,25 +63,25 @@ async def create_response( input_items: Iterable[Any] | None, history_item_ids: Iterable[str] | None, *, - isolation: Any = None, + context: Any = None, ) -> None: self.create_called = True if self.fail_on_create: raise RuntimeError("Simulated storage failure") - return await self._inner.create_response(response, input_items, history_item_ids, isolation=isolation) + return await self._inner.create_response(response, input_items, history_item_ids, context=context) - async def update_response(self, response: Any, *, isolation: Any = None) -> None: + async def update_response(self, response: Any, *, context: Any = None) -> None: self.update_called = True if self.fail_on_update: raise RuntimeError("Simulated storage failure") - return await self._inner.update_response(response, isolation=isolation) + return await self._inner.update_response(response, context=context) - async def get_response(self, response_id: str, *, isolation: Any = None) -> Any: - return await self._inner.get_response(response_id, isolation=isolation) + async def get_response(self, response_id: str, *, context: Any = None) -> Any: + return await self._inner.get_response(response_id, context=context) - async def delete_response(self, response_id: str, *, isolation: Any = None) -> None: + async def delete_response(self, response_id: str, *, context: Any = None) -> None: self.delete_called = True - return await self._inner.delete_response(response_id, isolation=isolation) + return await self._inner.delete_response(response_id, context=context) async def get_history_item_ids( self, @@ -89,9 +89,9 @@ async def get_history_item_ids( before: str | None, limit: int, *, - isolation: Any = None, + context: Any = None, ) -> list[str] | None: - return await self._inner.get_history_item_ids(response_id, before, limit, isolation=isolation) + return await self._inner.get_history_item_ids(response_id, before, limit, context=context) async def get_input_items( self, @@ -99,23 +99,23 @@ async def get_input_items( *, limit: int = 100, ascending: bool = True, - isolation: Any = None, + context: Any = None, ) -> list[Any]: - return await self._inner.get_input_items(response_id, limit=limit, ascending=ascending, isolation=isolation) + return await self._inner.get_input_items(response_id, limit=limit, ascending=ascending, context=context) # ResponseStreamProviderProtocol delegation - async def save_stream_events(self, response_id: str, events: Any, *, isolation: Any = None) -> None: + async def save_stream_events(self, response_id: str, events: Any, *, context: Any = None) -> None: if hasattr(self._inner, "save_stream_events"): - return await self._inner.save_stream_events(response_id, events, isolation=isolation) + return await self._inner.save_stream_events(response_id, events, context=context) - async def get_stream_events(self, response_id: str, *, isolation: Any = None) -> Any: + async def get_stream_events(self, response_id: str, *, context: Any = None) -> Any: if hasattr(self._inner, "get_stream_events"): - return await self._inner.get_stream_events(response_id, isolation=isolation) + return await self._inner.get_stream_events(response_id, context=context) return None - async def delete_stream_events(self, response_id: str, *, isolation: Any = None) -> None: + async def delete_stream_events(self, response_id: str, *, context: Any = None) -> None: if hasattr(self._inner, "delete_stream_events"): - return await self._inner.delete_stream_events(response_id, isolation=isolation) + return await self._inner.delete_stream_events(response_id, context=context) def _make_app_with_failing_provider( diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_event_lifecycle.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_event_lifecycle.py index c245b23c146c..4b692142b993 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_event_lifecycle.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_event_lifecycle.py @@ -53,18 +53,18 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: Any = None, + context: Any = None, ) -> None: - await self._inner.create_response(response, input_items, history_item_ids, isolation=isolation) + await self._inner.create_response(response, input_items, history_item_ids, context=context) - async def get_response(self, response_id: str, *, isolation: Any = None) -> ResponseObject: - return await self._inner.get_response(response_id, isolation=isolation) + async def get_response(self, response_id: str, *, context: Any = None) -> ResponseObject: + return await self._inner.get_response(response_id, context=context) - async def update_response(self, response: ResponseObject, *, isolation: Any = None) -> None: - await self._inner.update_response(response, isolation=isolation) + async def update_response(self, response: ResponseObject, *, context: Any = None) -> None: + await self._inner.update_response(response, context=context) - async def delete_response(self, response_id: str, *, isolation: Any = None) -> None: - await self._inner.delete_response(response_id, isolation=isolation) + async def delete_response(self, response_id: str, *, context: Any = None) -> None: + await self._inner.delete_response(response_id, context=context) async def get_input_items( self, @@ -74,17 +74,17 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem]: - return await self._inner.get_input_items(response_id, limit, ascending, after, before, isolation=isolation) + return await self._inner.get_input_items(response_id, limit, ascending, after, before, context=context) async def get_items( self, item_ids: Iterable[str], *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem | None]: - return await self._inner.get_items(item_ids, isolation=isolation) + return await self._inner.get_items(item_ids, context=context) async def get_history_item_ids( self, @@ -92,9 +92,9 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: Any = None, + context: Any = None, ) -> list[str]: - return await self._inner.get_history_item_ids(previous_response_id, conversation_id, limit, isolation=isolation) + return await self._inner.get_history_item_ids(previous_response_id, conversation_id, limit, context=context) # ──────────────────────────────────────── diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_provider_fallback.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_provider_fallback.py index dbb8813c078d..e7f7008594dd 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_provider_fallback.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_stream_provider_fallback.py @@ -49,18 +49,18 @@ async def create_response( input_items: Iterable[OutputItem] | None, history_item_ids: Iterable[str] | None, *, - isolation: Any = None, + context: Any = None, ) -> None: - await self._inner.create_response(response, input_items, history_item_ids, isolation=isolation) + await self._inner.create_response(response, input_items, history_item_ids, context=context) - async def get_response(self, response_id: str, *, isolation: Any = None) -> ResponseObject: - return await self._inner.get_response(response_id, isolation=isolation) + async def get_response(self, response_id: str, *, context: Any = None) -> ResponseObject: + return await self._inner.get_response(response_id, context=context) - async def update_response(self, response: ResponseObject, *, isolation: Any = None) -> None: - await self._inner.update_response(response, isolation=isolation) + async def update_response(self, response: ResponseObject, *, context: Any = None) -> None: + await self._inner.update_response(response, context=context) - async def delete_response(self, response_id: str, *, isolation: Any = None) -> None: - await self._inner.delete_response(response_id, isolation=isolation) + async def delete_response(self, response_id: str, *, context: Any = None) -> None: + await self._inner.delete_response(response_id, context=context) async def get_input_items( self, @@ -70,7 +70,7 @@ async def get_input_items( after: str | None = None, before: str | None = None, *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem]: return await self._inner.get_input_items( response_id, @@ -78,16 +78,16 @@ async def get_input_items( ascending, after, before, - isolation=isolation, + context=context, ) async def get_items( self, item_ids: Iterable[str], *, - isolation: Any = None, + context: Any = None, ) -> list[OutputItem | None]: - return await self._inner.get_items(item_ids, isolation=isolation) + return await self._inner.get_items(item_ids, context=context) async def get_history_item_ids( self, @@ -95,13 +95,13 @@ async def get_history_item_ids( conversation_id: str | None, limit: int, *, - isolation: Any = None, + context: Any = None, ) -> list[str]: return await self._inner.get_history_item_ids( previous_response_id, conversation_id, limit, - isolation=isolation, + context=context, ) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_streaming_request_context.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_streaming_request_context.py new file mode 100644 index 000000000000..12c25e8d529f --- /dev/null +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_streaming_request_context.py @@ -0,0 +1,93 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. +"""Contract test: the platform request context is available inside streaming handlers. + +For streaming requests the registered handler does not run during +``handle_create``; it runs lazily while Starlette iterates the +``StreamingResponse`` body. The request context bound in ``handle_create`` is +reset in its ``finally`` block before that iteration begins, so the streaming +body must re-establish the platform context itself. Otherwise +``get_request_context()`` returns the empty context inside any streaming +handler and the per-request ``x-agent-foundry-call-id`` / ``x-agent-user-id`` +cannot be forwarded on raw outbound 1P calls (protocol 2.0.0). + +Regression test for: request context not re-established for the streaming body. +""" + +from __future__ import annotations + +from typing import Any + +from starlette.testclient import TestClient + +from azure.ai.agentserver.core import get_request_context +from azure.ai.agentserver.responses import ResponsesAgentServerHost +from azure.ai.agentserver.responses.store._memory import InMemoryResponseProvider +from azure.ai.agentserver.responses.streaming import ResponseEventStream + + +def _build_capturing_client(captured: dict[str, Any]) -> TestClient: + def _capturing_handler(request: Any, context: Any, cancellation_signal: Any) -> Any: + async def _events(): + # This runs while Starlette iterates the streaming body, AFTER + # handle_create returned and reset its own request context. + rc = get_request_context() + captured["call_id"] = rc.call_id + captured["user_id"] = rc.user_id + captured["session_id"] = rc.session_id + + stream = ResponseEventStream( + response_id=context.response_id, model=getattr(request, "model", None) + ) + yield stream.emit_created() + yield stream.emit_completed() + + return _events() + + app = ResponsesAgentServerHost(store=InMemoryResponseProvider()) + app.response_handler(_capturing_handler) + return TestClient(app) + + +class TestStreamingRequestContext: + """The platform context must be visible inside streaming handler bodies.""" + + def test_streaming_handler_sees_call_id_and_user_id(self) -> None: + captured: dict[str, Any] = {} + client = _build_capturing_client(captured) + + headers = { + "x-agent-user-id": "user_123", + "x-agent-foundry-call-id": "call_456", + } + with client.stream( + "POST", + "/responses", + json={"model": "m", "input": "hi", "stream": True, "store": False}, + headers=headers, + ) as r: + assert r.status_code == 200 + # Force the SSE body to iterate fully so the handler runs. + for _ in r.iter_lines(): + pass + + assert captured.get("call_id") == "call_456" + assert captured.get("user_id") == "user_123" + + def test_streaming_handler_without_headers_sees_empty_context(self) -> None: + captured: dict[str, Any] = {} + client = _build_capturing_client(captured) + + with client.stream( + "POST", + "/responses", + json={"model": "m", "input": "hi", "stream": True, "store": False}, + ) as r: + assert r.status_code == 200 + for _ in r.iter_lines(): + pass + + # No identity headers → context fields are None (but the handler still ran). + assert "call_id" in captured + assert captured.get("call_id") is None + assert captured.get("user_id") is None diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_chat_isolation_enforcement.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_user_isolation_enforcement.py similarity index 88% rename from sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_chat_isolation_enforcement.py rename to sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_user_isolation_enforcement.py index c472306c1c37..745faaf39563 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_chat_isolation_enforcement.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_user_isolation_enforcement.py @@ -1,11 +1,11 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. -"""Contract tests for chat isolation key enforcement across all endpoints. +"""Contract tests for user ID (user isolation) enforcement across all endpoints. -When a response is created with an ``x-agent-chat-isolation-key`` header, +When a response is created with an ``x-agent-user-id`` header, all subsequent GET, Cancel, DELETE, and InputItems requests must include the same key. Mismatched or missing keys return an indistinguishable 404 -to prevent cross-chat information leakage. +to prevent cross-user information leakage. Backward-compatible: no enforcement when the response was created without a key. """ @@ -41,7 +41,7 @@ def _make_client(handler=_noop_handler) -> TestClient: return TestClient(host) -def _create_response(client: TestClient, *, chat_key: str | None = None, **overrides) -> dict[str, Any]: +def _create_response(client: TestClient, *, user_id_key: str | None = None, **overrides) -> dict[str, Any]: """Create a response and return the parsed JSON body.""" payload = { "model": "m", @@ -49,8 +49,8 @@ def _create_response(client: TestClient, *, chat_key: str | None = None, **overr **overrides, } headers: dict[str, str] = {} - if chat_key is not None: - headers["x-agent-chat-isolation-key"] = chat_key + if user_id_key is not None: + headers["x-agent-user-id"] = user_id_key r = client.post("/responses", json=payload, headers=headers) assert r.status_code == 200, f"create failed: {r.status_code} {r.text}" return r.json() @@ -212,8 +212,8 @@ def _build_async_client(handler: Any) -> _AsyncAsgiClient: # ── GET with isolation ──────────────────────────────────── -class TestGetChatIsolation: - """GET /responses/{id} with chat isolation key enforcement. +class TestGetUserIsolation: + """GET /responses/{id} with user ID enforcement. In-flight isolation is enforced locally by the endpoint handler. After eviction, the Foundry storage provider enforces isolation @@ -223,16 +223,16 @@ class TestGetChatIsolation: """ def test_get_matching_key_returns_200(self) -> None: - """GET with the same chat key that was used at creation → 200.""" + """GET with the same user ID that was used at creation → 200.""" client = _make_client() - resp = _create_response(client, chat_key="key_A") - _wait_for_terminal(client, resp["id"], **{"x-agent-chat-isolation-key": "key_A"}) - r = client.get(f"/responses/{resp['id']}", headers={"x-agent-chat-isolation-key": "key_A"}) + resp = _create_response(client, user_id_key="key_A") + _wait_for_terminal(client, resp["id"], **{"x-agent-user-id": "key_A"}) + r = client.get(f"/responses/{resp['id']}", headers={"x-agent-user-id": "key_A"}) assert r.status_code == 200 @pytest.mark.asyncio async def test_get_mismatched_key_returns_404(self) -> None: - """GET with a different chat key on in-flight response → 404.""" + """GET with a different user ID on in-flight response → 404.""" handler = _make_cancellable_bg_handler() client = _build_async_client(handler) response_id = IdGenerator.new_response_id() @@ -246,14 +246,14 @@ async def test_get_mismatched_key_returns_404(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: await asyncio.wait_for(handler.started.wait(), timeout=5.0) r = await client.get( f"/responses/{response_id}", - headers={"x-agent-chat-isolation-key": "key_B"}, + headers={"x-agent-user-id": "key_B"}, ) assert r.status_code == 404 finally: @@ -267,7 +267,7 @@ async def test_get_mismatched_key_returns_404(self) -> None: @pytest.mark.asyncio async def test_get_missing_key_when_created_with_key_returns_404(self) -> None: - """GET without chat key when response was created with one → 404.""" + """GET without user ID when response was created with one → 404.""" handler = _make_cancellable_bg_handler() client = _build_async_client(handler) response_id = IdGenerator.new_response_id() @@ -281,7 +281,7 @@ async def test_get_missing_key_when_created_with_key_returns_404(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: @@ -303,7 +303,7 @@ def test_get_created_without_key_any_request_returns_200(self) -> None: resp = _create_response(client) _wait_for_terminal(client, resp["id"]) # With a key - r = client.get(f"/responses/{resp['id']}", headers={"x-agent-chat-isolation-key": "any_key"}) + r = client.get(f"/responses/{resp['id']}", headers={"x-agent-user-id": "any_key"}) assert r.status_code == 200 # Without a key r = client.get(f"/responses/{resp['id']}") @@ -325,14 +325,14 @@ async def test_get_404_error_body_is_standard(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: await asyncio.wait_for(handler.started.wait(), timeout=5.0) r = await client.get( f"/responses/{response_id}", - headers={"x-agent-chat-isolation-key": "key_WRONG"}, + headers={"x-agent-user-id": "key_WRONG"}, ) assert r.status_code == 404 body = r.json() @@ -351,8 +351,8 @@ async def test_get_404_error_body_is_standard(self) -> None: # ── DELETE with isolation ──────────────────────────────── -class TestDeleteChatIsolation: - """DELETE /responses/{id} with chat isolation key enforcement. +class TestDeleteUserIsolation: + """DELETE /responses/{id} with user ID enforcement. In-flight isolation is enforced locally; after eviction, isolation is enforced by the Foundry storage provider server-side. @@ -360,9 +360,9 @@ class TestDeleteChatIsolation: def test_delete_matching_key_returns_200(self) -> None: client = _make_client() - resp = _create_response(client, chat_key="key_A") - _wait_for_terminal(client, resp["id"], **{"x-agent-chat-isolation-key": "key_A"}) - r = client.delete(f"/responses/{resp['id']}", headers={"x-agent-chat-isolation-key": "key_A"}) + resp = _create_response(client, user_id_key="key_A") + _wait_for_terminal(client, resp["id"], **{"x-agent-user-id": "key_A"}) + r = client.delete(f"/responses/{resp['id']}", headers={"x-agent-user-id": "key_A"}) assert r.status_code == 200 @pytest.mark.asyncio @@ -380,7 +380,7 @@ async def test_delete_mismatched_key_returns_404(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: @@ -388,7 +388,7 @@ async def test_delete_mismatched_key_returns_404(self) -> None: r = await client.request( "DELETE", f"/responses/{response_id}", - headers={"x-agent-chat-isolation-key": "key_B"}, + headers={"x-agent-user-id": "key_B"}, ) assert r.status_code == 404 finally: @@ -415,7 +415,7 @@ async def test_delete_missing_key_when_created_with_key_returns_404(self) -> Non "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: @@ -435,8 +435,8 @@ async def test_delete_missing_key_when_created_with_key_returns_404(self) -> Non # ── CANCEL with isolation (async — needs real event loop) ── -class TestCancelChatIsolation: - """POST /responses/{id}/cancel with chat isolation key enforcement. +class TestCancelUserIsolation: + """POST /responses/{id}/cancel with user ID enforcement. Cancel tests must use async ASGI client because the handler runs as a background asyncio task that needs the event loop to start before the @@ -459,14 +459,14 @@ async def test_cancel_matching_key_succeeds(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: await asyncio.wait_for(handler.started.wait(), timeout=5.0) r = await client.post( f"/responses/{response_id}/cancel", - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) assert r.status_code == 200 finally: @@ -494,14 +494,14 @@ async def test_cancel_mismatched_key_returns_404(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: await asyncio.wait_for(handler.started.wait(), timeout=5.0) r = await client.post( f"/responses/{response_id}/cancel", - headers={"x-agent-chat-isolation-key": "key_B"}, + headers={"x-agent-user-id": "key_B"}, ) assert r.status_code == 404 finally: @@ -529,7 +529,7 @@ async def test_cancel_missing_key_when_created_with_key_returns_404(self) -> Non "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: @@ -549,8 +549,8 @@ async def test_cancel_missing_key_when_created_with_key_returns_404(self) -> Non # ── INPUT_ITEMS with isolation ──────────────────────────── -class TestInputItemsChatIsolation: - """GET /responses/{id}/input_items with chat isolation key enforcement. +class TestInputItemsUserIsolation: + """GET /responses/{id}/input_items with user ID enforcement. In-flight isolation is enforced locally; after eviction, isolation is enforced by the Foundry storage provider server-side. @@ -558,11 +558,11 @@ class TestInputItemsChatIsolation: def test_input_items_matching_key_returns_200(self) -> None: client = _make_client() - resp = _create_response(client, chat_key="key_A") - _wait_for_terminal(client, resp["id"], **{"x-agent-chat-isolation-key": "key_A"}) + resp = _create_response(client, user_id_key="key_A") + _wait_for_terminal(client, resp["id"], **{"x-agent-user-id": "key_A"}) r = client.get( f"/responses/{resp['id']}/input_items", - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) assert r.status_code == 200 @@ -581,14 +581,14 @@ async def test_input_items_mismatched_key_returns_404(self) -> None: "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: await asyncio.wait_for(handler.started.wait(), timeout=5.0) r = await client.get( f"/responses/{response_id}/input_items", - headers={"x-agent-chat-isolation-key": "key_B"}, + headers={"x-agent-user-id": "key_B"}, ) assert r.status_code == 404 finally: @@ -615,7 +615,7 @@ async def test_input_items_missing_key_when_created_with_key_returns_404(self) - "background": True, "stream": True, }, - headers={"x-agent-chat-isolation-key": "key_A"}, + headers={"x-agent-user-id": "key_A"}, ) ) try: diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_logging_policy.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_logging_policy.py index 3b507d369e46..6b33253b7d24 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_logging_policy.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_logging_policy.py @@ -154,63 +154,59 @@ async def test_logging_policy_handles_missing_correlation_headers(caplog: pytest @pytest.mark.asyncio -async def test_logging_policy_logs_isolation_header_presence(caplog: pytest.LogCaptureFixture) -> None: - """Isolation header *presence* is logged but actual values are NOT.""" +async def test_logging_policy_logs_platform_header_presence(caplog: pytest.LogCaptureFixture) -> None: + """Platform header *presence* is logged but actual values are NOT.""" policy = FoundryStorageLoggingPolicy() next_policy = AsyncMock() next_policy.send = AsyncMock(return_value=_make_response(200)) policy.next = next_policy request = _make_request("GET", "https://storage.example.com/responses/r1") - request.http_request.headers["x-agent-user-isolation-key"] = "secret-user-key" - request.http_request.headers["x-agent-chat-isolation-key"] = "secret-chat-key" + request.http_request.headers["x-agent-foundry-call-id"] = "secret-call-id" with caplog.at_level(logging.INFO, logger="azure.ai.agentserver"): await policy.send(request) msg = caplog.records[0].message - assert "has_user_isolation_key=True" in msg - assert "has_chat_isolation_key=True" in msg + assert "has_call_id=True" in msg # Values must never appear - assert "secret-user-key" not in msg - assert "secret-chat-key" not in msg + assert "secret-call-id" not in msg @pytest.mark.asyncio -async def test_logging_policy_logs_isolation_header_absence(caplog: pytest.LogCaptureFixture) -> None: - """When isolation headers are absent both flags are False.""" +async def test_logging_policy_logs_platform_header_absence(caplog: pytest.LogCaptureFixture) -> None: + """When platform headers are absent both flags are False.""" policy = FoundryStorageLoggingPolicy() next_policy = AsyncMock() next_policy.send = AsyncMock(return_value=_make_response(200)) policy.next = next_policy request = _make_request("GET", "https://storage.example.com/responses/r1") - # Default _make_request has no isolation headers + # Default _make_request has no platform headers with caplog.at_level(logging.INFO, logger="azure.ai.agentserver"): await policy.send(request) msg = caplog.records[0].message - assert "has_user_isolation_key=False" in msg - assert "has_chat_isolation_key=False" in msg + assert "has_call_id=False" in msg @pytest.mark.asyncio -async def test_logging_policy_transport_failure_omits_isolation_flags(caplog: pytest.LogCaptureFixture) -> None: - """Transport failure ERROR log is minimal and omits isolation flags.""" +async def test_logging_policy_transport_failure_omits_platform_flags(caplog: pytest.LogCaptureFixture) -> None: + """Transport failure ERROR log is minimal and omits platform flags.""" policy = FoundryStorageLoggingPolicy() next_policy = AsyncMock() next_policy.send = AsyncMock(side_effect=ConnectionError("oops")) policy.next = next_policy request = _make_request("POST", "https://storage.example.com/responses") - request.http_request.headers["x-agent-chat-isolation-key"] = "secret" + request.http_request.headers["x-agent-foundry-call-id"] = "secret" with caplog.at_level(logging.DEBUG, logger="azure.ai.agentserver"): with pytest.raises(ConnectionError): await policy.send(request) - # Transport failure log — at ERROR level, does not include isolation flags + # Transport failure log — at ERROR level, does not include platform flags # (transport failure message is intentionally minimal) error_records = [r for r in caplog.records if r.levelno >= logging.ERROR] assert len(error_records) == 1 diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_storage_provider.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_storage_provider.py index b912e146c1e0..0ef99fb9b2b5 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_storage_provider.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_foundry_storage_provider.py @@ -11,11 +11,11 @@ import pytest from azure.ai.agentserver.core._platform_headers import ( - CHAT_ISOLATION_KEY as _CHAT_ISOLATION_HEADER, - USER_ISOLATION_KEY as _USER_ISOLATION_HEADER, + FOUNDRY_CALL_ID as _CALL_ID_HEADER, + USER_ID as _USER_ID_HEADER, ) -from azure.ai.agentserver.responses._response_context import IsolationContext +from azure.ai.agentserver.responses._response_context import PlatformContext from azure.ai.agentserver.responses.store._foundry_errors import ( FoundryApiError, FoundryBadRequestError, @@ -459,121 +459,136 @@ async def test_get_history_item_ids__omits_optional_params_when_none( # =========================================================================== -# Isolation headers (S-018) +# Platform identity headers (S-018) # =========================================================================== @pytest.mark.asyncio -async def test_create_response__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_create_response__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, {})) from azure.ai.agentserver.responses.models._generated import ResponseObject - isolation = IsolationContext(user_key="u_key_1", chat_key="c_key_1") - await provider.create_response(ResponseObject(_RESPONSE_DICT), None, None, isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_1", call_id="c_key_1") + await provider.create_response(ResponseObject(_RESPONSE_DICT), None, None, context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_1" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_1" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_1" @pytest.mark.asyncio -async def test_get_response__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_get_response__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, _RESPONSE_DICT)) - isolation = IsolationContext(user_key="u_key_2", chat_key="c_key_2") - await provider.get_response("resp_abc123", isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_2", call_id="c_key_2") + await provider.get_response("resp_abc123", context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_2" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_2" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_2" @pytest.mark.asyncio -async def test_update_response__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_update_response__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, {})) from azure.ai.agentserver.responses.models._generated import ResponseObject - isolation = IsolationContext(user_key="u_key_3", chat_key="c_key_3") - await provider.update_response(ResponseObject(_RESPONSE_DICT), isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_3", call_id="c_key_3") + await provider.update_response(ResponseObject(_RESPONSE_DICT), context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_3" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_3" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_3" @pytest.mark.asyncio -async def test_delete_response__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_delete_response__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, {})) - isolation = IsolationContext(user_key="u_key_4", chat_key="c_key_4") - await provider.delete_response("resp_abc123", isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_4", call_id="c_key_4") + await provider.delete_response("resp_abc123", context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_4" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_4" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_4" @pytest.mark.asyncio -async def test_get_input_items__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_get_input_items__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, {"data": []})) - isolation = IsolationContext(user_key="u_key_5", chat_key="c_key_5") - await provider.get_input_items("resp_abc123", isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_5", call_id="c_key_5") + await provider.get_input_items("resp_abc123", context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_5" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_5" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_5" @pytest.mark.asyncio -async def test_get_items__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_get_items__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, [_OUTPUT_ITEM_DICT])) - isolation = IsolationContext(user_key="u_key_6", chat_key="c_key_6") - await provider.get_items(["item_out_001"], isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_6", call_id="c_key_6") + await provider.get_items(["item_out_001"], context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_6" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_6" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_6" @pytest.mark.asyncio -async def test_get_history_item_ids__sends_isolation_headers(credential: Any, settings: FoundryStorageSettings) -> None: +async def test_get_history_item_ids__sends_platform_headers(credential: Any, settings: FoundryStorageSettings) -> None: provider = _make_provider(credential, settings, _make_response(200, [])) - isolation = IsolationContext(user_key="u_key_7", chat_key="c_key_7") - await provider.get_history_item_ids(None, None, limit=10, isolation=isolation) + isolation = PlatformContext(user_id_key="u_key_7", call_id="c_key_7") + await provider.get_history_item_ids(None, None, limit=10, context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_key_7" - assert request.headers[_CHAT_ISOLATION_HEADER] == "c_key_7" + assert _USER_ID_HEADER not in request.headers # user_id is not forwarded to 1P + assert request.headers[_CALL_ID_HEADER] == "c_key_7" @pytest.mark.asyncio -async def test_isolation_headers__omitted_when_none(credential: Any, settings: FoundryStorageSettings) -> None: - """When isolation=None (default), no isolation headers are sent.""" +async def test_platform_headers__omitted_when_none(credential: Any, settings: FoundryStorageSettings) -> None: + """When context=None (default), no platform headers are sent.""" provider = _make_provider(credential, settings, _make_response(200, _RESPONSE_DICT)) await provider.get_response("resp_abc123") request = provider._client.send_request.call_args[0][0] - assert _USER_ISOLATION_HEADER not in request.headers - assert _CHAT_ISOLATION_HEADER not in request.headers + assert _USER_ID_HEADER not in request.headers + assert _CALL_ID_HEADER not in request.headers @pytest.mark.asyncio -async def test_isolation_headers__partial_keys_only_sends_present( +async def test_platform_headers__user_id_alone_sends_nothing( credential: Any, settings: FoundryStorageSettings ) -> None: - """When only user_key is set, only user header is added.""" + """user_id is never forwarded to 1P; with only user_id_key set, no headers are sent.""" provider = _make_provider(credential, settings, _make_response(200, _RESPONSE_DICT)) - isolation = IsolationContext(user_key="u_only") - await provider.get_response("resp_abc123", isolation=isolation) + isolation = PlatformContext(user_id_key="u_only") + await provider.get_response("resp_abc123", context=isolation) request = provider._client.send_request.call_args[0][0] - assert request.headers[_USER_ISOLATION_HEADER] == "u_only" - assert _CHAT_ISOLATION_HEADER not in request.headers + assert _USER_ID_HEADER not in request.headers + assert _CALL_ID_HEADER not in request.headers + + +@pytest.mark.asyncio +async def test_platform_headers__call_id_alone_sends_call_id( + credential: Any, settings: FoundryStorageSettings +) -> None: + """With only call_id set, only the call-id header is forwarded.""" + provider = _make_provider(credential, settings, _make_response(200, _RESPONSE_DICT)) + + isolation = PlatformContext(call_id="c_only") + await provider.get_response("resp_abc123", context=isolation) + + request = provider._client.send_request.call_args[0][0] + assert request.headers[_CALL_ID_HEADER] == "c_only" + assert _USER_ID_HEADER not in request.headers # =========================================================================== diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_in_memory_provider_crud.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_in_memory_provider_crud.py index d90dff957de9..3aa249cc0675 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_in_memory_provider_crud.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_in_memory_provider_crud.py @@ -4,7 +4,7 @@ Covers create, read, update, delete of response envelopes, output item storage, history resolution via previous_response_id -and conversation_id, and defensive-copy isolation. +and conversation_id, and defensive-copy platform context. """ from __future__ import annotations diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_platform_headers.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_platform_headers.py index c3721fc058b9..350ac5d0f7d9 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_platform_headers.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_platform_headers.py @@ -6,14 +6,14 @@ from azure.ai.agentserver.core._platform_headers import ( APIM_REQUEST_ID, - CHAT_ISOLATION_KEY, CLIENT_HEADER_PREFIX, CLIENT_REQUEST_ID, + FOUNDRY_CALL_ID, REQUEST_ID, SERVER_VERSION, SESSION_ID, TRACEPARENT, - USER_ISOLATION_KEY, + USER_ID, ) from azure.ai.agentserver.core._request_id import REQUEST_ID_STATE_KEY @@ -30,11 +30,11 @@ def test_server_version(self) -> None: def test_session_id(self) -> None: assert SESSION_ID == "x-agent-session-id" - def test_user_isolation_key(self) -> None: - assert USER_ISOLATION_KEY == "x-agent-user-isolation-key" + def test_user_id(self) -> None: + assert USER_ID == "x-agent-user-id" - def test_chat_isolation_key(self) -> None: - assert CHAT_ISOLATION_KEY == "x-agent-chat-isolation-key" + def test_foundry_call_id(self) -> None: + assert FOUNDRY_CALL_ID == "x-agent-foundry-call-id" def test_client_header_prefix(self) -> None: assert CLIENT_HEADER_PREFIX == "x-client-" diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_context_input_items.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_context_input_items.py index 5f10a2906adf..bc878b06b8b7 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_context_input_items.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_context_input_items.py @@ -9,7 +9,7 @@ import pytest -from azure.ai.agentserver.responses._response_context import IsolationContext, ResponseContext +from azure.ai.agentserver.responses._response_context import PlatformContext, ResponseContext from azure.ai.agentserver.responses.models._generated import ( CreateResponse, Item, @@ -91,7 +91,7 @@ async def test_get_input_items__resolves_single_reference() -> None: # Resolved via to_item(): OutputItemMessage → ItemMessage assert isinstance(items[0], ItemMessage) assert items[0].role == "assistant" - provider.get_items.assert_awaited_once_with(["item_abc"], isolation=ctx.isolation) + provider.get_items.assert_awaited_once_with(["item_abc"], context=ctx.platform_context) # ------------------------------------------------------------------ @@ -258,17 +258,17 @@ async def test_get_input_items__empty_input() -> None: # ------------------------------------------------------------------ -# Isolation context is forwarded to provider +# Platform context is forwarded to provider # ------------------------------------------------------------------ @pytest.mark.asyncio -async def test_get_input_items__forwards_isolation() -> None: - """Isolation context is passed through to provider.get_items().""" +async def test_get_input_items__forwards_platform_context() -> None: + """Platform context is passed through to provider.get_items().""" ref = ItemReferenceParam(id="item_iso") resolved = OutputItemMessage(id="item_iso", role="assistant", content=[], status="completed") provider = _mock_provider(get_items_return=[resolved]) - isolation = IsolationContext(user_key="user_123", chat_key="chat_456") + isolation = PlatformContext(user_id_key="user_123", call_id="call_456") request = _make_request([ref]) ctx = ResponseContext( @@ -277,14 +277,14 @@ async def test_get_input_items__forwards_isolation() -> None: request=request, input_items=[ref], provider=provider, - isolation=isolation, + platform_context=isolation, ) items = await ctx.get_input_items() assert len(items) == 1 assert isinstance(items[0], ItemMessage) # resolved via to_item() - provider.get_items.assert_awaited_once_with(["item_iso"], isolation=isolation) + provider.get_items.assert_awaited_once_with(["item_iso"], context=isolation) # ------------------------------------------------------------------ diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_emitter.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_emitter.py index fd5f91f165e2..215bf3b2517d 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_emitter.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_emitter.py @@ -7,7 +7,7 @@ import re from types import ModuleType -from scripts.validator_emitter import build_validator_module +from _scripts.validator_emitter import build_validator_module def _load_module(code: str) -> ModuleType: diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_contract.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_contract.py index cdc6953a4533..3843d8ca6150 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_contract.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_contract.py @@ -10,7 +10,7 @@ def _script_path() -> Path: - return Path(__file__).resolve().parents[2] / "scripts" / "generate_validators.py" + return Path(__file__).resolve().parents[2] / "_scripts" / "generate_validators.py" def _minimal_spec() -> str: diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_e2e.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_e2e.py index adaffd242655..0807e452c750 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_e2e.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_generator_e2e.py @@ -11,7 +11,7 @@ def _script_path() -> Path: - return Path(__file__).resolve().parents[2] / "scripts" / "generate_validators.py" + return Path(__file__).resolve().parents[2] / "_scripts" / "generate_validators.py" def _spec() -> str: diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_schema_walker.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_schema_walker.py index 1d5b27234743..5d4f55517067 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_schema_walker.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validator_schema_walker.py @@ -4,7 +4,7 @@ from __future__ import annotations -from scripts.validator_schema_walker import SchemaWalker, discover_post_request_roots, resolve_ref +from _scripts.validator_schema_walker import SchemaWalker, discover_post_request_roots, resolve_ref def test_resolve_ref_extracts_schema_name() -> None: