diff --git a/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md b/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md index e38c86ddb51a..fe6433972a02 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md +++ b/sdk/agentserver/azure-ai-agentserver-responses/CHANGELOG.md @@ -4,6 +4,7 @@ ### Other Changes +- Cleaned up the public API surface by moving validation-only error helpers to a private implementation module and renaming runtime terminal/replay helpers as private. - Bumped the minimum `azure-ai-agentserver-core` dependency to `>=2.0.0b10`, which adds an opt-in gate for resilient-task startup recovery. The resilient Responses samples now call `set_resilient_tasks_enabled(True)` to explicitly opt in, mirroring the invocations resilient samples. ## 2.0.0b0 (2026-07-29) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/api.md b/sdk/agentserver/azure-ai-agentserver-responses/api.md index 3dea894ec80b..416ff6312c7a 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/api.md +++ b/sdk/agentserver/azure-ai-agentserver-responses/api.md @@ -1,15 +1,9 @@ ```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.ConversationChainMetadataNamespace(Protocol): implements Collection def __call__(self, name: Optional[str] = None) -> ConversationChainMetadataNamespace: ... @@ -5927,108 +5921,8 @@ namespace azure.ai.agentserver.responses.models type: Literal[workflow_action] -namespace azure.ai.agentserver.responses.models.errors - - class azure.ai.agentserver.responses.models.errors.ApiErrorResponse(TypedDict, total=False): - key "error": Required[Error] - error: Error - - - class azure.ai.agentserver.responses.models.errors.Error(TypedDict, total=False): - key "code": Required[Optional[str]] - key "message": Required[str] - key "param": Optional[str] - key "type": str - additionalInfo: dict[str, Any] - additional_info: dict[str, Any] - code: str - debugInfo: dict[str, Any] - debug_info: dict[str, Any] - details: list[Error] - message: str - param: str - type: str - - - 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.apply_cancelled_terminal(base: Mapping[str, Any]) -> dict[str, Any]: ... - - - def azure.ai.agentserver.responses.models.runtime.apply_failed_terminal( - base: Mapping[str, Any], - *, - error: dict[str, Any] - ) -> dict[str, Any]: ... - - - 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: ... - - - def azure.ai.agentserver.responses.models.runtime.resolve_cancelled_response( - base: Mapping[str, Any] | None, - response_id: str, - agent_reference: AgentReference | dict[str, Any], - model: str | None, - *, - created_at: datetime | None = ... - ) -> ResponseObject: ... - - - def azure.ai.agentserver.responses.models.runtime.resolve_failed_response( - base: Mapping[str, Any] | None, - response_id: str, - agent_reference: AgentReference | dict[str, Any], - model: str | None, - *, - created_at: datetime | None = ..., - error_code: str = "server_error", - error_message: str = _DEFAULT_FAILED_ERROR_MESSAGE - ) -> ResponseObject: ... - - - class azure.ai.agentserver.responses.models.runtime.AgentReference(TypedDict, total=False): - key "name": Required[str] - key "type": Required[Literal["agent_reference"]] - key "version": str - name: str - type: Literal[agent_reference] - version: str - - class azure.ai.agentserver.responses.models.runtime.ResponseExecution: property agent_reference: AgentReference | dict[str, Any] # Read-only property is_terminal: bool # Read-only @@ -6084,78 +5978,6 @@ namespace azure.ai.agentserver.responses.models.runtime ) -> None: ... - class azure.ai.agentserver.responses.models.runtime.ResponseObject(TypedDict, total=False): - key "agent_reference": Required[Optional[AgentReference]] - key "background": Optional[bool] - key "completed_at": Optional[int] - key "conversation": Optional[ConversationReference] - key "created_at": Required[int] - key "error": Required[Optional[ResponseErrorInfo]] - key "id": Required[str] - key "incomplete_details": Required[Optional[ResponseIncompleteDetails]] - key "instructions": Required[Optional[Union[str, list[Item]]]] - key "max_output_tokens": Optional[int] - key "max_tool_calls": Optional[int] - key "metadata": Optional[Metadata] - key "model": str - key "moderation": Optional[Moderation] - key "object": Required[Literal["response"]] - key "output": Required[list[OutputItem]] - key "output_text": Optional[str] - key "parallel_tool_calls": Required[bool] - key "previous_response_id": Optional[str] - key "prompt": ForwardRef('Prompt', module='types') - key "prompt_cache_key": str - key "prompt_cache_retention": Optional[Literal["in_memory", "24h"]] - key "reasoning": Optional[Reasoning] - key "safety_identifier": str - key "service_tier": Optional[Literal["auto", "default", "flex", "scale", "priority"]] - key "status": Literal["completed", "failed", "in_progress", "cancelled", "queued", "incomplete"] - key "temperature": Optional[float] - key "text": ForwardRef('ResponseTextParam', module='types') - key "tool_choice": Union[Literal["none", "auto", "required"], ToolChoiceParam] - key "top_logprobs": Optional[int] - key "top_p": Optional[float] - key "truncation": Optional[Literal["auto", "disabled"]] - key "usage": ForwardRef('ResponseUsage', module='types') - key "user": str - agent_reference: AgentReference - background: bool - completed_at: int - conversation: ConversationReference - created_at: int - error: ResponseErrorInfo - id: str - incomplete_details: ResponseIncompleteDetails - instructions: Union[str, list[Item]] - max_output_tokens: int - max_tool_calls: int - metadata: Metadata - model: str - moderation: Moderation - object: Literal[response] - output: list[OutputItem] - output_text: str - parallel_tool_calls: bool - previous_response_id: str - prompt: Prompt - prompt_cache_key: str - prompt_cache_retention: Literal[in_memory, 24h] - reasoning: Reasoning - safety_identifier: str - service_tier: Literal[auto, default, flex, scale, priority] - status: Literal[completed, failed, in_progress, cancelled, queued, incomplete] - temperature: float - text: ResponseTextParam - tool_choice: Union[ToolChoiceOptions, ToolChoiceParam] - tools: list[Tool] - top_logprobs: int - top_p: float - truncation: Literal[auto, disabled] - usage: ResponseUsage - user: str - - class azure.ai.agentserver.responses.models.runtime.StreamEventRecord: property terminal: bool # Read-only @@ -6176,19 +5998,6 @@ namespace azure.ai.agentserver.responses.models.runtime ) -> 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.store class azure.ai.agentserver.responses.store.ResponseAlreadyExistsError(Exception): diff --git a/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml b/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml index 6c892122a747..991cefd4d123 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml +++ b/sdk/agentserver/azure-ai-agentserver-responses/api.metadata.yml @@ -1,3 +1,3 @@ -apiMdSha256: 2c3ff121746e6028ece71257bcd47d7421233e6f92f2d3f6612a03a5ca34735a +apiMdSha256: bf36559af5d6dc108cd68fc723cdbc31635cfe70b6439382f8a3d5b3282dd1a4 parserVersion: 0.3.30 -pythonVersion: 3.12.10 +pythonVersion: 3.11.15 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 3b1a4d04bd0c..0273bcec3e0e 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 @@ -18,9 +18,7 @@ from .hosting._routing import ResponsesAgentServerHost from .models import CreateResponse, ResponseObject from .models._helpers import ( - get_conversation_id, get_input_expanded, - to_output_item, ) from .store._base import ResponseProviderProtocol from .store._file import FileResponseStore @@ -59,7 +57,5 @@ "TextResponse", "CreateResponse", "ResponseObject", - "get_conversation_id", "get_input_expanded", - "to_output_item", ] 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 b17f39079a42..060dbf934f14 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 @@ -56,8 +56,8 @@ from ..models.runtime import ( ResponseExecution, ResponseModeFlags, - resolve_cancelled_response, - resolve_failed_response, + _resolve_cancelled_response, + _resolve_failed_response, ) from ..store._base import ResponseProviderProtocol, ResponseStoreCorruptionError from ..store._foundry_errors import FoundryApiError, FoundryBadRequestError, FoundryResourceNotFoundError @@ -1552,7 +1552,7 @@ async def handle_cancel(self, request: Request) -> Response: if terminal_error is not None: if record.status == "cancelled": record.set_response_snapshot( - resolve_cancelled_response( + _resolve_cancelled_response( record.response, record.response_id, record.agent_reference, record.model ) ) @@ -1581,7 +1581,7 @@ async def handle_cancel(self, request: Request) -> Response: # Set cancelled snapshot and transition record.set_response_snapshot( - resolve_cancelled_response(record.response, record.response_id, record.agent_reference, record.model) + _resolve_cancelled_response(record.response, record.response_id, record.agent_reference, record.model) ) # Stamp mode flags so the provider fallback can enforce B1/B2 checks # after eager eviction removes the in-memory record. @@ -1836,7 +1836,7 @@ async def handle_shutdown(self) -> None: # Leave in current state — will be re-entered on restart. continue # Non-resilient or foreground: best-effort mark failed. - failed_payload = resolve_failed_response( + failed_payload = _resolve_failed_response( record.response, record.response_id, record.agent_reference, record.model ) record.set_response_snapshot(failed_payload) 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 1b71c4cc5417..9e779c8111a6 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 @@ -41,18 +41,10 @@ ResponseExecution, ResponseModeFlags, ResponseStatus, -) -from ..models.runtime import ( - apply_cancelled_terminal as _apply_cancelled_terminal, -) -from ..models.runtime import ( - apply_failed_terminal as _apply_failed_terminal, -) -from ..models.runtime import ( - resolve_cancelled_response as _resolve_cancelled_response, -) -from ..models.runtime import ( - resolve_failed_response as _resolve_failed_response, + _apply_cancelled_terminal, + _apply_failed_terminal, + _resolve_cancelled_response, + _resolve_failed_response, ) from ..store._base import ResponseAlreadyExistsError, ResponseProviderProtocol from ..streaming._checkpoint import ResponseCheckpointEvent diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_request_parsing.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_request_parsing.py index 2106c625ed71..d7ba9451eb28 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_request_parsing.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_request_parsing.py @@ -13,7 +13,7 @@ from ..models import AgentReference, CreateResponse from .._id_generator import IdGenerator -from ..models.errors import RequestValidationError +from ..models._errors import RequestValidationError _X_AGENT_RESPONSE_ID_HEADER = "x-agent-response-id" diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_resilient_orchestrator.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_resilient_orchestrator.py index 113961a01b82..9dff20b503b5 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_resilient_orchestrator.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_resilient_orchestrator.py @@ -191,14 +191,14 @@ def _overlay_failed_terminal( :returns: A copy of the snapshot transitioned to ``failed``. :rtype: ResponseObject """ - from ..models.runtime import apply_failed_terminal # pylint: disable=import-outside-toplevel + from ..models.runtime import _apply_failed_terminal # pylint: disable=import-outside-toplevel from ..models._generated import ResponseObject # pylint: disable=import-outside-toplevel error = { "code": "server_error", "message": message if message is not None else _server_error_message(shutdown_reason), } - return cast(ResponseObject, apply_failed_terminal(snapshot, error=error)) + return cast(ResponseObject, _apply_failed_terminal(snapshot, error=error)) # (Spec 033 §3.1) Process-local cache of typed :class:`RuntimeRefs` (record, diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_validation.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_validation.py index 1cb7df5df10f..4289c1676a1d 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_validation.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_validation.py @@ -17,7 +17,7 @@ from .._id_generator import IdGenerator from .._options import ResponsesServerOptions from ..models import ApiErrorResponse, CreateResponse -from ..models.errors import RequestValidationError +from ..models._errors import RequestValidationError from ..models._validators import ( validate_create_response_payload, ) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/errors.py b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/_errors.py similarity index 97% rename from sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/errors.py rename to sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/_errors.py index 67ef67e0a847..e632a92f9ea8 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/errors.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/models/_errors.py @@ -1,6 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. -"""Error model types for request validation failures.""" +"""Internal error model helpers for request validation failures.""" from __future__ import annotations 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 68fd22dd20bb..026dab258e5a 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 @@ -9,11 +9,10 @@ from datetime import datetime, timezone from typing import TYPE_CHECKING, Any, Literal, Mapping, cast -from ._generated import AgentReference, OutputItem, ResponseObject, ResponseStreamEvent - if TYPE_CHECKING: from .._response_context import ResponseContext from azure.ai.agentserver.core.streaming import EventStream # pylint: disable=import-error,no-name-in-module + from ._generated import AgentReference, OutputItem, ResponseObject, ResponseStreamEvent ResponseStatus = Literal["queued", "in_progress", "completed", "failed", "cancelled", "incomplete"] @@ -83,8 +82,7 @@ def from_generated(cls, event: ResponseStreamEvent, payload: Mapping[str, Any]) class ResponseExecution: # pylint: disable=too-many-instance-attributes """Lightweight pipeline state for one response execution. - This type intentionally does not own persisted stream history. Stream replay - concerns are modeled separately in :class:`StreamReplayState`. + This type intentionally does not own persisted stream history. """ def __init__( @@ -256,7 +254,7 @@ def apply_event(self, normalized: ResponseStreamEvent, all_events: list[Response agent_reference=agent_reference, model=model, ) - self.set_response_snapshot(cast(ResponseObject, snapshot)) + self.set_response_snapshot(cast("ResponseObject", snapshot)) resolved = snapshot.get("status") if isinstance(resolved, str): self.status = cast(ResponseStatus, resolved) @@ -303,7 +301,7 @@ def model(self) -> str | None: return None -class StreamReplayState: +class _StreamReplayState: """Persisted stream replay state for one response identifier.""" def __init__( @@ -335,13 +333,12 @@ def append(self, event: StreamEventRecord) -> None: def terminal_event_seen(self) -> bool: """Return whether replay state has already recorded a terminal event. - :returns: True if the last recorded event is terminal, False otherwise. :rtype: bool """ return bool(self.events and self.events[-1].terminal) -def build_cancelled_response( +def _build_cancelled_response( response_id: str, agent_reference: AgentReference | dict[str, Any], model: str | None, @@ -371,10 +368,10 @@ def build_cancelled_response( } if created_at is not None: payload["created_at"] = int(created_at.timestamp()) - return cast(ResponseObject, payload) + return cast("ResponseObject", payload) -def build_failed_response( +def _build_failed_response( response_id: str, agent_reference: AgentReference | dict[str, Any], model: str | None, @@ -394,7 +391,7 @@ def build_failed_response( :type created_at: datetime | None :param error_message: Human-readable error message. :type error_message: str - :param error_code: Error code string (e.g. ``"server_error"`` or ``"storage_error"``). + :param error_code: Error code string. :type error_code: str :returns: A Response object with status ``"failed"`` and empty output. :rtype: ResponseObject @@ -411,29 +408,21 @@ def build_failed_response( } if created_at is not None: payload["created_at"] = int(created_at.timestamp()) - return cast(ResponseObject, payload) + return cast("ResponseObject", payload) _DEFAULT_FAILED_ERROR_MESSAGE = "An internal server error occurred." -def apply_failed_terminal(base: Mapping[str, Any], *, error: dict[str, Any]) -> dict[str, Any]: +def _apply_failed_terminal(base: Mapping[str, Any], *, error: dict[str, Any]) -> dict[str, Any]: """Overlay a ``failed`` terminal onto an existing response snapshot. - The handler owns the contents of the response object; the framework may - only set the terminal ``status`` and attach the ``error``. Every other - field the handler produced (``metadata``, ``conversation``, - ``instructions``, ``tools``, ``usage``, sampling params, ``output``, ...) - is preserved. Per the SOT behaviour contract a ``failed`` response's - ``output`` "may be partial", so accumulated output is kept; ``error`` is - non-null and ``completed_at`` MUST be null (only ``completed`` carries it). - - :param base: The existing (typically non-terminal) response snapshot. - :type base: ~typing.Mapping[str, ~typing.Any] - :keyword error: The ``error`` object to attach (``{code, message, ...}``). - :paramtype error: dict[str, ~typing.Any] + :param base: The existing response snapshot. + :type base: Mapping[str, Any] + :keyword error: The error payload to attach. + :paramtype error: dict[str, Any] :returns: A new payload dict transitioned to ``failed``. - :rtype: dict[str, ~typing.Any] + :rtype: dict[str, Any] """ as_dict = getattr(base, "as_dict", None) obj = cast("dict[str, Any]", as_dict()) if callable(as_dict) else deepcopy(dict(base)) @@ -443,19 +432,13 @@ def apply_failed_terminal(base: Mapping[str, Any], *, error: dict[str, Any]) -> return obj -def apply_cancelled_terminal(base: Mapping[str, Any]) -> dict[str, Any]: +def _apply_cancelled_terminal(base: Mapping[str, Any]) -> dict[str, Any]: """Overlay a ``cancelled`` terminal onto an existing response snapshot. - The handler owns the response contents; the framework sets ``status`` and, - per the SOT behaviour contract (B11 / Terminal Guarantee #2 — "cancellation - always wins ... 0 output items regardless of what processing had - produced"), clears ``output``. ``error`` and ``completed_at`` MUST be null - for a ``cancelled`` response. All other handler-owned fields are preserved. - - :param base: The existing (typically non-terminal) response snapshot. - :type base: ~typing.Mapping[str, ~typing.Any] - :returns: A new payload dict transitioned to ``cancelled`` with empty output. - :rtype: dict[str, ~typing.Any] + :param base: The existing response snapshot. + :type base: Mapping[str, Any] + :returns: A new payload dict transitioned to ``cancelled``. + :rtype: dict[str, Any] """ as_dict = getattr(base, "as_dict", None) obj = cast("dict[str, Any]", as_dict()) if callable(as_dict) else deepcopy(dict(base)) @@ -466,7 +449,7 @@ def apply_cancelled_terminal(base: Mapping[str, Any]) -> dict[str, Any]: return obj -def resolve_failed_response( +def _resolve_failed_response( base: Mapping[str, Any] | None, response_id: str, agent_reference: AgentReference | dict[str, Any], @@ -478,36 +461,34 @@ def resolve_failed_response( ) -> ResponseObject: """Build a ``failed`` terminal, preserving the handler's response object. - When ``base`` (the handler-produced snapshot) exists, the failed terminal - is overlaid onto it so no handler-owned fields are lost. When it is absent - (the handler crashed before ``response.created``, so there is nothing to - preserve), a minimal object is synthesized via :func:`build_failed_response`. - :param base: The handler's response snapshot, or ``None`` if none exists. - :type base: ~typing.Mapping[str, ~typing.Any] | None - :param response_id: The response identifier (used only for the synthesized fallback). + :type base: Mapping[str, Any] | None + :param response_id: The response identifier. :type response_id: str - :param agent_reference: Agent reference for the synthesized fallback. - :type agent_reference: ~azure.ai.agentserver.responses.models.AgentReference | dict[str, ~typing.Any] - :param model: Model identifier for the synthesized fallback. + :param agent_reference: Agent reference for synthesized responses. + :type agent_reference: AgentReference | dict[str, Any] + :param model: Model identifier for synthesized responses. :type model: str | None - :keyword created_at: Optional creation timestamp for the synthesized fallback. - :paramtype created_at: ~datetime.datetime | None - :keyword error_code: Error code (e.g. ``"server_error"`` / ``"storage_error"``). + :keyword created_at: Optional creation timestamp for synthesized responses. + :paramtype created_at: datetime | None + :keyword error_code: Error code for the terminal error payload. :paramtype error_code: str - :keyword error_message: Human-readable error message. + :keyword error_message: Error message for the terminal error payload. :paramtype error_message: str - :returns: A ``failed`` response object. - :rtype: ~azure.ai.agentserver.responses.models.ResponseObject + :returns: A failed terminal response payload. + :rtype: ResponseObject """ if base is not None: - return cast(ResponseObject, apply_failed_terminal(base, error={"code": error_code, "message": error_message})) - return build_failed_response( + return cast( + "ResponseObject", + _apply_failed_terminal(base, error={"code": error_code, "message": error_message}), + ) + return _build_failed_response( response_id, agent_reference, model, created_at=created_at, error_message=error_message, error_code=error_code ) -def resolve_cancelled_response( +def _resolve_cancelled_response( base: Mapping[str, Any] | None, response_id: str, agent_reference: AgentReference | dict[str, Any], @@ -517,23 +498,19 @@ def resolve_cancelled_response( ) -> ResponseObject: """Build a ``cancelled`` terminal, preserving the handler's response object. - When ``base`` exists it is overlaid (status → ``cancelled``, output - cleared); otherwise a minimal object is synthesized via - :func:`build_cancelled_response`. - :param base: The handler's response snapshot, or ``None`` if none exists. - :type base: ~typing.Mapping[str, ~typing.Any] | None - :param response_id: The response identifier (used only for the synthesized fallback). + :type base: Mapping[str, Any] | None + :param response_id: The response identifier. :type response_id: str - :param agent_reference: Agent reference for the synthesized fallback. - :type agent_reference: ~azure.ai.agentserver.responses.models.AgentReference | dict[str, ~typing.Any] - :param model: Model identifier for the synthesized fallback. + :param agent_reference: Agent reference for synthesized responses. + :type agent_reference: AgentReference | dict[str, Any] + :param model: Model identifier for synthesized responses. :type model: str | None - :keyword created_at: Optional creation timestamp for the synthesized fallback. - :paramtype created_at: ~datetime.datetime | None - :returns: A ``cancelled`` response object. - :rtype: ~azure.ai.agentserver.responses.models.ResponseObject + :keyword created_at: Optional creation timestamp for synthesized responses. + :paramtype created_at: datetime | None + :returns: A cancelled terminal response payload. + :rtype: ResponseObject """ if base is not None: - return cast(ResponseObject, apply_cancelled_terminal(base)) - return build_cancelled_response(response_id, agent_reference, model, created_at=created_at) + return cast("ResponseObject", _apply_cancelled_terminal(base)) + return _build_cancelled_response(response_id, agent_reference, model, created_at=created_at) 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 4f10d4d4b9e0..941be36ee682 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 @@ -14,7 +14,7 @@ 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 +from ..models.runtime import ResponseExecution, ResponseModeFlags, ResponseStatus, StreamEventRecord, _StreamReplayState from ._base import ResponseAlreadyExistsError, ResponseProviderProtocol _DEFAULT_REPLAY_EVENT_TTL_SECONDS: int = 600 @@ -28,7 +28,7 @@ def __init__( self, *, execution: ResponseExecution, - replay: StreamReplayState, + replay: _StreamReplayState, response: ResponseObject | None = None, input_item_ids: list[str] | None = None, output_item_ids: list[str] | None = None, @@ -122,7 +122,7 @@ async def create_response( response_id=response_id, mode_flags=self._resolve_mode_flags_from_response(response), ), - replay=StreamReplayState(response_id=response_id), + replay=_StreamReplayState(response_id=response_id), response=deepcopy(response), input_item_ids=input_ids, output_item_ids=output_ids, @@ -342,7 +342,7 @@ async def create_execution(self, execution: ResponseExecution, *, ttl_seconds: i self._entries[execution.response_id] = _StoreEntry( execution=deepcopy(execution), - replay=StreamReplayState(response_id=execution.response_id), + replay=_StreamReplayState(response_id=execution.response_id), expires_at=self._compute_expiry(ttl_seconds), ) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/doc/azure.ai.agentserver.responses.models.rst b/sdk/agentserver/azure-ai-agentserver-responses/doc/azure.ai.agentserver.responses.models.rst index aff45524268e..aaa0a9718bc0 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/doc/azure.ai.agentserver.responses.models.rst +++ b/sdk/agentserver/azure-ai-agentserver-responses/doc/azure.ai.agentserver.responses.models.rst @@ -9,14 +9,6 @@ azure.ai.agentserver.responses.models package Submodules ---------- -azure.ai.agentserver.responses.models.errors module ---------------------------------------------------- - -.. automodule:: azure.ai.agentserver.responses.models.errors - :inherited-members: - :members: - :undoc-members: - azure.ai.agentserver.responses.models.runtime module ---------------------------------------------------- diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_error_source_classification.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_error_source_classification.py index e28efe37ba99..fc006884b671 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_error_source_classification.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_error_source_classification.py @@ -27,7 +27,7 @@ service_unavailable_response, tag_platform_error, ) -from azure.ai.agentserver.responses.models.errors import RequestValidationError +from azure.ai.agentserver.responses.models._errors import RequestValidationError # --------------------------------------------------------------------------- # is_platform_error / tag_platform_error diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_generated_payload_validation.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_generated_payload_validation.py index ee4913d2eadf..1e2b63ad09c5 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_generated_payload_validation.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_generated_payload_validation.py @@ -8,7 +8,7 @@ from azure.ai.agentserver.responses.hosting._validation import parse_create_response from azure.ai.agentserver.responses.models._validators import validate_create_response_payload -from azure.ai.agentserver.responses.models.errors import RequestValidationError +from azure.ai.agentserver.responses.models._errors import RequestValidationError # --------------------------------------------------------------------------- # parse_create_response integration tests (real validator + real model) diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_execution.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_execution.py index a4935e5ef4de..e36e423d9905 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_execution.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_response_execution.py @@ -1,6 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. -"""Unit tests for ResponseExecution fields, properties, apply_event, and build_cancelled_response.""" +"""Unit tests for ResponseExecution fields, properties, apply_event, and cancelled response building.""" from __future__ import annotations @@ -11,7 +11,7 @@ from azure.ai.agentserver.responses.models.runtime import ( ResponseExecution, ResponseModeFlags, - build_cancelled_response, + _build_cancelled_response, ) # --------------------------------------------------------------------------- @@ -222,12 +222,12 @@ def test_apply_event_output_item_added() -> None: # --------------------------------------------------------------------------- -# T12 – build_cancelled_response +# T12 - _build_cancelled_response # --------------------------------------------------------------------------- def test_build_cancelled_response() -> None: - response = build_cancelled_response( + response = _build_cancelled_response( "caresp_xxx0000000000000000000000000000", {"name": "agent-a"}, "gpt-4o", diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_terminal_overlay.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_terminal_overlay.py index 17e5cdfbcb45..14c106c8275a 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_terminal_overlay.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_terminal_overlay.py @@ -14,10 +14,10 @@ from __future__ import annotations from azure.ai.agentserver.responses.models.runtime import ( - apply_cancelled_terminal, - apply_failed_terminal, - resolve_cancelled_response, - resolve_failed_response, + _apply_cancelled_terminal, + _apply_failed_terminal, + _resolve_cancelled_response, + _resolve_failed_response, ) @@ -42,7 +42,7 @@ def _rich_snapshot() -> dict: def test_apply_failed_terminal_preserves_handler_fields_and_partial_output() -> None: base = _rich_snapshot() - out = apply_failed_terminal(base, error={"code": "server_error", "message": "boom"}) + out = _apply_failed_terminal(base, error={"code": "server_error", "message": "boom"}) assert out["status"] == "failed" assert out["error"] == {"code": "server_error", "message": "boom"} @@ -60,7 +60,7 @@ def test_apply_failed_terminal_preserves_handler_fields_and_partial_output() -> def test_apply_cancelled_terminal_clears_output_and_error_preserves_rest() -> None: base = _rich_snapshot() base["error"] = {"code": "server_error", "message": "stale"} - out = apply_cancelled_terminal(base) + out = _apply_cancelled_terminal(base) assert out["status"] == "cancelled" # Cancellation always wins: 0 output items regardless of prior progress. @@ -75,7 +75,7 @@ def test_apply_cancelled_terminal_clears_output_and_error_preserves_rest() -> No def test_resolve_failed_response_overlays_when_base_present() -> None: base = _rich_snapshot() - resp = resolve_failed_response(base, "caresp_x", {"name": "a", "version": "1"}, "m", error_code="storage_error") + resp = _resolve_failed_response(base, "caresp_x", {"name": "a", "version": "1"}, "m", error_code="storage_error") payload = resp assert payload["status"] == "failed" assert payload["error"]["code"] == "storage_error" @@ -84,7 +84,7 @@ def test_resolve_failed_response_overlays_when_base_present() -> None: def test_resolve_failed_response_synthesizes_when_no_base() -> None: - resp = resolve_failed_response(None, "caresp_x", {"name": "a", "version": "1"}, "m") + resp = _resolve_failed_response(None, "caresp_x", {"name": "a", "version": "1"}, "m") payload = resp assert payload["status"] == "failed" assert payload["agent_reference"]["name"] == "a" @@ -94,7 +94,7 @@ def test_resolve_failed_response_synthesizes_when_no_base() -> None: def test_resolve_cancelled_response_overlays_when_base_present() -> None: base = _rich_snapshot() - resp = resolve_cancelled_response(base, "caresp_x", {"name": "a", "version": "1"}, "m") + resp = _resolve_cancelled_response(base, "caresp_x", {"name": "a", "version": "1"}, "m") payload = resp assert payload["status"] == "cancelled" assert payload["output"] == [] @@ -103,7 +103,7 @@ def test_resolve_cancelled_response_overlays_when_base_present() -> None: def test_resolve_cancelled_response_synthesizes_when_no_base() -> None: - resp = resolve_cancelled_response(None, "caresp_x", {"name": "a", "version": "1"}, "m") + resp = _resolve_cancelled_response(None, "caresp_x", {"name": "a", "version": "1"}, "m") payload = resp assert payload["status"] == "cancelled" assert payload["output"] == [] diff --git a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validation.py b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validation.py index 02403acf9a25..6011b6aff33f 100644 --- a/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validation.py +++ b/sdk/agentserver/azure-ai-agentserver-responses/tests/unit/test_validation.py @@ -11,7 +11,7 @@ to_api_error_response, validate_create_response, ) -from azure.ai.agentserver.responses.models.errors import RequestValidationError +from azure.ai.agentserver.responses.models._errors import RequestValidationError class _FakeCreateRequest(dict):