diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 82ca0b271c71..240fd9351b4c 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -144,6 +144,8 @@ "sdk/ai/azure-ai-voicelive/samples/**" ], "words": [ + "PSTN", + "pstn", "vally", "regen", "pylintrc", diff --git a/eng/tools/azure-sdk-tools/azpysdk/samples.py b/eng/tools/azure-sdk-tools/azpysdk/samples.py index e06cf84e6e8a..2520244eb6ed 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/samples.py +++ b/eng/tools/azure-sdk-tools/azpysdk/samples.py @@ -86,6 +86,22 @@ "hello_world_sample_entra_id_and_bleu.py", ], "azure-ai-ml": ["ml_samples_authentication_sovereign_cloud.py"], + "azure-ai-projects": [ + # These interactively read from stdin via input(), which raises EOFError when this + # runner executes the file non-interactively. + "sample_voice_agent_live_text_conversation.py", + "sample_voice_agent_live_text_conversation_async.py", + # Runs until Ctrl-C (continuous microphone capture/playback); would hang indefinitely + # under this non-interactive runner whenever PyAudio and live credentials are available. + "sample_voice_agent_live_audio_conversation_async.py", + # These read back a conversation transcript/audio from a *pre-existing*, already-persisted + # voice session via FOUNDRY_VOICE_CONVERSATION_ID, which no automation here provides (the + # package's own recorded sample suite skips them for the same reason -- see + # samples_to_skip in tests/samples/test_samples.py); running them raises a KeyError before + # exercising anything. + "sample_voice_agent_read_conversation.py", + "sample_voice_agent_read_conversation_audio.py", + ], "azure-eventgrid": [ "__init__.py", "consume_cloud_events_from_eventhub.py", diff --git a/scripts/devops_tasks/test_run_samples.py b/scripts/devops_tasks/test_run_samples.py index 2d7b44c9c366..b65debfbb68d 100644 --- a/scripts/devops_tasks/test_run_samples.py +++ b/scripts/devops_tasks/test_run_samples.py @@ -88,6 +88,22 @@ "azure-ai-ml": [ "ml_samples_authentication_sovereign_cloud.py" ], + "azure-ai-projects": [ + # These interactively read from stdin via input(), which raises EOFError when this + # runner executes the file non-interactively. + "sample_voice_agent_live_text_conversation.py", + "sample_voice_agent_live_text_conversation_async.py", + # Runs until Ctrl-C (continuous microphone capture/playback); would hang indefinitely + # under this non-interactive runner whenever PyAudio and live credentials are available. + "sample_voice_agent_live_audio_conversation_async.py", + # These read back a conversation transcript/audio from a *pre-existing*, already-persisted + # voice session via FOUNDRY_VOICE_CONVERSATION_ID, which no automation here provides (the + # package's own recorded sample suite skips them for the same reason -- see + # samples_to_skip in tests/samples/test_samples.py); running them raises a KeyError before + # exercising anything. + "sample_voice_agent_read_conversation.py", + "sample_voice_agent_read_conversation_audio.py", + ], "azure-eventgrid": [ "__init__.py", "consume_cloud_events_from_eventhub.py", diff --git a/sdk/ai/azure-ai-projects/.env.template b/sdk/ai/azure-ai-projects/.env.template index a89bd766f143..d9da54546934 100644 --- a/sdk/ai/azure-ai-projects/.env.template +++ b/sdk/ai/azure-ai-projects/.env.template @@ -23,6 +23,14 @@ AZURE_AI_PROJECTS_CONSOLE_LOGGING= FOUNDRY_PROJECT_ENDPOINT= FOUNDRY_PROJECT_API_KEY= FOUNDRY_MODEL_NAME= +# Read by the recorded voice-agent CRUD tests only (tests/test_base.py), not by any sample. +FOUNDRY_VOICE_MODEL_NAME= +# Read by the samples under samples/agents/voice/ (model deployment name, agent name, model type, +# and a conversation ID for the read-conversation samples). Distinct from FOUNDRY_VOICE_MODEL_NAME above. +FOUNDRY_VOICE_MODEL= +FOUNDRY_VOICE_MODEL_TYPE= +FOUNDRY_VOICE_AGENT_NAME= +FOUNDRY_VOICE_CONVERSATION_ID= FOUNDRY_AGENT_NAME= FOUNDRY_AGENT_CONTAINER_IMAGE= CONVERSATION_ID= diff --git a/sdk/ai/azure-ai-projects/CHANGELOG.md b/sdk/ai/azure-ai-projects/CHANGELOG.md index 4c282c7c4883..f7651eb6e6be 100644 --- a/sdk/ai/azure-ai-projects/CHANGELOG.md +++ b/sdk/ai/azure-ai-projects/CHANGELOG.md @@ -1,5 +1,31 @@ # Release History +## 2.7.0b1 (Unreleased) + +### Features Added + +* Added voice agents, unified with the rest of the Agents API as a new `kind="voice"` on `AgentDefinition`: + * Define a voice agent with `VoiceAgentDefinition`, configuring its model (`VoiceModelType`), audio input/output (`VoiceAgentAudioConfig`, `VoiceAgentAudioInputConfig`, `VoiceAgentAudioOutputConfig`), turn detection (`VoiceAgentTurnDetectionConfig` and its `VoiceAgentServerVadTurnDetection` / `VoiceAgentAzureSemanticVadTurnDetection` / `VoiceAgentAzureSemanticVadEnTurnDetection` / `VoiceAgentAzureSemanticVadMultilingualTurnDetection` variants), greeting (`VoiceAgentGreetingConfig` and its `VoiceAgentTemplateGreetingConfig` / `VoiceAgentLlmGeneratedGreetingConfig` variants), tools (`VoiceAgentTool`, `VoiceAgentFunctionTool`, `VoiceAgentMcpTool`, `VoiceAgentSystemTool`, `VoiceAgentToolboxTool`), and avatar (`VoiceAgentAvatarConfig`). Manage it like any other agent through `project_client.agents` (`create_version`, `get`, `list`, `disable`/`enable`, `delete`). + * Added guided authoring via `project_client.agents.generate_agent(GenerateVoiceAgentRequest(kind=AgentKind.VOICE, ...))`, which returns a service-generated starter definition that can be edited afterward through the standard `create_version`/`update` flow. + * Added a new `client.realtime` / `async_client.realtime` entry point for realtime speech-to-speech streaming. Use `with client.realtime.connect(agent_name=...) as connection:` to open a WebSocket connection, `connection.send(...)` to send strongly-typed client events (or use the `connection.response`, `connection.conversation.item`, and `connection.session` helpers), and iterate over `connection` to receive strongly-typed server events (`RealtimeServerEvent*`). Conversation items exchanged with `connection.conversation.item.create(...)` are `RealtimeConversationItemMessageSystem`, `RealtimeConversationItemMessageUser`, `RealtimeConversationItemMessageAssistant`, `RealtimeConversationItemFunctionCall`, `RealtimeConversationItemFunctionCallOutput`, `RealtimeMCPApprovalResponse`, or a raw `Mapping[str, Any]`. The new types `Realtime`, `RealtimeConnection`, and `RealtimeConnectionManager` (and their async equivalents `AsyncRealtime`, `AsyncRealtimeConnection`, `AsyncRealtimeConnectionManager`) are exported from `azure.ai.projects` / `azure.ai.projects.aio`. Requires the optional `websockets` package for the sync client, or `aiohttp` for the async client. + * Added the `agent_endpoint_conversations` operation group for reading back persisted voice-agent conversation transcripts and audio, for agents created with `store=True`. + * Added the underlying `RealtimeConversationItem*`, `RealtimeMCP*`, `RealtimeResponseUsage`, and related realtime event/session models used by the voice agent WebSocket protocol. +* Added 11 new samples under `samples/agents/voice/`, covering basic agent lifecycle, guided generation, live audio and text conversations (sync and async), function tools, versioning, and reading back conversation transcripts and audio. +* Extended voice agents with telephony, WebRTC, and sub-agent consultation: + * Added telephony bindings so a voice agent can receive calls through Teams Phone or Twilio. `project_client.agents.create_telephony_binding`/`get_telephony_binding`/`update_telephony_binding`/`delete_telephony_binding`/`list_telephony_bindings` manage the binding (`TelephonyBinding` and its `TeamsPhoneExtensionTelephonyBinding`/`TwilioTelephonyBinding` variants), and `list_telephony_calls`/`get_telephony_call`/`transfer_telephony_call`/`end_telephony_call`/`get_telephony_transfer_targets`/`replace_telephony_transfer_targets` manage in-progress and historical calls (`TelephonyCallRecord`, `TelephonyCallSummary`, `TelephonyCallTrace`, `TelephonyTransferTarget` and its `PSTNTelephonyTransferDestination`/`SipTelephonyTransferDestination`/`TeamsTelephonyTransferDestination` variants). + * Added an optional WebRTC transport for realtime voice sessions (`VoiceAgentTransport.WEBRTC`), where only SDP signaling travels over the WebSocket connection while media flows peer-to-peer. The new `VoiceAgentClientEventRtcCallSdpCreate`, `VoiceAgentServerEventRtcCallSdpCreated`, and `VoiceAgentServerEventRtcCallError` events carry the signaling exchange. + * Added the `agent_endpoint_conversations.get_agent_conversation_item_generated_audio`/`get_agent_conversation_item_generated_audio_content` methods for reading back a conversation item's *generated* audio, a subordinate artifact that can differ from what the listener heard when playback was interrupted, returning `VoiceGeneratedItemAudioResponse`. + * Added sub-agent consultation, letting a voice agent consult sibling Foundry text agents as background specialists mid-conversation, through the new `subagent_config` property on `VoiceAgentDefinition` (`VoiceAgentSubagentConfig`, `VoiceAgentSubagent`, `VoiceAgentSubagentResponsePolicy`), and the new `session.subagent.started`/`session.subagent.completed`/`session.subagent.aborted` realtime server events. + * Added an optional `conversation_engine` property on `VoiceAgentDefinition` (`VoiceConversationEngine`, `VoiceHostedAgentConversationEngine`) to delegate a voice agent's conversation handling to another hosted agent instead of configuring a model directly. + +### Dependency update + +* Added an optional dependency on `websockets` (sync `client.realtime`) and `aiohttp` (async `async_client.realtime`), required only when using the new voice agent realtime streaming APIs. + +### Bugs Fixed + +* The hand-written `client.realtime`/`async_client.realtime` WebSocket clients now identify themselves to the service the same way the generated HTTP surface already does: a standard Azure SDK `User-Agent` header (for example `azsdk-python-ai-projects/2.7.0b1 ...`) and an `x-ms-client-sdk` query parameter carrying the same value, for paths where the header isn't forwarded. Previously these connections fell back to the underlying `websockets`/`aiohttp` library's generic default, preventing service telemetry from attributing this traffic to the SDK. A caller-supplied `User-Agent` in `extra_headers` still takes precedence. + ## 2.6.0 (2026-09-04) ### Features Added diff --git a/sdk/ai/azure-ai-projects/PostEmitter.ps1 b/sdk/ai/azure-ai-projects/PostEmitter.ps1 index 129b8b4bbd12..ad9f44e43783 100644 --- a/sdk/ai/azure-ai-projects/PostEmitter.ps1 +++ b/sdk/ai/azure-ai-projects/PostEmitter.ps1 @@ -26,25 +26,96 @@ git restore pyproject.toml # recursive-include samples *.py *.md git restore MANIFEST.in -# Force streaming in get_session_log_stream for both sync and async operations. +# `types.py` is a dead artifact of the `generate-typeddict: false` tspconfig setting: the emitter +# still rewrites this file's mtime on every run, but its TypedDict content has been byte-for-byte +# frozen/stale since the very first regeneration of this package, regardless of how much the spec's +# models have changed since (confirmed via `git diff --quiet` across multiple TypeSpec commits with +# substantial, unrelated model renames). Delete it outright rather than let it silently ship stale, +# misleading type shapes. The small number of hand-written call sites that referenced it +# (`_patch_agents.py`, `_patch_datasets.py`, `_patch_evaluators.py`, and their aio counterparts) +# now use the emitter's own `JSON` (= MutableMapping[str, Any]) alias instead, matching the same +# "raw JSON body" overload pattern the generated `_operations.py` already uses for these same jobs. +$typesFile = 'azure\ai\projects\types.py' +if (Test-Path $typesFile) { + Remove-Item $typesFile -Force +} + +# `_AgentDefinitionOptInKeys` is an internal implementation-detail enum (leading underscore) used +# only to build the `Foundry-Features` opt-in header value in hand-written `_patch.py`/`_realtime.py` +# customization code, which always imports it directly from `.models._enums` (or `..models._enums`) - +# never through the `models` package's public re-export. The emitter nonetheless includes it in +# `models/__init__.py`'s import list and `__all__`, which makes it part of the public API surface +# (and shows up in APIView) even though nothing needs it there. Strip it from both places. +$f = 'azure\ai\projects\models\__init__.py' +$lines = Get-Content $f +$out = New-Object System.Collections.Generic.List[string] +foreach ($line in $lines) { + if ($line -match '^\s*_AgentDefinitionOptInKeys,\s*$') { continue } + if ($line -match '^\s*"_AgentDefinitionOptInKeys",\s*$') { continue } + $out.Add($line) +} +Set-Content $f $out + +# Remove the generated `voice_agent_web_socket` operation group from the public surface entirely. +# The generated operation only performs a plain HTTP GET (no WebSocket upgrade handshake) and +# discards the connection - it's not a usable client and was never meant to be public (the real +# voice-agent WebSocket client is `.realtime`). This operation group has moved around in the +# generated output across regenerations (previously wired directly on the top-level client as +# `VoiceAgentWebSocketOperations`; now nested as `BetaVoiceAgentWebSocketOperations` under +# `BetaOperations.__init__` in `_operations.py`) - this fixup targets wherever it currently lives, +# matching either class name, so it keeps working if the spec relocates it again. +$files = 'azure\ai\projects\_client.py', 'azure\ai\projects\aio\_client.py', 'azure\ai\projects\operations\_operations.py', 'azure\ai\projects\aio\operations\_operations.py' +foreach ($f in $files) { + $lines = Get-Content $f + $out = New-Object System.Collections.Generic.List[string] + $skipUntilCloseParen = $false + foreach ($line in $lines) { + if ($skipUntilCloseParen) { + if ($line -match '^\s*\)\s*$') { $skipUntilCloseParen = $false } + continue + } + if ($line -match '^\s*VoiceAgentWebSocketOperations,\s*$') { continue } + if ($line -match '^\s*:ivar voice_agent_web_socket:') { continue } + if ($line -match '^\s*:vartype voice_agent_web_socket:') { continue } + if ($line -match '^\s*self\.voice_agent_web_socket = (Beta)?VoiceAgentWebSocketOperations\(\s*$') { + $skipUntilCloseParen = $true + continue + } + $out.Add($line) + } + Set-Content $f $out +} + +# get_session_log_stream must always treat the response as an SSE stream, but must still pop any +# caller-supplied stream= kwarg first -- otherwise it collides with the explicit stream=_stream +# argument passed to self._client._pipeline.run(), raising "got multiple values for keyword +# argument 'stream'" (hit by samples calling get_session_log_stream(..., stream=True)). The popped +# value is discarded (not used to set _stream): this operation must always stream regardless of +# what the caller passes, otherwise a caller-supplied stream=False would make the generated method +# attempt normal deserialization of an open SSE response, which is invalid per its SSE contract. $files = 'azure\ai\projects\operations\_operations.py', 'azure\ai\projects\aio\operations\_operations.py' foreach ($f in $files) { $lines = Get-Content $f + $out = New-Object System.Collections.Generic.List[string] $inFunc = $false - for ($i = 0; $i -lt $lines.Length; $i++) { - if ($lines[$i] -match '^\s*(async\s+)?def\s+get_session_log_stream\(') { + foreach ($line in $lines) { + if ($line -match '^\s*(async\s+)?def\s+get_session_log_stream\(') { $inFunc = $true + $out.Add($line) continue } - if ($inFunc -and $lines[$i] -match '^\s*(async\s+)?def\s+\w+\(') { + if ($inFunc -and $line -match '^\s*(async\s+)?def\s+\w+\(') { $inFunc = $false } - if ($inFunc -and $lines[$i] -match 'kwargs\.pop\(.+stream.+False\)') { - $indent = ([regex]::Match($lines[$i], '^\s*')).Value - $lines[$i] = $indent + '_stream = True' + if ($inFunc -and $line -match '^\s*_stream = (True|kwargs\.pop\(.+\))\s*$') { + $indent = ([regex]::Match($line, '^\s*')).Value + $out.Add($indent + 'kwargs.pop("stream", None) # must always stream; discard any caller override') + $out.Add($indent + '_stream = True') + continue } + $out.Add($line) } - Set-Content $f $lines + Set-Content $f $out } # Fix Sphinx docutils warnings in class SessionLogEvent: the generated docstring wraps two long @@ -86,6 +157,304 @@ foreach ($f in $files) { Set-Content $f $c -NoNewline } +# Fix Sphinx docutils "Bullet list ends without a blank line; unexpected unindent" warnings in +# VoiceAudioOutputConfig (types.py + models/_models.py) and VoiceConversationStatus +# (models/_enums.py). The emitter wraps long bullet-item lines without indenting the +# continuation lines to align with the bullet's text, and (for VoiceAudioOutputConfig) runs the +# trailing summary sentence straight into the last bullet with no blank line to end the list. +# +# NOTE: these here-strings use single-quoted @'...'@ delimiters (not @"..."@) on purpose. +# Double-quoted here-strings still process backtick escape sequences, and since this text is +# full of literal Markdown backticks (`` `azure-standard` ``, etc.), any backtick not immediately +# followed by a recognized escape letter (n, r, t, 0, a, b, f, v, e, #, ', ", `) gets silently +# DROPPED by the PowerShell parser -- with no error or warning. That corrupts $oldVoiceAudioOutputConfig +# so it can never match the real (backtick-containing) generated file content, and .Replace() then +# just silently no-ops. Single-quoted here-strings disable all escape/interpolation processing, so +# the backticks survive exactly as written. +$oldVoiceAudioOutputConfig = @' + * `azure-standard`: `voice`, `voice_locale`, `speed`, `voice_temperature`, + `custom_lexicon_url`, + `custom_text_normalization_url`, `prefer_locales`, `style`, `pitch`, and `volume`. + * `azure-custom`: all `azure-standard` fields except `style`, plus `custom_voice_endpoint_id`. + * `azure-personal`: all `azure-standard` fields except `style`, plus `personal_voice_model`. + * `avatar-voice-sync`: all `azure-standard` fields except `voice` and `style`, plus + `personal_voice_model`; the voice name is derived from the avatar. + * `azure-realtime-native`: `voice` and `speed`. + `format` and `output_audio_timestamp_types` apply to every voice type. +'@ +$newVoiceAudioOutputConfig = @' + * `azure-standard`: `voice`, `voice_locale`, `speed`, `voice_temperature`, + `custom_lexicon_url`, + `custom_text_normalization_url`, `prefer_locales`, `style`, `pitch`, and `volume`. + * `azure-custom`: all `azure-standard` fields except `style`, plus `custom_voice_endpoint_id`. + * `azure-personal`: all `azure-standard` fields except `style`, plus `personal_voice_model`. + * `avatar-voice-sync`: all `azure-standard` fields except `voice` and `style`, plus + `personal_voice_model`; the voice name is derived from the avatar. + * `azure-realtime-native`: `voice` and `speed`. + + `format` and `output_audio_timestamp_types` apply to every voice type. +'@ +# NOTE: `types.py` used to be listed here too, but it is now deleted outright (see the fixup +# above) before this point would matter, since its TypedDict mirror of this same class no +# longer exists as a file at all. +$files = 'azure\ai\projects\models\_models.py' +foreach ($f in $files) { + $c = Get-Content $f -Raw + $c = $c.Replace($oldVoiceAudioOutputConfig, $newVoiceAudioOutputConfig) + Set-Content $f $c -NoNewline +} + +$f = 'azure\ai\projects\models\_enums.py' +$c = Get-Content $f -Raw +# NOTE: single-quoted @'...'@ here-strings -- see comment above the VoiceAudioOutputConfig fix for why. +$c = $c.Replace( +@' + * `in_progress`: the live session is active, or post-session persistence finalization is + pending. + * `completed`: finalization succeeded after normal or client close, `end_conversation`, a + max-duration `1001` + close, or a client or network disconnect that the service can still finalize. + * `failed`: a terminal service, bridge, storage, or unrecoverable transport failure prevented + finalization. +'@, +@' + * `in_progress`: the live session is active, or post-session persistence finalization is + pending. + * `completed`: finalization succeeded after normal or client close, `end_conversation`, a + max-duration `1001` + close, or a client or network disconnect that the service can still finalize. + * `failed`: a terminal service, bridge, storage, or unrecoverable transport failure prevented + finalization. +'@ +) +Set-Content $f $c -NoNewline + +# Fix Sphinx docutils "Bullet list ends without a blank line; unexpected unindent" warnings in +# RealtimeServerEventConversationItemAdded and RealtimeServerEventConversationItemCreated +# (models/_models.py). Same root cause and fix pattern as the VoiceAudioOutputConfig/ +# VoiceConversationStatus fixup above: the emitter wraps long bullet-item lines without +# indenting the continuation lines to align with the bullet's text, and (for +# ConversationItemAdded) runs the trailing summary sentence straight into the last bullet with +# no blank line to end the list. See the NOTE above the VoiceAudioOutputConfig fix for why these +# use single-quoted @'...'@ here-strings (this text is full of literal Markdown backticks). +$f = 'azure\ai\projects\models\_models.py' +$c = Get-Content $f -Raw +$c = $c.Replace( +@' + * When the client sends a `conversation.item.create` event. + * When the input audio buffer is committed. In this case the item will be a user message + containing the audio from the buffer. + * When the model is generating a Response. In this case the `conversation.item.added` event + will be sent when the model starts generating a specific Item, and thus it will not yet have + any content (and `status` will be `in_progress`). + The event will include the full content of the Item (except when model is generating a + Response) except for audio data, which can be retrieved separately with a + `conversation.item.retrieve` event if necessary. +'@, +@' + * When the client sends a `conversation.item.create` event. + * When the input audio buffer is committed. In this case the item will be a user message + containing the audio from the buffer. + * When the model is generating a Response. In this case the `conversation.item.added` event + will be sent when the model starts generating a specific Item, and thus it will not yet have + any content (and `status` will be `in_progress`). + + The event will include the full content of the Item (except when model is generating a + Response) except for audio data, which can be retrieved separately with a + `conversation.item.retrieve` event if necessary. +'@ +) +$c = $c.Replace( +@' + * The server is generating a Response, which if successful will produce + either one or two Items, which will be of type `message` + (role `assistant`) or type `function_call`. + * The input audio buffer has been committed, either by the client or the + server (in `server_vad` mode). The server will take the content of the + input audio buffer and add it to a new user message Item. + * The client has sent a `conversation.item.create` event to add a new Item + to the Conversation. +'@, +@' + * The server is generating a Response, which if successful will produce + either one or two Items, which will be of type `message` + (role `assistant`) or type `function_call`. + * The input audio buffer has been committed, either by the client or the + server (in `server_vad` mode). The server will take the content of the + input audio buffer and add it to a new user message Item. + * The client has sent a `conversation.item.create` event to add a new Item + to the Conversation. +'@ +) +Set-Content $f $c -NoNewline + +# NOTE: a block of code in the implementation of "list_memories", in both sync and async +# _operations.py files, used to be emitted in the wrong place (inside the nested +# "prepare_request" function instead of the main method body, right after +# `error_map.update(kwargs.pop("error_map", {}) or {})`), causing a Pyright +# `reportUnboundVariable` failure and test failures. As of TypeSpec commit +# 1070c74ae519b6f86540bbd44ea295ff12642e60, the emitter now produces the correct shape +# directly (verified: `if body is _Unset: ...` appears in the main method body, before +# `def prepare_request(...)`, in both sync and async list_memories() overloads). The fixup +# that used to correct this has been removed since it's no longer needed. If this +# regresses in a future TypeSpec update (Pyright reports "body" is unbound, or this fixup's +# safety check throws because the old broken pattern reappears), reinstate a fixup here. + + +# GenerateAgentRequest is a single-member union in TypeSpec (only GenerateVoiceAgentRequest so +# far), which makes the emitter produce exactly ONE @overload stub for generate_agent. That +# triggers two pyright errors in both sync and async _operations.py: +# - reportInconsistentOverload: a function needs 0 or 2+ @overloads, never exactly 1. +# - reportInvalidTypeForm: the real impl's body param is typed as the bare forward-reference +# string "_unions.GenerateAgentRequest", which isn't a proper importable type (single-member +# unions are emitted as a plain runtime alias, not a type pyright can resolve). +# Fix: drop the redundant single @overload stub entirely, and retype the real implementation's +# body parameter with the concrete model type (matching the overload stub's own type). Add a new +# @overload here (making it 2+) if a second voice/agent kind is ever added upstream instead. +$oldPatternSync = @" + @overload + def generate_agent( + self, body: _models.GenerateVoiceAgentRequest, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentDetails: + """Generate an agent. + + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. + + :param body: The kind-specific inputs for generating and creating an agent. Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def generate_agent(self, body: "_unions.GenerateAgentRequest", **kwargs: Any) -> _models.AgentDetails: +"@ +$newPatternSync = @" + @distributed_trace + def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: +"@ +$oldPatternAsync = @" + @overload + async def generate_agent( + self, body: _models.GenerateVoiceAgentRequest, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentDetails: + """Generate an agent. + + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. + + :param body: The kind-specific inputs for generating and creating an agent. Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def generate_agent(self, body: "_unions.GenerateAgentRequest", **kwargs: Any) -> _models.AgentDetails: +"@ +$newPatternAsync = @" + @distributed_trace_async + async def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: +"@ +$f = 'azure\ai\projects\operations\_operations.py' +$c = Get-Content $f -Raw +$c = $c.Replace($oldPatternSync, $newPatternSync) +Set-Content $f $c -NoNewline +$f = 'azure\ai\projects\aio\operations\_operations.py' +$c = Get-Content $f -Raw +$c = $c.Replace($oldPatternAsync, $newPatternAsync) +Set-Content $f $c -NoNewline + +# VoiceResponse (formerly OmitPropertiesRealtimeResponse before an upstream TypeSpec rename) narrows +# its base class VoiceResponseBase's optional `id`/`conversation_id` (Optional[str]) to required +# `str`, per the TypeSpec spec's explicit "Required." docstrings -- an intentional Azure-specific +# tightening of OpenAI's generic realtime response template (a persisted voice response always has +# both set). Pyright's reportIncompatibleVariableOverride flags this because narrowing a *mutable* +# attribute's type in a subclass isn't sound in general, but it's safe here by construction (the +# service never omits these for a persisted response). This substitution matches on the field +# pattern itself (not the class name), so it keeps working across upstream class renames. +# NOTE: uses -replace with a \r?\n-tolerant regex (not .Replace() with a literal `n), since `n +# always resolves to a bare LF and can never match this file's real CRLF line endings -- the +# $1/$2 replacement backreferences preserve whatever newline the regex actually matched. +$f = 'azure\ai\projects\models\_models.py' +$c = Get-Content $f -Raw +$c = $c -replace '(id: str = rest_field\(visibility=\["read", "create", "update", "delete", "query"\]\))(\r?\n """The unique id of the response\. Required\.""")', '$1 # type: ignore[reportIncompatibleVariableOverride]$2' +$c = $c -replace '(conversation_id: str = rest_field\(visibility=\["read", "create", "update", "delete", "query"\]\))(\r?\n """The id of the conversation this response belongs to\. Required\.""")', '$1 # type: ignore[reportIncompatibleVariableOverride]$2' +Set-Content $f $c -NoNewline + +# VoiceAgentSessionResponse/VoiceAgentSessionUpdate are single-member unions in TypeSpec (only +# VoiceAgentSessionResponseConfig / VoiceAgentSessionUpdateConfig respectively so far), hitting the +# exact same emitter bug as the GenerateAgentRequest case just above: a single-member union is +# recorded in `_unions.py` as a bare forward-reference *string* (e.g. +# `VoiceAgentSessionResponse = "_models.VoiceAgentSessionResponseConfig"`) rather than a real type +# alias, since `Union[X]` collapses to `X` and the emitter's union-alias codegen path isn't taken. +# Every place in `_models.py` that types a field/parameter as `"_unions.VoiceAgentSessionResponse"` +# or `"_unions.VoiceAgentSessionUpdate"` is therefore an invalid forward reference for mypy/pyright +# (`_unions.py`'s `VoiceAgentSessionResponse`/`VoiceAgentSessionUpdate` are plain `str` values at +# runtime, not resolvable types) -- a `[valid-type]` error every round. Fix by pointing the forward +# reference directly at the concrete model instead of routing through `_unions.py`. +$f = 'azure\ai\projects\models\_models.py' +$c = Get-Content $f -Raw +$c = $c.Replace('"_unions.VoiceAgentSessionResponse"', '"_models.VoiceAgentSessionResponseConfig"') +$c = $c.Replace('"_unions.VoiceAgentSessionUpdate"', '"_models.VoiceAgentSessionUpdateConfig"') +Set-Content $f $c -NoNewline + +# `replace_telephony_transfer_targets`'s JSON-body and IO[bytes]-body @overload stubs mistype +# `etag`/`match_condition`: they declare `etag: List[_models.TelephonyTransferTarget]` and +# `match_condition: str`, but the real implementation (and the keyword-only overload) correctly +# type them as `etag: str` / `match_condition: MatchConditions` -- an internally-inconsistent +# emitter bug (mypy: "Overloaded function implementation does not accept all possible arguments of +# signature 2/3"; pyright: "Overloaded implementation is not consistent with signature of overload +# 2/3"). This also breaks the hand-written call in _patch_agents.py/_patch_agents_async.py, whose +# call no longer matches any overload once the impl's real parameter types are considered (pyright: +# "Argument of type ... cannot be assigned to parameter 'body'/'etag'"). Fix both overloads' +# signatures and docstrings in both sync and async _operations.py. +$files = 'azure\ai\projects\operations\_operations.py', 'azure\ai\projects\aio\operations\_operations.py' +foreach ($f in $files) { + $c = Get-Content $f -Raw + $c = $c -replace 'etag: List\[_models\.TelephonyTransferTarget\],(\r?\n\s+)match_condition: str,', 'etag: str,$1match_condition: MatchConditions,' + $c = $c -replace ':paramtype etag: list\[~azure\.ai\.projects\.models\.TelephonyTransferTarget\]', ':paramtype etag: str' + $c = $c -replace ':paramtype match_condition: str', ':paramtype match_condition: ~azure.core.MatchConditions' + Set-Content $f $c -NoNewline +} + +# Regression guard: `_realtime.py` and `aio\_realtime.py` are hand-written files that are NOT +# `_patch.py`-named, so they aren't covered by the emitter's own "never touch _patch.py" guarantee -- +# nothing in the TypeSpec emitter is aware these files exist. They carry the SDK client-identification +# fix ported from the azure-ai-voicelive PR #48848 (a User-Agent header and x-ms-client-sdk query +# parameter, both derived from `_USER_AGENT = UserAgentPolicy(sdk_moniker=...)`, with a case-insensitive +# guard so a caller-supplied extra_headers User-Agent of any casing is honored instead of duplicated). +# If a future `tsp-client update` ever starts generating (and thus silently overwriting) a file at either +# of these paths, this fix would be lost with no other signal until someone happens to run the realtime +# test suite. Fail the emit step immediately instead, right after regeneration, rather than relying on +# that eventual test run. +$realtimeFiles = @('azure\ai\projects\_realtime.py', 'azure\ai\projects\aio\_realtime.py') +foreach ($f in $realtimeFiles) { + if (-not (Test-Path $f)) { + throw "PostEmitter safety check failed: '$f' is missing. This hand-written file (not tracked by the TypeSpec emitter) carries the SDK client-identification fix from PR #48848; if the emitter deleted or renamed it, restore it from git history before continuing." + } + $c = Get-Content $f -Raw + if ($c -notmatch 'UserAgentPolicy\(sdk_moniker=') { + throw "PostEmitter safety check failed: '$f' no longer defines _USER_AGENT via UserAgentPolicy(sdk_moniker=...). The SDK client-identification fix from PR #48848 appears to have been overwritten -- reinstate the User-Agent header + x-ms-client-sdk query param wiring." + } + if ($c -notmatch '_has_header_case_insensitive') { + throw "PostEmitter safety check failed: '$f' no longer guards the User-Agent header with _has_header_case_insensitive. A caller-supplied extra_headers User-Agent (in any casing) would be duplicated instead of honored -- reinstate the case-insensitive check." + } + if ($c -notmatch 'x-ms-client-sdk') { + throw "PostEmitter safety check failed: '$f' no longer sends the x-ms-client-sdk query parameter alongside the User-Agent header -- reinstate it so service telemetry can still attribute traffic on paths that don't forward the header." + } +} +Write-Host "PostEmitter safety check passed: SDK client-identification fix (PR #48848) is intact in both _realtime.py files." + # Finishing by running 'black' tool to format code. pip install black black --config ../../../eng/black-pyproject.toml . diff --git a/sdk/ai/azure-ai-projects/README.md b/sdk/ai/azure-ai-projects/README.md index 6879f2a5e466..4f74d84584c6 100644 --- a/sdk/ai/azure-ai-projects/README.md +++ b/sdk/ai/azure-ai-projects/README.md @@ -191,6 +191,7 @@ The table below lists the operation groups supported by the client library, with | Sessions | [Manage hosted sessions](https://learn.microsoft.com/azure/foundry/agents/how-to/manage-hosted-sessions?pivots=python) | `samples/hosted_agents/` | | Skills (preview) | | `samples/skills/` | | Toolboxes | [Curate intent-based toolbox in Foundry](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox?pivots=python) | `samples/hosted_agents/`, `samples/toolboxes/` | +| Voice agents (preview) | [Use the GPT Realtime API for speech and audio](https://learn.microsoft.com/azure/foundry/openai/how-to/realtime-audio) | `samples/agents/voice/` | ## Client-side tracing diff --git a/sdk/ai/azure-ai-projects/api.md b/sdk/ai/azure-ai-projects/api.md index 56a558a575ea..da2ff279db6a 100644 --- a/sdk/ai/azure-ai-projects/api.md +++ b/sdk/ai/azure-ai-projects/api.md @@ -2,6 +2,7 @@ namespace azure.ai.projects class azure.ai.projects.AIProjectClient(AIProjectClientGenerated): implements ContextManager + property realtime: Realtime # Read-only agents: AgentsOperations beta: BetaOperations connections: ConnectionsOperations @@ -41,9 +42,79 @@ namespace azure.ai.projects ) -> HttpResponse: ... + class azure.ai.projects.Realtime: + + def __init__(self, client: AIProjectClient) -> None: ... + + def connect( + self, + *, + agent_name: str, + agent_session_id: Optional[str] = ..., + agent_version_override: Optional[str] = ..., + api_version: Optional[str] = ..., + connection_url: Optional[str] = ..., + credential_scopes: Optional[List[str]] = ..., + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + foundry_features: str = _VOICE_AGENT_FEATURE_HEADER, + structured_inputs: Optional[str] = ..., + **kwargs: Any + ) -> RealtimeConnectionManager: ... + + + class azure.ai.projects.RealtimeConnection: implements ContextManager + property closed: bool # Read-only + + def __init__(self, connection: ClientConnection) -> None: ... + + def __iter__(self) -> Iterator[ServerEvent]: ... + + def __repr__(self) -> str: ... + + def close( + self, + *, + code: int = 1000, + reason: str = "" + ) -> None: ... + + def recv( + self, + *, + timeout: Optional[float] = ... + ) -> ServerEvent: ... + + def send(self, event: ClientEvent) -> None: ... + + + class azure.ai.projects.RealtimeConnectionManager: implements ContextManager + + def __init__( + self, + *, + agent_name: str, + agent_session_id: Optional[str] = ..., + agent_version_override: Optional[str] = ..., + api_version: str, + connection_url: Optional[str] = ..., + credential: TokenCredential, + credential_scopes: List[str], + endpoint: str, + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + foundry_features: str, + structured_inputs: Optional[str] = ..., + **kwargs: Any + ) -> None: ... + + def enter(self) -> RealtimeConnection: ... + + namespace azure.ai.projects.aio class azure.ai.projects.aio.AIProjectClient(AIProjectClientGenerated): implements AsyncContextManager + property realtime: AsyncRealtime # Read-only agents: AgentsOperations beta: BetaOperations connections: ConnectionsOperations @@ -83,893 +154,1085 @@ namespace azure.ai.projects.aio ) -> Awaitable[AsyncHttpResponse]: ... -namespace azure.ai.projects.aio.operations + class azure.ai.projects.aio.AsyncRealtime: + + def __init__(self, client: AIProjectClient) -> None: ... + + def connect( + self, + *, + agent_name: str, + agent_session_id: Optional[str] = ..., + agent_version_override: Optional[str] = ..., + api_version: Optional[str] = ..., + connection_url: Optional[str] = ..., + credential_scopes: Optional[List[str]] = ..., + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + foundry_features: str = _VOICE_AGENT_FEATURE_HEADER, + structured_inputs: Optional[str] = ..., + **kwargs: Any + ) -> AsyncRealtimeConnectionManager: ... - class azure.ai.projects.aio.operations.AgentsOperations(GeneratedAgentsOperations): + + class azure.ai.projects.aio.AsyncRealtimeConnection: implements AsyncContextManager + property closed: bool # Read-only + + def __aiter__(self) -> AsyncIterator[ServerEvent]: ... def __init__( self, - *args, - **kwargs + connection: ClientWebSocketResponse, + session: ClientSession ) -> None: ... - @overload - async def create_session( + def __repr__(self) -> str: ... + + async def close( self, - agent_name: str, *, - agent_session_id: Optional[str] = ..., - content_type: str = "application/json", - version_indicator: VersionIndicator, - **kwargs: Any - ) -> AgentSessionResource: ... + code: int = 1000, + reason: str = "" + ) -> None: ... - @overload - async def create_session( + async def recv(self) -> ServerEvent: ... + + async def send(self, event: ClientEvent) -> None: ... + + + class azure.ai.projects.aio.AsyncRealtimeConnectionManager: implements AsyncContextManager + + def __init__( self, - agent_name: str, - body: JSON, *, - content_type: str = "application/json", + agent_name: str, + agent_session_id: Optional[str] = ..., + agent_version_override: Optional[str] = ..., + api_version: str, + connection_url: Optional[str] = ..., + credential: AsyncTokenCredential, + credential_scopes: List[str], + endpoint: str, + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + foundry_features: str, + structured_inputs: Optional[str] = ..., **kwargs: Any - ) -> AgentSessionResource: ... + ) -> None: ... - @overload - async def create_session( + async def enter(self) -> AsyncRealtimeConnection: ... + + +namespace azure.ai.projects.aio.operations + + class azure.ai.projects.aio.operations.AgentEndpointConversationsOperations(GeneratedAgentEndpointConversationsOperations): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace_async + async def delete_agent_conversation( self, agent_name: str, - body: IO[bytes], - *, - content_type: str = "application/json", + conversation_id: str, **kwargs: Any - ) -> AgentSessionResource: ... + ) -> None: ... - @overload - async def create_version( + @distributed_trace_async + async def get_agent_conversation( self, agent_name: str, - *, - blueprint_reference: Optional[AgentBlueprintReference] = ..., - content_type: str = "application/json", - definition: AgentDefinition, - description: Optional[str] = ..., - draft: Optional[bool] = ..., - metadata: Optional[dict[str, str]] = ..., + conversation_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> VoiceConversation: ... - @overload - async def create_version( + @distributed_trace_async + async def get_agent_conversation_audio( self, agent_name: str, - body: JSON, - *, - content_type: str = "application/json", + conversation_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> VoiceRecordingResponse: ... - @overload - async def create_version( + @distributed_trace_async + async def get_agent_conversation_audio_content( self, agent_name: str, - body: IO[bytes], - *, - content_type: str = "application/json", + conversation_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> AsyncIterator[bytes]: ... @distributed_trace_async - async def create_version_from_code( + async def get_agent_conversation_item( self, agent_name: str, - *, - code: IO[bytes], - code_zip_sha256: Optional[str] = ..., - definition: HostedAgentDefinition, - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., + conversation_id: str, + item_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> RealtimeConversationItem: ... - @overload - async def create_version_from_manifest( + @distributed_trace_async + async def get_agent_conversation_item_audio( self, agent_name: str, - *, - content_type: str = "application/json", - description: Optional[str] = ..., - manifest_id: str, - metadata: Optional[dict[str, str]] = ..., - parameter_values: dict[str, Any], + conversation_id: str, + item_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> VoiceItemAudioResponse: ... - @overload - async def create_version_from_manifest( + @distributed_trace_async + async def get_agent_conversation_item_audio_content( self, agent_name: str, - body: JSON, - *, - content_type: str = "application/json", + conversation_id: str, + item_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> AsyncIterator[bytes]: ... - @overload - async def create_version_from_manifest( + @distributed_trace_async + async def get_agent_conversation_item_generated_audio( self, agent_name: str, - body: IO[bytes], - *, - content_type: str = "application/json", + conversation_id: str, + item_id: str, **kwargs: Any - ) -> AgentVersionDetails: ... + ) -> VoiceGeneratedItemAudioResponse: ... @distributed_trace_async - async def delete( + async def get_agent_conversation_item_generated_audio_content( self, agent_name: str, - *, - force: Optional[bool] = ..., + conversation_id: str, + item_id: str, **kwargs: Any - ) -> DeleteAgentResponse: ... + ) -> AsyncIterator[bytes]: ... @distributed_trace_async - async def delete_session( + async def get_agent_conversation_response( self, agent_name: str, - session_id: str, + conversation_id: str, + response_id: str, **kwargs: Any - ) -> None: ... + ) -> VoiceResponse: ... - @distributed_trace_async - async def delete_session_file( + @distributed_trace + def list_agent_conversation_items( self, agent_name: str, - session_id: str, + conversation_id: str, *, - path: str, - recursive: Optional[bool] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> None: ... + ) -> AsyncItemPaged[RealtimeConversationItem]: ... - @distributed_trace_async - async def delete_version( + @distributed_trace + def list_agent_conversation_response_items( self, agent_name: str, - agent_version: str, + conversation_id: str, + response_id: str, *, - force: Optional[bool] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> DeleteAgentVersionResponse: ... + ) -> AsyncItemPaged[RealtimeConversationItem]: ... - @distributed_trace_async - async def disable( + @distributed_trace + def list_agent_conversation_responses( self, agent_name: str, + conversation_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> None: ... + ) -> AsyncItemPaged[VoiceResponse]: ... - @distributed_trace_async - async def download_code( + @distributed_trace + def list_agent_conversations( self, agent_name: str, *, - agent_version: Optional[str] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncItemPaged[VoiceConversation]: ... - @distributed_trace_async - async def download_session_file( + + class azure.ai.projects.aio.operations.AgentTelephonyOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def begin_import_telephony_campaign_recipients( self, agent_name: str, - session_id: str, + campaign_id: str, + body: ImportTelephonyCampaignRecipientsRequest, *, - path: str, + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... - @distributed_trace_async - async def enable( + @overload + async def begin_import_telephony_campaign_recipients( self, agent_name: str, + campaign_id: str, + body: JSON, + *, + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> None: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... - @distributed_trace_async - async def get( + @overload + async def begin_import_telephony_campaign_recipients( self, agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> AgentDetails: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... @overload - async def get_microsoft365_package( + async def begin_publish_telephony_campaign( self, agent_name: str, + campaign_id: str, + body: PublishTelephonyCampaignRequest, *, - access_boundaries: Optional[List[Union[str, ActivityProtocolAccessBoundary]]] = ..., - agent_display_name: Optional[str] = ..., - app_version: Optional[str] = ..., - bot_service_arm_id: Optional[str] = ..., - can_respond_without_mention: Optional[bool] = ..., - color_icon_base64: Optional[str] = ..., content_type: str = "application/json", - developer_name: Optional[str] = ..., - developer_website_url: Optional[str] = ..., - full_description: Optional[str] = ..., - optional_permission_scopes: Optional[List[Microsoft365PermissionScopes]] = ..., - outline_icon_base64: Optional[str] = ..., - privacy_url: Optional[str] = ..., - publish_as_autopilot: Optional[bool] = ..., - publish_scope: Union[str, Microsoft365PublishScope], - short_description: Optional[str] = ..., - terms_of_use_url: Optional[str] = ..., **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... @overload - async def get_microsoft365_package( + async def begin_publish_telephony_campaign( self, agent_name: str, + campaign_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... @overload - async def get_microsoft365_package( + async def begin_publish_telephony_campaign( self, agent_name: str, + campaign_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... @distributed_trace_async - async def get_microsoft365_publish_defaults( + async def begin_validate_telephony_campaign( self, agent_name: str, - *, - publish_as_digital_worker: Optional[bool] = ..., + campaign_id: str, **kwargs: Any - ) -> Microsoft365PublishDefaults: ... + ) -> AsyncLROPoller[TelephonyOperationResource]: ... @distributed_trace_async - async def get_session( + async def cancel_telephony_call_job( self, agent_name: str, - session_id: str, + call_job_id: str, + *, + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> AgentSessionResource: ... + ) -> TelephonyCallJob: ... @distributed_trace_async - async def get_session_log_stream( + async def cancel_telephony_campaign( self, agent_name: str, - agent_version: str, - session_id: str, - **kwargs: Any - ) -> SessionLogEvent: ... - - @distributed_trace_async - async def get_version( - self, - agent_name: str, - agent_version: str, - **kwargs: Any - ) -> AgentVersionDetails: ... - - @distributed_trace - def list( - self, - *, - before: Optional[str] = ..., - kind: Optional[Union[str, AgentKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + campaign_id: str, **kwargs: Any - ) -> AsyncItemPaged[AgentDetails]: ... + ) -> TelephonyCampaign: ... - @distributed_trace - def list_session_files( + @overload + async def create_telephony_call_job( self, agent_name: str, - session_id: str, + body: CreateTelephonyCallJobRequest, *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - path: Optional[str] = ..., + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> AsyncItemPaged[SessionDirectoryEntry]: ... + ) -> TelephonyCallJob: ... - @distributed_trace - def list_sessions( + @overload + async def create_telephony_call_job( self, agent_name: str, + body: JSON, *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> AsyncItemPaged[AgentSessionResource]: ... + ) -> TelephonyCallJob: ... - @distributed_trace - def list_versions( + @overload + async def create_telephony_call_job( self, agent_name: str, + body: IO[bytes], *, - before: Optional[str] = ..., - include_drafts: Optional[bool] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> AsyncItemPaged[AgentVersionDetails]: ... + ) -> TelephonyCallJob: ... @overload - async def publish_to_microsoft365( + async def create_telephony_campaign( self, agent_name: str, + body: CreateTelephonyCampaignRequest, *, - access_boundaries: Optional[List[Union[str, ActivityProtocolAccessBoundary]]] = ..., - agent_display_name: Optional[str] = ..., - app_version: Optional[str] = ..., - bot_service_arm_id: Optional[str] = ..., - can_respond_without_mention: Optional[bool] = ..., - color_icon_base64: Optional[str] = ..., content_type: str = "application/json", - developer_name: Optional[str] = ..., - developer_website_url: Optional[str] = ..., - full_description: Optional[str] = ..., - optional_permission_scopes: Optional[List[Microsoft365PermissionScopes]] = ..., - outline_icon_base64: Optional[str] = ..., - privacy_url: Optional[str] = ..., - publish_as_autopilot: Optional[bool] = ..., - publish_scope: Union[str, Microsoft365PublishScope], - short_description: Optional[str] = ..., - terms_of_use_url: Optional[str] = ..., **kwargs: Any - ) -> Microsoft365PublishResult: ... + ) -> TelephonyCampaign: ... @overload - async def publish_to_microsoft365( + async def create_telephony_campaign( self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> Microsoft365PublishResult: ... + ) -> TelephonyCampaign: ... @overload - async def publish_to_microsoft365( + async def create_telephony_campaign( self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> Microsoft365PublishResult: ... + ) -> TelephonyCampaign: ... @distributed_trace_async - async def stop_session( + async def get_telephony_call_job( self, agent_name: str, - session_id: str, + call_job_id: str, + **kwargs: Any + ) -> TelephonyCallJob: ... + + @distributed_trace_async + async def get_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... + + @distributed_trace_async + async def get_telephony_campaign_recipient_import( + self, + agent_name: str, + campaign_id: str, + import_id: str, + **kwargs: Any + ) -> TelephonyCampaignRecipientImport: ... + + @distributed_trace_async + async def get_telephony_operation( + self, + agent_name: str, + operation_id: str, + **kwargs: Any + ) -> TelephonyOperation: ... + + @distributed_trace_async + async def pause_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... + + @distributed_trace_async + async def resume_telephony_campaign( + self, + agent_name: str, + campaign_id: str, **kwargs: Any + ) -> TelephonyCampaign: ... + + + class azure.ai.projects.aio.operations.AgentsOperations(GeneratedAgentsOperations): + + def __init__( + self, + *args, + **kwargs ) -> None: ... @overload - async def update_details( + async def create_session( self, agent_name: str, *, - agent_card: Optional[AgentCard] = ..., - agent_endpoint: Optional[AgentEndpointConfig] = ..., - content_type: str = "application/merge-patch+json", + agent_session_id: Optional[str] = ..., + content_type: str = "application/json", + version_indicator: VersionIndicator, **kwargs: Any - ) -> AgentDetails: ... + ) -> AgentSessionResource: ... @overload - async def update_details( + async def create_session( self, agent_name: str, body: JSON, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> AgentDetails: ... + ) -> AgentSessionResource: ... @overload - async def update_details( + async def create_session( self, agent_name: str, body: IO[bytes], *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> AgentDetails: ... + ) -> AgentSessionResource: ... @overload - async def upload_session_file( + async def create_telephony_binding( self, agent_name: str, - session_id: str, - content: bytes, + body: CreateTelephonyBindingRequest, *, - content_type: str = "application/octet-stream", - path: str, + content_type: str = "application/json", **kwargs: Any - ) -> SessionFileWriteResult: ... + ) -> TelephonyBinding: ... @overload - async def upload_session_file( + async def create_telephony_binding( self, agent_name: str, - session_id: str, - content: IO[bytes], + body: JSON, *, - content_type: str = "application/octet-stream", - path: str, + content_type: str = "application/json", **kwargs: Any - ) -> SessionFileWriteResult: ... + ) -> TelephonyBinding: ... - - class azure.ai.projects.aio.operations.BetaAgentInsightMonitorsOperations(BetaAgentInsightMonitorsOperationsGenerated): - - def __init__( + @overload + async def create_telephony_binding( self, - *args, - **kwargs - ) -> None: ... + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... @overload - async def begin_create_run( + async def create_version( self, - monitor_id: str, - run: AgentInsightRunCreate, + agent_name: str, *, + blueprint_reference: Optional[AgentBlueprintReference] = ..., content_type: str = "application/json", - operation_id: Optional[str] = ..., + definition: AgentDefinition, + description: Optional[str] = ..., + draft: Optional[bool] = ..., + metadata: Optional[dict[str, str]] = ..., **kwargs: Any - ) -> AsyncAgentInsightRunLROPoller: ... + ) -> AgentVersionDetails: ... @overload - async def begin_create_run( + async def create_version( self, - monitor_id: str, - run: JSON, + agent_name: str, + body: JSON, *, content_type: str = "application/json", - operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncAgentInsightRunLROPoller: ... + ) -> AgentVersionDetails: ... @overload - async def begin_create_run( + async def create_version( self, - monitor_id: str, - run: IO[bytes], + agent_name: str, + body: IO[bytes], *, content_type: str = "application/json", - operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncAgentInsightRunLROPoller: ... + ) -> AgentVersionDetails: ... @distributed_trace_async - async def cancel_run( + async def create_version_from_code( self, - monitor_id: str, - run_id: str, + agent_name: str, + *, + code: IO[bytes], + code_zip_sha256: Optional[str] = ..., + definition: HostedAgentDefinition, + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., **kwargs: Any - ) -> AgentInsightRun: ... + ) -> AgentVersionDetails: ... @overload - async def create( + async def create_version_from_manifest( self, - monitor: AgentInsightMonitorCreate, + agent_name: str, *, content_type: str = "application/json", + description: Optional[str] = ..., + manifest_id: str, + metadata: Optional[dict[str, str]] = ..., + parameter_values: dict[str, Any], **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> AgentVersionDetails: ... @overload - async def create( + async def create_version_from_manifest( self, - monitor: JSON, + agent_name: str, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> AgentVersionDetails: ... @overload - async def create( + async def create_version_from_manifest( self, - monitor: IO[bytes], + agent_name: str, + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> AgentVersionDetails: ... @distributed_trace_async async def delete( self, - monitor_id: str, + agent_name: str, + *, + force: Optional[bool] = ..., **kwargs: Any - ) -> None: ... + ) -> DeleteAgentResponse: ... @distributed_trace_async - async def get( + async def delete_session( self, - monitor_id: str, + agent_name: str, + session_id: str, **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> None: ... @distributed_trace_async - async def get_insight( + async def delete_session_file( self, - monitor_id: str, - insight_id: str, + agent_name: str, + session_id: str, *, - include_details: Optional[bool] = ..., + path: str, + recursive: Optional[bool] = ..., **kwargs: Any - ) -> AgentInsight: ... + ) -> None: ... @distributed_trace_async - async def get_run( + async def delete_telephony_binding( self, - monitor_id: str, - run_id: str, + agent_name: str, + binding_id: str, + *, + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> AgentInsightRun: ... + ) -> None: ... - @distributed_trace - def list( + @distributed_trace_async + async def delete_version( self, + agent_name: str, + agent_version: str, *, - agent_name: Optional[str] = ..., - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + force: Optional[bool] = ..., **kwargs: Any - ) -> AsyncItemPaged[AgentInsightMonitorListItem]: ... + ) -> DeleteAgentVersionResponse: ... - @distributed_trace - def list_insights( + @distributed_trace_async + async def disable( self, - monitor_id: str, + agent_name: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def download_code( + self, + agent_name: str, *, - before: Optional[str] = ..., - category: Optional[str] = ..., - include_details: Optional[bool] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - severity: Optional[Union[str, AgentInsightSeverity]] = ..., - status: Optional[Union[str, AgentInsightStatus]] = ..., + agent_version: Optional[str] = ..., **kwargs: Any - ) -> AsyncItemPaged[AgentInsight]: ... + ) -> AsyncIterator[bytes]: ... - @distributed_trace - def list_runs( + @distributed_trace_async + async def download_session_file( self, - monitor_id: str, + agent_name: str, + session_id: str, *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - status: Optional[Union[str, JobStatus]] = ..., - trigger: Optional[Union[str, AgentInsightRunTrigger]] = ..., + path: str, **kwargs: Any - ) -> AsyncItemPaged[AgentInsightRun]: ... + ) -> AsyncIterator[bytes]: ... @distributed_trace_async - async def reset( + async def enable( self, - monitor_id: str, + agent_name: str, **kwargs: Any ) -> None: ... - @overload - async def update( + @distributed_trace_async + async def end_telephony_call( self, - monitor_id: str, - monitor: AgentInsightMonitorUpdate, - *, - content_type: str = "application/merge-patch+json", + agent_name: str, + call_id: str, **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> TelephonyCallRecord: ... - @overload - async def update( + @distributed_trace_async + async def generate_agent( self, - monitor_id: str, - monitor: JSON, - *, - content_type: str = "application/merge-patch+json", + body: GenerateVoiceAgentRequest, **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> AgentDetails: ... - @overload - async def update( + @distributed_trace_async + async def get( self, - monitor_id: str, - monitor: IO[bytes], - *, - content_type: str = "application/merge-patch+json", + agent_name: str, **kwargs: Any - ) -> AgentInsightMonitor: ... + ) -> AgentDetails: ... @overload - async def update_insight( + async def get_microsoft365_package( self, - monitor_id: str, - insight_id: str, - update: AgentInsightUpdate, + agent_name: str, *, - content_type: str = "application/merge-patch+json", + access_boundaries: Optional[List[Union[str, ActivityProtocolAccessBoundary]]] = ..., + agent_display_name: Optional[str] = ..., + app_version: Optional[str] = ..., + bot_service_arm_id: Optional[str] = ..., + can_respond_without_mention: Optional[bool] = ..., + color_icon_base64: Optional[str] = ..., + content_type: str = "application/json", + developer_name: Optional[str] = ..., + developer_website_url: Optional[str] = ..., + full_description: Optional[str] = ..., + optional_permission_scopes: Optional[List[Microsoft365PermissionScopes]] = ..., + outline_icon_base64: Optional[str] = ..., + privacy_url: Optional[str] = ..., + publish_as_autopilot: Optional[bool] = ..., + publish_scope: Union[str, Microsoft365PublishScope], + short_description: Optional[str] = ..., + terms_of_use_url: Optional[str] = ..., **kwargs: Any - ) -> AgentInsight: ... + ) -> AsyncIterator[bytes]: ... @overload - async def update_insight( + async def get_microsoft365_package( self, - monitor_id: str, - insight_id: str, - update: JSON, + agent_name: str, + body: JSON, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> AgentInsight: ... + ) -> AsyncIterator[bytes]: ... @overload - async def update_insight( + async def get_microsoft365_package( self, - monitor_id: str, - insight_id: str, - update: IO[bytes], + agent_name: str, + body: IO[bytes], *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> AgentInsight: ... - - - class azure.ai.projects.aio.operations.BetaAgentsOperations(BetaAgentsOperationsGenerated): + ) -> AsyncIterator[bytes]: ... - def __init__( + @distributed_trace_async + async def get_microsoft365_publish_defaults( self, - *args, - **kwargs - ) -> None: ... + agent_name: str, + *, + publish_as_digital_worker: Optional[bool] = ..., + **kwargs: Any + ) -> Microsoft365PublishDefaults: ... - @overload - async def begin_create_optimization_job( + @distributed_trace_async + async def get_session( self, - job: AgentOptimizationJob, - *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + agent_name: str, + session_id: str, **kwargs: Any - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> AgentSessionResource: ... - @overload - async def begin_create_optimization_job( + @distributed_trace_async + async def get_session_log_stream( self, - job: JSON, - *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + agent_name: str, + agent_version: str, + session_id: str, **kwargs: Any - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> SessionLogEvent: ... - @overload - async def begin_create_optimization_job( + @distributed_trace_async + async def get_telephony_binding( self, - job: IO[bytes], - *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + agent_name: str, + binding_id: str, **kwargs: Any - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> TelephonyBinding: ... @distributed_trace_async - async def cancel_optimization_job( + async def get_telephony_call( self, - job_id: str, + agent_name: str, + call_id: str, **kwargs: Any - ) -> AgentOptimizationJob: ... + ) -> TelephonyCallRecord: ... @distributed_trace_async - async def delete_optimization_job( + async def get_telephony_transfer_targets( self, - job_id: str, + agent_name: str, **kwargs: Any - ) -> None: ... + ) -> TelephonyTransferTargets: ... @distributed_trace_async - async def get_optimization_job( + async def get_version( self, - job_id: str, + agent_name: str, + agent_version: str, **kwargs: Any - ) -> AgentOptimizationJob: ... + ) -> AgentVersionDetails: ... @distributed_trace - def list_optimization_jobs( + def list( self, *, - agent_name: Optional[str] = ..., before: Optional[str] = ..., + kind: Optional[Union[str, AgentKind]] = ..., limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., - status: Optional[Union[str, JobStatus]] = ..., **kwargs: Any - ) -> AsyncItemPaged[AgentOptimizationJobListItem]: ... - - - class azure.ai.projects.aio.operations.BetaDatasetsOperations(BetaDatasetsOperationsGenerated): + ) -> AsyncItemPaged[AgentDetails]: ... - def __init__( + @distributed_trace + def list_session_files( self, - *args, - **kwargs - ) -> None: ... + agent_name: str, + session_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + path: Optional[str] = ..., + **kwargs: Any + ) -> AsyncItemPaged[SessionDirectoryEntry]: ... - @overload - async def begin_create_generation_job( + @distributed_trace + def list_sessions( self, - job: DataGenerationJob, + agent_name: str, *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncDatasetGenerationLROPoller: ... + ) -> AsyncItemPaged[AgentSessionResource]: ... - @overload - async def begin_create_generation_job( + @distributed_trace + def list_telephony_bindings( self, - job: JSON, + agent_name: str, *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ..., **kwargs: Any - ) -> AsyncDatasetGenerationLROPoller: ... + ) -> AsyncItemPaged[TelephonyBindingListItem]: ... - @overload - async def begin_create_generation_job( + @distributed_trace + def list_telephony_calls( self, - job: IO[bytes], + agent_name: str, *, - content_type: str = "application/json", - operation_id: Optional[str] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + started_after: Optional[datetime] = ..., + started_before: Optional[datetime] = ..., + status: Optional[Union[str, TelephonyCallStatus]] = ..., **kwargs: Any - ) -> AsyncDatasetGenerationLROPoller: ... + ) -> AsyncItemPaged[TelephonyCallSummary]: ... - @distributed_trace_async - async def cancel_generation_job( + @distributed_trace + def list_versions( self, - job_id: str, + agent_name: str, + *, + before: Optional[str] = ..., + include_drafts: Optional[bool] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> DataGenerationJob: ... + ) -> AsyncItemPaged[AgentVersionDetails]: ... - @distributed_trace_async - async def delete_generation_job( + @overload + async def publish_to_microsoft365( self, - job_id: str, + agent_name: str, + *, + access_boundaries: Optional[List[Union[str, ActivityProtocolAccessBoundary]]] = ..., + agent_display_name: Optional[str] = ..., + app_version: Optional[str] = ..., + bot_service_arm_id: Optional[str] = ..., + can_respond_without_mention: Optional[bool] = ..., + color_icon_base64: Optional[str] = ..., + content_type: str = "application/json", + developer_name: Optional[str] = ..., + developer_website_url: Optional[str] = ..., + full_description: Optional[str] = ..., + optional_permission_scopes: Optional[List[Microsoft365PermissionScopes]] = ..., + outline_icon_base64: Optional[str] = ..., + privacy_url: Optional[str] = ..., + publish_as_autopilot: Optional[bool] = ..., + publish_scope: Union[str, Microsoft365PublishScope], + short_description: Optional[str] = ..., + terms_of_use_url: Optional[str] = ..., **kwargs: Any - ) -> None: ... + ) -> Microsoft365PublishResult: ... - @distributed_trace_async - async def get_generation_job( + @overload + async def publish_to_microsoft365( self, - job_id: str, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", **kwargs: Any - ) -> DataGenerationJob: ... + ) -> Microsoft365PublishResult: ... - @distributed_trace - def list_generation_jobs( + @overload + async def publish_to_microsoft365( self, + agent_name: str, + body: IO[bytes], *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged[DataGenerationJob]: ... + ) -> Microsoft365PublishResult: ... + + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + transfer_targets: List[TelephonyTransferTarget], + **kwargs: Any + ) -> TelephonyTransferTargets: ... + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyTransferTargets: ... - class azure.ai.projects.aio.operations.BetaEvaluationTaxonomiesOperations: + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyTransferTargets: ... - def __init__( + @distributed_trace_async + async def stop_session( self, - *args, - **kwargs + agent_name: str, + session_id: str, + **kwargs: Any ) -> None: ... @overload - async def create( + async def transfer_telephony_call( self, - name: str, - taxonomy: EvaluationTaxonomy, + agent_name: str, + call_id: str, *, content_type: str = "application/json", + target: str, **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyCallRecord: ... @overload - async def create( + async def transfer_telephony_call( self, - name: str, - taxonomy: JSON, + agent_name: str, + call_id: str, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyCallRecord: ... @overload - async def create( + async def transfer_telephony_call( self, - name: str, - taxonomy: IO[bytes], + agent_name: str, + call_id: str, + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyCallRecord: ... - @distributed_trace_async - async def delete( + @overload + async def update_details( self, - name: str, + agent_name: str, + *, + agent_card: Optional[AgentCard] = ..., + agent_endpoint: Optional[AgentEndpointConfig] = ..., + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> None: ... + ) -> AgentDetails: ... - @distributed_trace_async - async def get( + @overload + async def update_details( self, - name: str, + agent_name: str, + body: JSON, + *, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> AgentDetails: ... - @distributed_trace - def list( + @overload + async def update_details( self, + agent_name: str, + body: IO[bytes], *, - input_name: Optional[str] = ..., - input_type: Optional[str] = ..., + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> AsyncItemPaged[EvaluationTaxonomy]: ... + ) -> AgentDetails: ... @overload - async def update( + async def update_telephony_binding( self, - name: str, - taxonomy: EvaluationTaxonomy, + agent_name: str, + binding_id: str, + body: UpdateTelephonyBindingRequest, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyBinding: ... @overload - async def update( + async def update_telephony_binding( self, - name: str, - taxonomy: JSON, + agent_name: str, + binding_id: str, + body: JSON, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyBinding: ... @overload - async def update( + async def update_telephony_binding( self, - name: str, - taxonomy: IO[bytes], + agent_name: str, + binding_id: str, + body: IO[bytes], *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> EvaluationTaxonomy: ... + ) -> TelephonyBinding: ... + + @overload + async def upload_session_file( + self, + agent_name: str, + session_id: str, + content: bytes, + *, + content_type: str = "application/octet-stream", + path: str, + **kwargs: Any + ) -> SessionFileWriteResult: ... + + @overload + async def upload_session_file( + self, + agent_name: str, + session_id: str, + content: IO[bytes], + *, + content_type: str = "application/octet-stream", + path: str, + **kwargs: Any + ) -> SessionFileWriteResult: ... - class azure.ai.projects.aio.operations.BetaEvaluatorsOperations(BetaEvaluatorsOperationsGenerated): + class azure.ai.projects.aio.operations.BetaAgentInsightMonitorsOperations(BetaAgentInsightMonitorsOperationsGenerated): def __init__( self, @@ -978,232 +1241,216 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def begin_create_generation_job( + async def begin_create_run( self, - job: EvaluatorGenerationJob, + monitor_id: str, + run: AgentInsightRunCreate, *, content_type: str = "application/json", operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncEvaluatorGenerationLROPoller: ... + ) -> AsyncAgentInsightRunLROPoller: ... @overload - async def begin_create_generation_job( + async def begin_create_run( self, - job: JSON, + monitor_id: str, + run: JSON, *, content_type: str = "application/json", operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncEvaluatorGenerationLROPoller: ... + ) -> AsyncAgentInsightRunLROPoller: ... @overload - async def begin_create_generation_job( + async def begin_create_run( self, - job: IO[bytes], + monitor_id: str, + run: IO[bytes], *, content_type: str = "application/json", operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncEvaluatorGenerationLROPoller: ... + ) -> AsyncAgentInsightRunLROPoller: ... @distributed_trace_async - async def cancel_generation_job( + async def cancel_run( self, - job_id: str, + monitor_id: str, + run_id: str, **kwargs: Any - ) -> EvaluatorGenerationJob: ... + ) -> AgentInsightRun: ... @overload - async def create_version( + async def create( self, - name: str, - evaluator_version: EvaluatorVersion, + monitor: AgentInsightMonitorCreate, *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsightMonitor: ... @overload - async def create_version( + async def create( self, - name: str, - evaluator_version: JSON, + monitor: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsightMonitor: ... @overload - async def create_version( + async def create( self, - name: str, - evaluator_version: IO[bytes], + monitor: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsightMonitor: ... @distributed_trace_async - async def delete_generation_job( + async def delete( self, - job_id: str, + monitor_id: str, **kwargs: Any ) -> None: ... @distributed_trace_async - async def delete_version( + async def get( self, - name: str, - version: str, + monitor_id: str, **kwargs: Any - ) -> None: ... + ) -> AgentInsightMonitor: ... - @overload - async def get_credentials( + @distributed_trace_async + async def get_insight( self, - name: str, - version: str, - credential_request: EvaluatorCredentialRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> DatasetCredential: ... - - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> DatasetCredential: ... - - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: IO[bytes], + monitor_id: str, + insight_id: str, *, - content_type: str = "application/json", - **kwargs: Any - ) -> DatasetCredential: ... - - @distributed_trace_async - async def get_generation_job( - self, - job_id: str, + include_details: Optional[bool] = ..., **kwargs: Any - ) -> EvaluatorGenerationJob: ... + ) -> AgentInsight: ... @distributed_trace_async - async def get_version( + async def get_run( self, - name: str, - version: str, + monitor_id: str, + run_id: str, **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsightRun: ... @distributed_trace def list( self, *, + agent_name: Optional[str] = ..., + before: Optional[str] = ..., limit: Optional[int] = ..., - type: Optional[Union[Literal[builtin], Literal[custom], Literal[all], str]] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncItemPaged[EvaluatorVersion]: ... + ) -> AsyncItemPaged[AgentInsightMonitorListItem]: ... @distributed_trace - def list_generation_jobs( + def list_insights( self, + monitor_id: str, *, before: Optional[str] = ..., + category: Optional[str] = ..., + include_details: Optional[bool] = ..., limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., + severity: Optional[Union[str, AgentInsightSeverity]] = ..., + status: Optional[Union[str, AgentInsightStatus]] = ..., **kwargs: Any - ) -> AsyncItemPaged[EvaluatorGenerationJob]: ... + ) -> AsyncItemPaged[AgentInsight]: ... @distributed_trace - def list_versions( + def list_runs( self, - name: str, + monitor_id: str, *, + before: Optional[str] = ..., limit: Optional[int] = ..., - type: Optional[Union[Literal[builtin], Literal[custom], Literal[all], str]] = ..., + order: Optional[Union[str, PageOrder]] = ..., + status: Optional[Union[str, JobStatus]] = ..., + trigger: Optional[Union[str, AgentInsightRunTrigger]] = ..., **kwargs: Any - ) -> AsyncItemPaged[EvaluatorVersion]: ... + ) -> AsyncItemPaged[AgentInsightRun]: ... + + @distributed_trace_async + async def reset( + self, + monitor_id: str, + **kwargs: Any + ) -> None: ... @overload - async def pending_upload( + async def update( self, - name: str, - version: str, - pending_upload_request: PendingUploadRequest, + monitor_id: str, + monitor: AgentInsightMonitorUpdate, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AgentInsightMonitor: ... @overload - async def pending_upload( + async def update( self, - name: str, - version: str, - pending_upload_request: JSON, + monitor_id: str, + monitor: JSON, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AgentInsightMonitor: ... @overload - async def pending_upload( + async def update( self, - name: str, - version: str, - pending_upload_request: IO[bytes], + monitor_id: str, + monitor: IO[bytes], *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AgentInsightMonitor: ... @overload - async def update_version( + async def update_insight( self, - name: str, - version: str, - evaluator_version: EvaluatorVersion, + monitor_id: str, + insight_id: str, + update: AgentInsightUpdate, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsight: ... @overload - async def update_version( + async def update_insight( self, - name: str, - version: str, - evaluator_version: JSON, + monitor_id: str, + insight_id: str, + update: JSON, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsight: ... @overload - async def update_version( + async def update_insight( self, - name: str, - version: str, - evaluator_version: IO[bytes], + monitor_id: str, + insight_id: str, + update: IO[bytes], *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> EvaluatorVersion: ... + ) -> AgentInsight: ... - class azure.ai.projects.aio.operations.BetaInsightsOperations: + class azure.ai.projects.aio.operations.BetaAgentsOperations(BetaAgentsOperationsGenerated): def __init__( self, @@ -1212,55 +1459,70 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def generate( + async def begin_create_optimization_job( self, - insight: Insight, + job: AgentOptimizationJob, *, content_type: str = "application/json", + operation_id: Optional[str] = ..., **kwargs: Any - ) -> Insight: ... + ) -> AsyncAgentOptimizationLROPoller: ... @overload - async def generate( + async def begin_create_optimization_job( self, - insight: JSON, + job: JSON, *, content_type: str = "application/json", + operation_id: Optional[str] = ..., **kwargs: Any - ) -> Insight: ... + ) -> AsyncAgentOptimizationLROPoller: ... @overload - async def generate( + async def begin_create_optimization_job( self, - insight: IO[bytes], + job: IO[bytes], *, content_type: str = "application/json", + operation_id: Optional[str] = ..., **kwargs: Any - ) -> Insight: ... + ) -> AsyncAgentOptimizationLROPoller: ... @distributed_trace_async - async def get( + async def cancel_optimization_job( self, - insight_id: str, - *, - include_coordinates: Optional[bool] = ..., + job_id: str, **kwargs: Any - ) -> Insight: ... + ) -> AgentOptimizationJob: ... + + @distributed_trace_async + async def delete_optimization_job( + self, + job_id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get_optimization_job( + self, + job_id: str, + **kwargs: Any + ) -> AgentOptimizationJob: ... @distributed_trace - def list( + def list_optimization_jobs( self, *, agent_name: Optional[str] = ..., - eval_id: Optional[str] = ..., - include_coordinates: Optional[bool] = ..., - run_id: Optional[str] = ..., - type: Optional[Union[str, InsightType]] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + status: Optional[Union[str, JobStatus]] = ..., **kwargs: Any - ) -> AsyncItemPaged[Insight]: ... + ) -> AsyncItemPaged[AgentOptimizationJobListItem]: ... - class azure.ai.projects.aio.operations.BetaMemoryStoresOperations(GenerateBetaMemoryStoresOperations): + class azure.ai.projects.aio.operations.BetaDatasetsOperations(BetaDatasetsOperationsGenerated): def __init__( self, @@ -1269,454 +1531,336 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def begin_update_memories( + async def begin_create_generation_job( self, - name: str, + job: DataGenerationJob, *, content_type: str = "application/json", - items: Optional[Union[str, ResponseInputParam]] = ..., - previous_update_id: Optional[str] = ..., - scope: str, - update_delay: Optional[int] = ..., + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncUpdateMemoriesLROPoller: ... + ) -> AsyncDatasetGenerationLROPoller: ... @overload - async def begin_update_memories( + async def begin_create_generation_job( self, - name: str, - body: JSON, + job: JSON, *, content_type: str = "application/json", + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncUpdateMemoriesLROPoller: ... + ) -> AsyncDatasetGenerationLROPoller: ... @overload - async def begin_update_memories( + async def begin_create_generation_job( self, - name: str, - body: IO[bytes], + job: IO[bytes], *, content_type: str = "application/json", + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncUpdateMemoriesLROPoller: ... + ) -> AsyncDatasetGenerationLROPoller: ... - @overload - async def create( + @distributed_trace_async + async def cancel_generation_job( self, - *, - content_type: str = "application/json", - definition: MemoryStoreDefinition, - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., - name: str, + job_id: str, **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> DataGenerationJob: ... - @overload - async def create( + @distributed_trace_async + async def delete_generation_job( self, - body: JSON, - *, - content_type: str = "application/json", + job_id: str, **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> None: ... - @overload - async def create( + @distributed_trace_async + async def get_generation_job( + self, + job_id: str, + **kwargs: Any + ) -> DataGenerationJob: ... + + @distributed_trace + def list_generation_jobs( self, - body: IO[bytes], *, - content_type: str = "application/json", + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> AsyncItemPaged[DataGenerationJob]: ... + + + class azure.ai.projects.aio.operations.BetaEvaluationTaxonomiesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... @overload - async def create_memory( + async def create( self, name: str, + taxonomy: EvaluationTaxonomy, *, - content: str, content_type: str = "application/json", - kind: Union[str, MemoryItemKind], - scope: str, **kwargs: Any - ) -> MemoryItem: ... + ) -> EvaluationTaxonomy: ... @overload - async def create_memory( + async def create( self, name: str, - body: JSON, + taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> EvaluationTaxonomy: ... @overload - async def create_memory( + async def create( self, name: str, - body: IO[bytes], + taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> EvaluationTaxonomy: ... @distributed_trace_async async def delete( self, name: str, **kwargs: Any - ) -> DeleteMemoryStoreResult: ... + ) -> None: ... @distributed_trace_async - async def delete_memory( + async def get( self, name: str, - memory_id: str, **kwargs: Any - ) -> DeleteMemoryResult: ... + ) -> EvaluationTaxonomy: ... - @overload - async def delete_scope( + @distributed_trace + def list( self, - name: str, *, - content_type: str = "application/json", - scope: str, + input_name: Optional[str] = ..., + input_type: Optional[str] = ..., **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> AsyncItemPaged[EvaluationTaxonomy]: ... @overload - async def delete_scope( + async def update( self, name: str, - body: JSON, + taxonomy: EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> EvaluationTaxonomy: ... @overload - async def delete_scope( + async def update( self, name: str, - body: IO[bytes], + taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> EvaluationTaxonomy: ... - @distributed_trace_async - async def get( + @overload + async def update( self, name: str, + taxonomy: IO[bytes], + *, + content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> EvaluationTaxonomy: ... - @distributed_trace_async - async def get_memory( - self, - name: str, - memory_id: str, - **kwargs: Any - ) -> MemoryItem: ... - @distributed_trace - def list( + class azure.ai.projects.aio.operations.BetaEvaluatorsOperations(BetaEvaluatorsOperationsGenerated): + + def __init__( self, - *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - **kwargs: Any - ) -> AsyncItemPaged[MemoryStoreDetails]: ... + *args, + **kwargs + ) -> None: ... @overload - def list_memories( + async def begin_create_generation_job( self, - name: str, + job: EvaluatorGenerationJob, *, - before: Optional[str] = ..., content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - scope: str, + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncItemPaged[MemoryItem]: ... + ) -> AsyncEvaluatorGenerationLROPoller: ... @overload - def list_memories( + async def begin_create_generation_job( self, - name: str, - body: JSON, + job: JSON, *, - before: Optional[str] = ..., content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncItemPaged[MemoryItem]: ... + ) -> AsyncEvaluatorGenerationLROPoller: ... @overload - def list_memories( + async def begin_create_generation_job( self, - name: str, - body: IO[bytes], + job: IO[bytes], *, - before: Optional[str] = ..., content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + operation_id: Optional[str] = ..., **kwargs: Any - ) -> AsyncItemPaged[MemoryItem]: ... + ) -> AsyncEvaluatorGenerationLROPoller: ... - @overload - async def search_memories( + @distributed_trace_async + async def cancel_generation_job( self, - name: str, - *, - content_type: str = "application/json", - items: Optional[Union[str, ResponseInputParam]] = ..., - options: Optional[MemorySearchOptions] = ..., - previous_search_id: Optional[str] = ..., - scope: str, + job_id: str, **kwargs: Any - ) -> MemoryStoreSearchResult: ... + ) -> EvaluatorGenerationJob: ... @overload - async def search_memories( + async def create_version( self, name: str, - body: JSON, + evaluator_version: EvaluatorVersion, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreSearchResult: ... + ) -> EvaluatorVersion: ... @overload - async def search_memories( + async def create_version( self, name: str, - body: IO[bytes], + evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreSearchResult: ... + ) -> EvaluatorVersion: ... @overload - async def update( + async def create_version( self, name: str, + evaluator_version: IO[bytes], *, content_type: str = "application/json", - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> EvaluatorVersion: ... - @overload - async def update( + @distributed_trace_async + async def delete_generation_job( self, - name: str, - body: JSON, - *, - content_type: str = "application/json", + job_id: str, **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> None: ... - @overload - async def update( + @distributed_trace_async + async def delete_version( self, name: str, - body: IO[bytes], - *, - content_type: str = "application/json", + version: str, **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> None: ... @overload - async def update_memory( + async def get_credentials( self, name: str, - memory_id: str, + version: str, + credential_request: EvaluatorCredentialRequest, *, - content: str, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> DatasetCredential: ... @overload - async def update_memory( + async def get_credentials( self, name: str, - memory_id: str, - body: JSON, + version: str, + credential_request: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> DatasetCredential: ... @overload - async def update_memory( + async def get_credentials( self, name: str, - memory_id: str, - body: IO[bytes], + version: str, + credential_request: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... - - - class azure.ai.projects.aio.operations.BetaModelsOperations(BetaModelsOperationsGenerated): + ) -> DatasetCredential: ... - def __init__( + @distributed_trace_async + async def get_generation_job( self, - *args, - **kwargs - ) -> None: ... + job_id: str, + **kwargs: Any + ) -> EvaluatorGenerationJob: ... - @overload - async def create( + @distributed_trace_async + async def get_version( self, - *, - base_model: Optional[str] = ..., - description: Optional[str] = ..., name: str, - polling_interval: float = 2.0, - polling_timeout: float = 300.0, - source: Union[str, PathLike[str]], - tags: Optional[dict[str, str]] = ..., version: str, - wait_for_commit: Literal[True] = True, - weight_type: Optional[str] = ..., **kwargs: Any - ) -> ModelVersion: ... + ) -> EvaluatorVersion: ... - @overload - async def create( + @distributed_trace + def list( self, *, - base_model: Optional[str] = ..., - description: Optional[str] = ..., - name: str, - polling_interval: float = 2.0, - polling_timeout: float = 300.0, - source: Union[str, PathLike[str]], - tags: Optional[dict[str, str]] = ..., - version: str, - wait_for_commit: Literal[False], - weight_type: Optional[str] = ..., - **kwargs: Any - ) -> None: ... - - @distributed_trace_async - async def delete( - self, - name: str, - version: str, - **kwargs: Any - ) -> None: ... - - @distributed_trace_async - async def get( - self, - name: str, - version: str, - **kwargs: Any - ) -> ModelVersion: ... - - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: ModelCredentialRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> DatasetCredential: ... - - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", + limit: Optional[int] = ..., + type: Optional[Union[Literal[builtin], Literal[custom], Literal[all], str]] = ..., **kwargs: Any - ) -> DatasetCredential: ... + ) -> AsyncItemPaged[EvaluatorVersion]: ... - @overload - async def get_credentials( + @distributed_trace + def list_generation_jobs( self, - name: str, - version: str, - credential_request: IO[bytes], *, - content_type: str = "application/json", + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> DatasetCredential: ... - - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[ModelVersion]: ... + ) -> AsyncItemPaged[EvaluatorGenerationJob]: ... @distributed_trace def list_versions( self, name: str, - **kwargs: Any - ) -> AsyncItemPaged[ModelVersion]: ... - - @overload - async def pending_create_version( - self, - name: str, - version: str, - model_version: ModelVersion, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> CreateAsyncResponse: ... - - @overload - async def pending_create_version( - self, - name: str, - version: str, - model_version: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> CreateAsyncResponse: ... - - @overload - async def pending_create_version( - self, - name: str, - version: str, - model_version: IO[bytes], *, - content_type: str = "application/json", + limit: Optional[int] = ..., + type: Optional[Union[Literal[builtin], Literal[custom], Literal[all], str]] = ..., **kwargs: Any - ) -> CreateAsyncResponse: ... + ) -> AsyncItemPaged[EvaluatorVersion]: ... @overload async def pending_upload( self, name: str, version: str, - pending_upload_request: ModelPendingUploadRequest, + pending_upload_request: PendingUploadRequest, *, content_type: str = "application/json", **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> PendingUploadResponse: ... @overload async def pending_upload( @@ -1727,7 +1871,7 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> PendingUploadResponse: ... @overload async def pending_upload( @@ -1738,64 +1882,43 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> PendingUploadResponse: ... @overload - async def update( + async def update_version( self, name: str, version: str, - model_version_update: UpdateModelVersionRequest, + evaluator_version: EvaluatorVersion, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> ModelVersion: ... + ) -> EvaluatorVersion: ... @overload - async def update( + async def update_version( self, name: str, version: str, - model_version_update: JSON, + evaluator_version: JSON, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> ModelVersion: ... + ) -> EvaluatorVersion: ... @overload - async def update( + async def update_version( self, name: str, version: str, - model_version_update: IO[bytes], + evaluator_version: IO[bytes], *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> ModelVersion: ... - - - class azure.ai.projects.aio.operations.BetaOperations(GeneratedBetaOperations): - agent_insight_monitors: BetaAgentInsightMonitorsOperations - agents: BetaAgentsOperations - datasets: BetaDatasetsOperations - evaluation_taxonomies: BetaEvaluationTaxonomiesOperations - evaluators: BetaEvaluatorsOperations - insights: BetaInsightsOperations - memory_stores: BetaMemoryStoresOperations - models: BetaModelsOperations - red_teams: BetaRedTeamsOperations - routines: BetaRoutinesOperations - schedules: BetaSchedulesOperations - skills: BetaSkillsOperations - - def __init__( - self, - *args: Any, + content_type: str = "application/json", **kwargs: Any - ) -> None: ... + ) -> EvaluatorVersion: ... - class azure.ai.projects.aio.operations.BetaRedTeamsOperations: + class azure.ai.projects.aio.operations.BetaInsightsOperations: def __init__( self, @@ -1804,44 +1927,55 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create( + async def generate( self, - red_team: RedTeam, + insight: Insight, *, content_type: str = "application/json", **kwargs: Any - ) -> RedTeam: ... + ) -> Insight: ... @overload - async def create( + async def generate( self, - red_team: JSON, + insight: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> RedTeam: ... + ) -> Insight: ... @overload - async def create( + async def generate( self, - red_team: IO[bytes], + insight: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> RedTeam: ... + ) -> Insight: ... @distributed_trace_async async def get( self, - name: str, + insight_id: str, + *, + include_coordinates: Optional[bool] = ..., **kwargs: Any - ) -> RedTeam: ... + ) -> Insight: ... @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[RedTeam]: ... + def list( + self, + *, + agent_name: Optional[str] = ..., + eval_id: Optional[str] = ..., + include_coordinates: Optional[bool] = ..., + run_id: Optional[str] = ..., + type: Optional[Union[str, InsightType]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Insight]: ... - class azure.ai.projects.aio.operations.BetaRoutinesOperations: + class azure.ai.projects.aio.operations.BetaMemoryStoresOperations(GenerateBetaMemoryStoresOperations): def __init__( self, @@ -1850,320 +1984,244 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create_or_update( + async def begin_update_memories( self, - routine_name: str, + name: str, *, - action: Optional[RoutineAction] = ..., - authorization: Optional[RoutineAuthorization] = ..., content_type: str = "application/json", - description: Optional[str] = ..., - enabled: Optional[bool] = ..., - triggers: Optional[dict[str, RoutineTrigger]] = ..., + items: Optional[Union[str, ResponseInputParam]] = ..., + previous_update_id: Optional[str] = ..., + scope: str, + update_delay: Optional[int] = ..., **kwargs: Any - ) -> Routine: ... + ) -> AsyncUpdateMemoriesLROPoller: ... @overload - async def create_or_update( + async def begin_update_memories( self, - routine_name: str, + name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> Routine: ... + ) -> AsyncUpdateMemoriesLROPoller: ... @overload - async def create_or_update( + async def begin_update_memories( self, - routine_name: str, + name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> Routine: ... - - @distributed_trace_async - async def delete( - self, - routine_name: str, - **kwargs: Any - ) -> None: ... - - @distributed_trace_async - async def disable( - self, - routine_name: str, - **kwargs: Any - ) -> Routine: ... + ) -> AsyncUpdateMemoriesLROPoller: ... @overload - async def dispatch( + async def create( self, - routine_name: str, *, content_type: str = "application/json", - payload: Optional[RoutineDispatchPayload] = ..., + definition: MemoryStoreDefinition, + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., + name: str, **kwargs: Any - ) -> DispatchRoutineResult: ... + ) -> MemoryStoreDetails: ... @overload - async def dispatch( + async def create( self, - routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> DispatchRoutineResult: ... + ) -> MemoryStoreDetails: ... @overload - async def dispatch( + async def create( self, - routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> DispatchRoutineResult: ... - - @distributed_trace_async - async def enable( - self, - routine_name: str, - **kwargs: Any - ) -> Routine: ... - - @distributed_trace_async - async def get( - self, - routine_name: str, - **kwargs: Any - ) -> Routine: ... - - @distributed_trace - def list( - self, - *, - after: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - **kwargs: Any - ) -> AsyncItemPaged[Routine]: ... - - @distributed_trace - def list_runs( - self, - routine_name: str, - *, - after: Optional[str] = ..., - filter: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - **kwargs: Any - ) -> AsyncItemPaged[RoutineRun]: ... - - - class azure.ai.projects.aio.operations.BetaSchedulesOperations: - - def __init__( - self, - *args, - **kwargs - ) -> None: ... + ) -> MemoryStoreDetails: ... @overload - async def create_or_update( + async def create_memory( self, - schedule_id: str, - schedule: Schedule, + name: str, *, + content: str, content_type: str = "application/json", + kind: Union[str, MemoryItemKind], + scope: str, **kwargs: Any - ) -> Schedule: ... + ) -> MemoryItem: ... @overload - async def create_or_update( + async def create_memory( self, - schedule_id: str, - schedule: JSON, + name: str, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> Schedule: ... + ) -> MemoryItem: ... @overload - async def create_or_update( + async def create_memory( self, - schedule_id: str, - schedule: IO[bytes], + name: str, + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> Schedule: ... + ) -> MemoryItem: ... @distributed_trace_async async def delete( self, - schedule_id: str, - **kwargs: Any - ) -> None: ... - - @distributed_trace_async - async def get( - self, - schedule_id: str, + name: str, **kwargs: Any - ) -> Schedule: ... + ) -> DeleteMemoryStoreResult: ... @distributed_trace_async - async def get_run( - self, - schedule_id: str, - run_id: str, - **kwargs: Any - ) -> ScheduleRun: ... - - @distributed_trace - def list( - self, - *, - enabled: Optional[bool] = ..., - type: Optional[Union[str, ScheduleTaskType]] = ..., - **kwargs: Any - ) -> AsyncItemPaged[Schedule]: ... - - @distributed_trace - def list_runs( + async def delete_memory( self, - schedule_id: str, - *, - enabled: Optional[bool] = ..., - type: Optional[Union[str, ScheduleTaskType]] = ..., + name: str, + memory_id: str, **kwargs: Any - ) -> AsyncItemPaged[ScheduleRun]: ... - - - class azure.ai.projects.aio.operations.BetaSkillsOperations: - - def __init__( - self, - *args, - **kwargs - ) -> None: ... + ) -> DeleteMemoryResult: ... @overload - async def create( + async def delete_scope( self, name: str, *, content_type: str = "application/json", - default: Optional[bool] = ..., - inline_content: Optional[SkillInlineContent] = ..., + scope: str, **kwargs: Any - ) -> SkillVersion: ... + ) -> MemoryStoreDeleteScopeResult: ... @overload - async def create( + async def delete_scope( self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> SkillVersion: ... + ) -> MemoryStoreDeleteScopeResult: ... @overload - async def create( + async def delete_scope( self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> SkillVersion: ... - - @overload - async def create_from_files( - self, - name: str, - content: CreateSkillVersionFromFilesBody, - **kwargs: Any - ) -> SkillVersion: ... + ) -> MemoryStoreDeleteScopeResult: ... - @overload - async def create_from_files( + @distributed_trace_async + async def get( self, name: str, - content: JSON, **kwargs: Any - ) -> SkillVersion: ... + ) -> MemoryStoreDetails: ... @distributed_trace_async - async def delete( + async def get_memory( self, name: str, + memory_id: str, **kwargs: Any - ) -> DeleteSkillResult: ... + ) -> MemoryItem: ... - @distributed_trace_async - async def delete_version( + @distributed_trace + def list( self, - name: str, - version: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> DeleteSkillVersionResult: ... + ) -> AsyncItemPaged[MemoryStoreDetails]: ... - @distributed_trace_async - async def download( + @overload + def list_memories( self, name: str, + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + scope: str, **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncItemPaged[MemoryItem]: ... - @distributed_trace_async - async def download_version( + @overload + def list_memories( self, name: str, - version: str, + body: JSON, + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncIterator[bytes]: ... + ) -> AsyncItemPaged[MemoryItem]: ... - @distributed_trace_async - async def get( + @overload + def list_memories( self, name: str, + body: IO[bytes], + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> SkillDetails: ... + ) -> AsyncItemPaged[MemoryItem]: ... - @distributed_trace_async - async def get_version( + @overload + async def search_memories( self, name: str, - version: str, + *, + content_type: str = "application/json", + items: Optional[Union[str, ResponseInputParam]] = ..., + options: Optional[MemorySearchOptions] = ..., + previous_search_id: Optional[str] = ..., + scope: str, **kwargs: Any - ) -> SkillVersion: ... + ) -> MemoryStoreSearchResult: ... - @distributed_trace - def list( + @overload + async def search_memories( self, + name: str, + body: JSON, *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged[SkillDetails]: ... + ) -> MemoryStoreSearchResult: ... - @distributed_trace - def list_versions( + @overload + async def search_memories( self, name: str, + body: IO[bytes], *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged[SkillVersion]: ... + ) -> MemoryStoreSearchResult: ... @overload async def update( @@ -2171,9 +2229,10 @@ namespace azure.ai.projects.aio.operations name: str, *, content_type: str = "application/json", - default_version: str, + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., **kwargs: Any - ) -> SkillDetails: ... + ) -> MemoryStoreDetails: ... @overload async def update( @@ -2183,7 +2242,7 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> SkillDetails: ... + ) -> MemoryStoreDetails: ... @overload async def update( @@ -2193,46 +2252,43 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> SkillDetails: ... - - - class azure.ai.projects.aio.operations.ConnectionsOperations(ConnectionsOperationsGenerated): + ) -> MemoryStoreDetails: ... - def __init__( - self, - *args, - **kwargs - ) -> None: ... - - @distributed_trace_async - async def get( + @overload + async def update_memory( self, name: str, + memory_id: str, *, - include_credentials: Optional[bool] = False, + content: str, + content_type: str = "application/json", **kwargs: Any - ) -> Connection: ... + ) -> MemoryItem: ... - @distributed_trace_async - async def get_default( + @overload + async def update_memory( self, - connection_type: Union[str, ConnectionType], + name: str, + memory_id: str, + body: JSON, *, - include_credentials: Optional[bool] = False, + content_type: str = "application/json", **kwargs: Any - ) -> Connection: ... + ) -> MemoryItem: ... - @distributed_trace - def list( + @overload + async def update_memory( self, + name: str, + memory_id: str, + body: IO[bytes], *, - connection_type: Optional[Union[str, ConnectionType]] = ..., - default_connection: Optional[bool] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged[Connection]: ... + ) -> MemoryItem: ... - class azure.ai.projects.aio.operations.DatasetsOperations(DatasetsOperationsGenerated): + class azure.ai.projects.aio.operations.BetaModelsOperations(BetaModelsOperationsGenerated): def __init__( self, @@ -2241,37 +2297,38 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create_or_update( + async def create( self, - name: str, - version: str, - dataset_version: DatasetVersion, *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> DatasetVersion: ... - - @overload - async def create_or_update( - self, + base_model: Optional[str] = ..., + description: Optional[str] = ..., name: str, + polling_interval: float = 2.0, + polling_timeout: float = 300.0, + source: Union[str, PathLike[str]], + tags: Optional[dict[str, str]] = ..., version: str, - dataset_version: JSON, - *, - content_type: str = "application/merge-patch+json", + wait_for_commit: Literal[True] = True, + weight_type: Optional[str] = ..., **kwargs: Any - ) -> DatasetVersion: ... + ) -> ModelVersion: ... @overload - async def create_or_update( + async def create( self, + *, + base_model: Optional[str] = ..., + description: Optional[str] = ..., name: str, + polling_interval: float = 2.0, + polling_timeout: float = 300.0, + source: Union[str, PathLike[str]], + tags: Optional[dict[str, str]] = ..., version: str, - dataset_version: IO[bytes], - *, - content_type: str = "application/merge-patch+json", + wait_for_commit: Literal[False], + weight_type: Optional[str] = ..., **kwargs: Any - ) -> DatasetVersion: ... + ) -> None: ... @distributed_trace_async async def delete( @@ -2287,36 +2344,94 @@ namespace azure.ai.projects.aio.operations name: str, version: str, **kwargs: Any - ) -> DatasetVersion: ... + ) -> ModelVersion: ... - @distributed_trace_async + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: ModelCredentialRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> DatasetCredential: ... + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> DatasetCredential: ... + + @overload async def get_credentials( self, name: str, version: str, + credential_request: IO[bytes], + *, + content_type: str = "application/json", **kwargs: Any ) -> DatasetCredential: ... @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[DatasetVersion]: ... + def list(self, **kwargs: Any) -> AsyncItemPaged[ModelVersion]: ... @distributed_trace def list_versions( self, name: str, **kwargs: Any - ) -> AsyncItemPaged[DatasetVersion]: ... + ) -> AsyncItemPaged[ModelVersion]: ... + + @overload + async def pending_create_version( + self, + name: str, + version: str, + model_version: ModelVersion, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> CreateAsyncResponse: ... + + @overload + async def pending_create_version( + self, + name: str, + version: str, + model_version: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> CreateAsyncResponse: ... + + @overload + async def pending_create_version( + self, + name: str, + version: str, + model_version: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> CreateAsyncResponse: ... @overload async def pending_upload( self, name: str, version: str, - pending_upload_request: PendingUploadRequest, + pending_upload_request: ModelPendingUploadRequest, *, content_type: str = "application/json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> ModelPendingUploadResponse: ... @overload async def pending_upload( @@ -2327,7 +2442,7 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> ModelPendingUploadResponse: ... @overload async def pending_upload( @@ -2338,59 +2453,64 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> ModelPendingUploadResponse: ... - @distributed_trace_async - async def upload_file( + @overload + async def update( self, - *, - connection_name: Optional[str] = ..., - file_path: str, name: str, version: str, + model_version_update: UpdateModelVersionRequest, + *, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> FileDatasetVersion: ... + ) -> ModelVersion: ... - @distributed_trace_async - async def upload_folder( + @overload + async def update( self, - *, - connection_name: Optional[str] = ..., - file_pattern: Optional[Pattern] = ..., - folder: str, name: str, version: str, + model_version_update: JSON, + *, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> FolderDatasetVersion: ... - - - class azure.ai.projects.aio.operations.DeploymentsOperations: - - def __init__( - self, - *args, - **kwargs - ) -> None: ... + ) -> ModelVersion: ... - @distributed_trace_async - async def get( + @overload + async def update( self, name: str, + version: str, + model_version_update: IO[bytes], + *, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> Deployment: ... + ) -> ModelVersion: ... - @distributed_trace - def list( + + class azure.ai.projects.aio.operations.BetaOperations(GeneratedBetaOperations): + agent_insight_monitors: BetaAgentInsightMonitorsOperations + agents: BetaAgentsOperations + datasets: BetaDatasetsOperations + evaluation_taxonomies: BetaEvaluationTaxonomiesOperations + evaluators: BetaEvaluatorsOperations + insights: BetaInsightsOperations + memory_stores: BetaMemoryStoresOperations + models: BetaModelsOperations + red_teams: BetaRedTeamsOperations + routines: BetaRoutinesOperations + schedules: BetaSchedulesOperations + skills: BetaSkillsOperations + + def __init__( self, - *, - deployment_type: Optional[Union[str, DeploymentType]] = ..., - model_name: Optional[str] = ..., - model_publisher: Optional[str] = ..., + *args: Any, **kwargs: Any - ) -> AsyncItemPaged[Deployment]: ... + ) -> None: ... - class azure.ai.projects.aio.operations.EvaluationRulesOperations(GeneratedEvaluationRulesOperations): + class azure.ai.projects.aio.operations.BetaRedTeamsOperations: def __init__( self, @@ -2399,61 +2519,44 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create_or_update( + async def create( self, - id: str, - evaluation_rule: EvaluationRule, + red_team: RedTeam, *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluationRule: ... + ) -> RedTeam: ... @overload - async def create_or_update( + async def create( self, - id: str, - evaluation_rule: JSON, + red_team: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluationRule: ... + ) -> RedTeam: ... @overload - async def create_or_update( + async def create( self, - id: str, - evaluation_rule: IO[bytes], + red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> EvaluationRule: ... - - @distributed_trace_async - async def delete( - self, - id: str, - **kwargs: Any - ) -> None: ... + ) -> RedTeam: ... @distributed_trace_async async def get( self, - id: str, + name: str, **kwargs: Any - ) -> EvaluationRule: ... + ) -> RedTeam: ... @distributed_trace - def list( - self, - *, - action_type: Optional[Union[str, EvaluationRuleActionType]] = ..., - agent_name: Optional[str] = ..., - enabled: Optional[bool] = ..., - **kwargs: Any - ) -> AsyncItemPaged[EvaluationRule]: ... + def list(self, **kwargs: Any) -> AsyncItemPaged[RedTeam]: ... - class azure.ai.projects.aio.operations.IndexesOperations: + class azure.ai.projects.aio.operations.BetaRoutinesOperations: def __init__( self, @@ -2464,72 +2567,199 @@ namespace azure.ai.projects.aio.operations @overload async def create_or_update( self, - name: str, - version: str, - index: Index, + routine_name: str, *, - content_type: str = "application/merge-patch+json", + action: Optional[RoutineAction] = ..., + authorization: Optional[RoutineAuthorization] = ..., + content_type: str = "application/json", + description: Optional[str] = ..., + enabled: Optional[bool] = ..., + triggers: Optional[dict[str, RoutineTrigger]] = ..., **kwargs: Any - ) -> Index: ... + ) -> Routine: ... @overload async def create_or_update( self, - name: str, - version: str, - index: JSON, + routine_name: str, + body: JSON, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> Index: ... + ) -> Routine: ... @overload async def create_or_update( self, - name: str, - version: str, - index: IO[bytes], + routine_name: str, + body: IO[bytes], *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> Index: ... + ) -> Routine: ... @distributed_trace_async async def delete( self, - name: str, - version: str, + routine_name: str, **kwargs: Any ) -> None: ... + @distributed_trace_async + async def disable( + self, + routine_name: str, + **kwargs: Any + ) -> Routine: ... + + @overload + async def dispatch( + self, + routine_name: str, + *, + content_type: str = "application/json", + payload: Optional[RoutineDispatchPayload] = ..., + **kwargs: Any + ) -> DispatchRoutineResult: ... + + @overload + async def dispatch( + self, + routine_name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> DispatchRoutineResult: ... + + @overload + async def dispatch( + self, + routine_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> DispatchRoutineResult: ... + + @distributed_trace_async + async def enable( + self, + routine_name: str, + **kwargs: Any + ) -> Routine: ... + @distributed_trace_async async def get( self, - name: str, - version: str, + routine_name: str, **kwargs: Any - ) -> Index: ... + ) -> Routine: ... @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[Index]: ... + def list( + self, + *, + after: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Routine]: ... @distributed_trace - def list_versions( + def list_runs( self, - name: str, + routine_name: str, + *, + after: Optional[str] = ..., + filter: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncItemPaged[Index]: ... + ) -> AsyncItemPaged[RoutineRun]: ... - class azure.ai.projects.aio.operations.TelemetryOperations: + class azure.ai.projects.aio.operations.BetaSchedulesOperations: - def __init__(self, outer_instance: AIProjectClient) -> None: ... + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + schedule_id: str, + schedule: Schedule, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> Schedule: ... + + @overload + async def create_or_update( + self, + schedule_id: str, + schedule: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> Schedule: ... + + @overload + async def create_or_update( + self, + schedule_id: str, + schedule: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> Schedule: ... @distributed_trace_async - async def get_application_insights_connection_string(self) -> str: ... + async def delete( + self, + schedule_id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + schedule_id: str, + **kwargs: Any + ) -> Schedule: ... + @distributed_trace_async + async def get_run( + self, + schedule_id: str, + run_id: str, + **kwargs: Any + ) -> ScheduleRun: ... - class azure.ai.projects.aio.operations.ToolboxesOperations: + @distributed_trace + def list( + self, + *, + enabled: Optional[bool] = ..., + type: Optional[Union[str, ScheduleTaskType]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Schedule]: ... + + @distributed_trace + def list_runs( + self, + schedule_id: str, + *, + enabled: Optional[bool] = ..., + type: Optional[Union[str, ScheduleTaskType]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ScheduleRun]: ... + + + class azure.ai.projects.aio.operations.BetaSkillsOperations: def __init__( self, @@ -2538,45 +2768,58 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create_version( + async def create( self, name: str, *, content_type: str = "application/json", - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., - policies: Optional[ToolboxPolicies] = ..., - skills: Optional[List[ToolboxSkill]] = ..., - tools: List[ToolboxTool], + default: Optional[bool] = ..., + inline_content: Optional[SkillInlineContent] = ..., **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> SkillVersion: ... @overload - async def create_version( + async def create( self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> SkillVersion: ... @overload - async def create_version( + async def create( self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> SkillVersion: ... + + @overload + async def create_from_files( + self, + name: str, + content: CreateSkillVersionFromFilesBody, + **kwargs: Any + ) -> SkillVersion: ... + + @overload + async def create_from_files( + self, + name: str, + content: JSON, + **kwargs: Any + ) -> SkillVersion: ... @distributed_trace_async async def delete( self, name: str, **kwargs: Any - ) -> None: ... + ) -> DeleteSkillResult: ... @distributed_trace_async async def delete_version( @@ -2584,14 +2827,29 @@ namespace azure.ai.projects.aio.operations name: str, version: str, **kwargs: Any - ) -> None: ... + ) -> DeleteSkillVersionResult: ... + + @distributed_trace_async + async def download( + self, + name: str, + **kwargs: Any + ) -> AsyncIterator[bytes]: ... + + @distributed_trace_async + async def download_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> AsyncIterator[bytes]: ... @distributed_trace_async async def get( self, name: str, **kwargs: Any - ) -> ToolboxObject: ... + ) -> SkillDetails: ... @distributed_trace_async async def get_version( @@ -2599,7 +2857,7 @@ namespace azure.ai.projects.aio.operations name: str, version: str, **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> SkillVersion: ... @distributed_trace def list( @@ -2609,7 +2867,7 @@ namespace azure.ai.projects.aio.operations limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncItemPaged[ToolboxObject]: ... + ) -> AsyncItemPaged[SkillDetails]: ... @distributed_trace def list_versions( @@ -2620,7 +2878,7 @@ namespace azure.ai.projects.aio.operations limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncItemPaged[ToolboxVersionObject]: ... + ) -> AsyncItemPaged[SkillVersion]: ... @overload async def update( @@ -2630,7 +2888,7 @@ namespace azure.ai.projects.aio.operations content_type: str = "application/json", default_version: str, **kwargs: Any - ) -> ToolboxObject: ... + ) -> SkillDetails: ... @overload async def update( @@ -2640,209 +2898,5023 @@ namespace azure.ai.projects.aio.operations *, content_type: str = "application/json", **kwargs: Any + ) -> SkillDetails: ... + + @overload + async def update( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> SkillDetails: ... + + + class azure.ai.projects.aio.operations.ConnectionsOperations(ConnectionsOperationsGenerated): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + *, + include_credentials: Optional[bool] = False, + **kwargs: Any + ) -> Connection: ... + + @distributed_trace_async + async def get_default( + self, + connection_type: Union[str, ConnectionType], + *, + include_credentials: Optional[bool] = False, + **kwargs: Any + ) -> Connection: ... + + @distributed_trace + def list( + self, + *, + connection_type: Optional[Union[str, ConnectionType]] = ..., + default_connection: Optional[bool] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Connection]: ... + + + class azure.ai.projects.aio.operations.DatasetsOperations(DatasetsOperationsGenerated): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: DatasetVersion, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> DatasetVersion: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> DatasetVersion: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> DatasetVersion: ... + + @distributed_trace_async + async def delete( + self, + name: str, + version: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + version: str, + **kwargs: Any + ) -> DatasetVersion: ... + + @distributed_trace_async + async def get_credentials( + self, + name: str, + version: str, + **kwargs: Any + ) -> DatasetCredential: ... + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged[DatasetVersion]: ... + + @distributed_trace + def list_versions( + self, + name: str, + **kwargs: Any + ) -> AsyncItemPaged[DatasetVersion]: ... + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> PendingUploadResponse: ... + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> PendingUploadResponse: ... + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> PendingUploadResponse: ... + + @distributed_trace_async + async def upload_file( + self, + *, + connection_name: Optional[str] = ..., + file_path: str, + name: str, + version: str, + **kwargs: Any + ) -> FileDatasetVersion: ... + + @distributed_trace_async + async def upload_folder( + self, + *, + connection_name: Optional[str] = ..., + file_pattern: Optional[Pattern] = ..., + folder: str, + name: str, + version: str, + **kwargs: Any + ) -> FolderDatasetVersion: ... + + + class azure.ai.projects.aio.operations.DeploymentsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + **kwargs: Any + ) -> Deployment: ... + + @distributed_trace + def list( + self, + *, + deployment_type: Optional[Union[str, DeploymentType]] = ..., + model_name: Optional[str] = ..., + model_publisher: Optional[str] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Deployment]: ... + + + class azure.ai.projects.aio.operations.EvaluationRulesOperations(GeneratedEvaluationRulesOperations): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: EvaluationRule, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @distributed_trace_async + async def delete( + self, + id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + id: str, + **kwargs: Any + ) -> EvaluationRule: ... + + @distributed_trace + def list( + self, + *, + action_type: Optional[Union[str, EvaluationRuleActionType]] = ..., + agent_name: Optional[str] = ..., + enabled: Optional[bool] = ..., + **kwargs: Any + ) -> AsyncItemPaged[EvaluationRule]: ... + + + class azure.ai.projects.aio.operations.IndexesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: Index, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @distributed_trace_async + async def delete( + self, + name: str, + version: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + version: str, + **kwargs: Any + ) -> Index: ... + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged[Index]: ... + + @distributed_trace + def list_versions( + self, + name: str, + **kwargs: Any + ) -> AsyncItemPaged[Index]: ... + + + class azure.ai.projects.aio.operations.TelemetryOperations: + + def __init__(self, outer_instance: AIProjectClient) -> None: ... + + @distributed_trace_async + async def get_application_insights_connection_string(self) -> str: ... + + + class azure.ai.projects.aio.operations.ToolboxesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_version( + self, + name: str, + *, + content_type: str = "application/json", + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., + policies: Optional[ToolboxPolicies] = ..., + skills: Optional[List[ToolboxSkill]] = ..., + tools: List[ToolboxTool], + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @overload + async def create_version( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @overload + async def create_version( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @distributed_trace_async + async def delete( + self, + name: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def delete_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + **kwargs: Any + ) -> ToolboxObject: ... + + @distributed_trace_async + async def get_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @distributed_trace + def list( + self, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ToolboxObject]: ... + + @distributed_trace + def list_versions( + self, + name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ToolboxVersionObject]: ... + + @overload + async def update( + self, + name: str, + *, + content_type: str = "application/json", + default_version: str, + **kwargs: Any + ) -> ToolboxObject: ... + + @overload + async def update( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxObject: ... + + @overload + async def update( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any ) -> ToolboxObject: ... + + class azure.ai.projects.aio.operations.VoiceAgentWebSocketOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace_async + async def connect_voice_agent( + self, + agent_name: str, + *, + agent_version_override: Optional[str] = ..., + foundry_features_query: Optional[Literal[_AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW]] = ..., + store: Optional[bool] = ..., + structured_input: Optional[str] = ..., + transport: Optional[Union[str, VoiceAgentTransport]] = ..., + websocket_subprotocol: Optional[Union[str, VoiceAgentWebSocketSubprotocol]] = ..., + **kwargs: Any + ) -> None: ... + + +namespace azure.ai.projects.models + + class azure.ai.projects.models.A2APreviewTool(Tool, discriminator='a2a_preview'): + agent_card_path: Optional[str] + base_url: Optional[str] + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + type: Literal[ToolType.A2A_PREVIEW] + + @overload + def __init__( + self, + *, + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2APreviewToolboxTool(ToolboxTool, discriminator='a2a_preview'): + agent_card_path: Optional[str] + base_url: Optional[str] + description: str + name: str + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.A2A_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] = ..., + send_credentials_for_agent_card: Optional[bool] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2AProtocolConfiguration(_Model): + + + class azure.ai.projects.models.A2AProtocolVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): + V1_0 = "1.0" + + + class azure.ai.projects.models.A2ATool(Tool, discriminator='a2a'): + a2a_version: Union[str, A2AProtocolVersion] + agent_card_path: Optional[str] + base_url: Optional[str] + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + type: Literal[ToolType.A2_A] + + @overload + def __init__( + self, + *, + a2a_version: Union[str, A2AProtocolVersion], + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2AToolboxTool(ToolboxTool, discriminator='a2a'): + a2a_version: Union[str, A2AProtocolVersion] + agent_card_path: Optional[str] + base_url: Optional[str] + description: str + name: str + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.A2_A] + + @overload + def __init__( + self, + *, + a2a_version: Union[str, A2AProtocolVersion], + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AISearchIndexResource(_Model): + filter: Optional[str] + index_asset_id: Optional[str] + index_name: Optional[str] + project_connection_id: Optional[str] + query_type: Optional[Union[str, AzureAISearchQueryType]] + top_k: Optional[int] + + @overload + def __init__( + self, + *, + filter: Optional[str] = ..., + index_asset_id: Optional[str] = ..., + index_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.projects.models.ActivityProtocolAccessBoundary(str, Enum, metaclass=CaseInsensitiveEnumMeta): + READ1_ON1_ALLOWLISTED = "read.1on1.allowlisted" + READ1_ON1_DEVELOPERS = "read.1on1.developers" + READ1_ON1_MANAGER = "read.1on1.manager" + READ1_ON1_TENANT = "read.1on1.tenant" + READ_GROUP_ALLOWLISTED = "read.group.allowlisted" + READ_GROUP_DEVELOPERS = "read.group.developers" + READ_GROUP_MANAGER_INVITED = "read.group.manager-invited" + READ_GROUP_MANAGER_PRESENT = "read.group.manager-present" + READ_GROUP_TENANT = "read.group.tenant" + WRITE1_ON1_ALLOWLISTED = "write.1on1.allowlisted" + WRITE1_ON1_DEVELOPERS = "write.1on1.developers" + WRITE1_ON1_MANAGER = "write.1on1.manager" + WRITE1_ON1_TENANT = "write.1on1.tenant" + WRITE_GROUP_ALLOWLISTED = "write.group.allowlisted" + WRITE_GROUP_DEVELOPERS = "write.group.developers" + WRITE_GROUP_MANAGER_INVITED = "write.group.manager-invited" + WRITE_GROUP_MANAGER_PRESENT = "write.group.manager-present" + WRITE_GROUP_TENANT = "write.group.tenant" + + + class azure.ai.projects.models.ActivityProtocolConfiguration(_Model): + access_boundaries: Optional[list[Union[str, ActivityProtocolAccessBoundary]]] + enable_m365_public_endpoint: Optional[bool] + + @overload + def __init__( + self, + *, + enable_m365_public_endpoint: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentBlueprintReference(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentBlueprintReferenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANAGED_AGENT_IDENTITY_BLUEPRINT = "ManagedAgentIdentityBlueprint" + + + class azure.ai.projects.models.AgentCard(_Model): + description: Optional[str] + skills: list[AgentCardSkill] + version: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + skills: list[AgentCardSkill], + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentCardSkill(_Model): + description: Optional[str] + examples: Optional[list[str]] + id: str + name: str + tags: Optional[list[str]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + examples: Optional[list[str]] = ..., + id: str, + name: str, + tags: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentClusterInsightRequest(InsightRequest, discriminator='AgentClusterInsight'): + agent_name: str + model_configuration: Optional[InsightModelConfiguration] + type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + agent_name: str, + model_configuration: Optional[InsightModelConfiguration] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentClusterInsightResult(InsightResult, discriminator='AgentClusterInsight'): + cluster_insight: ClusterInsightResult + type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + cluster_insight: ClusterInsightResult + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDataGenerationJobSource(DataGenerationJobSource, discriminator='agent'): + agent_name: str + agent_version: Optional[str] + description: str + type: Literal[DataGenerationJobSourceType.AGENT] + + @overload + def __init__( + self, + *, + agent_name: str, + agent_version: Optional[str] = ..., + description: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDefinition(_Model): + kind: str + rai_config: Optional[RaiConfig] + + @overload + def __init__( + self, + *, + kind: str, + rai_config: Optional[RaiConfig] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDetails(_Model): + agent_card: Optional[AgentCard] + agent_endpoint: Optional[AgentEndpointConfig] + blueprint: Optional[AgentIdentity] + blueprint_reference: Optional[AgentBlueprintReference] + digital_worker_type: Optional[Union[str, DigitalWorkerType]] + id: str + instance_identity: Optional[AgentIdentity] + name: str + object: Literal[AgentObjectType.AGENT] + state: Union[str, AgentState] + state_source: Optional[Union[str, AgentStateSource]] + versions: AgentObjectVersions + + @overload + def __init__( + self, + *, + agent_card: Optional[AgentCard] = ..., + agent_endpoint: Optional[AgentEndpointConfig] = ..., + digital_worker_type: Optional[Union[str, DigitalWorkerType]] = ..., + id: str, + name: str, + object: Literal[AgentObjectType.AGENT], + versions: AgentObjectVersions + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointAuthorizationScheme(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointAuthorizationSchemeType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOT_SERVICE = "BotService" + BOT_SERVICE_RBAC = "BotServiceRbac" + BOT_SERVICE_TENANT = "BotServiceTenant" + ENTRA = "Entra" + + + class azure.ai.projects.models.AgentEndpointConfig(_Model): + authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] + protocol_configuration: Optional[ProtocolConfiguration] + publish_approval_status: Optional[Union[str, PublishApprovalStatus]] + version_selector: Optional[VersionSelector] + + @overload + def __init__( + self, + *, + authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] = ..., + protocol_configuration: Optional[ProtocolConfiguration] = ..., + version_selector: Optional[VersionSelector] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A = "a2a" + ACTIVITY = "activity" + INVOCATIONS = "invocations" + INVOCATIONS_WS = "invocations_ws" + MCP = "mcp" + RESPONSES = "responses" + VOICE = "voice" + + + class azure.ai.projects.models.AgentEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='agent'): + agent_name: str + agent_version: Optional[str] + description: Optional[str] + type: Literal[EvaluatorGenerationJobSourceType.AGENT] + + @overload + def __init__( + self, + *, + agent_name: str, + agent_version: Optional[str] = ..., + description: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentIdentity(_Model): + client_id: str + principal_id: str + status: Optional[Union[str, AgentIdentityStatus]] + + @overload + def __init__( + self, + *, + client_id: str, + principal_id: str, + status: Optional[Union[str, AgentIdentityStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentIdentityStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + DISABLED = "disabled" + + + class azure.ai.projects.models.AgentInsight(_Model): + agent_name: str + agent_version: str + category: str + created_at: datetime + description: str + details: Optional[AgentInsightDetails] + id: str + monitor_id: str + severity: Union[str, AgentInsightSeverity] + status: Union[str, AgentInsightStatus] + title: str + trace_count: int + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightDetails(_Model): + highlighted_traces: list[AgentInsightHighlightedTrace] + linked_traces: list[AgentInsightLinkedTrace] + recommended_actions: AgentInsightRecommendedAction + + @overload + def __init__( + self, + *, + highlighted_traces: list[AgentInsightHighlightedTrace], + linked_traces: list[AgentInsightLinkedTrace], + recommended_actions: AgentInsightRecommendedAction + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightEstimatedCost(_Model): + amount: float + currency: Literal["USD"] + + @overload + def __init__( + self, + *, + amount: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightHighlightedTrace(_Model): + duration_ms: timedelta + summary: str + timestamp: datetime + total_tokens: Optional[int] + trace_id: str + + @overload + def __init__( + self, + *, + duration_ms: timedelta, + summary: str, + timestamp: datetime, + total_tokens: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightLinkedTrace(_Model): + timestamp: datetime + trace_id: str + + + class azure.ai.projects.models.AgentInsightMonitor(_Model): + agent_name: str + enabled: bool + estimated_cost: Optional[AgentInsightEstimatedCost] + id: str + model_deployment_name: str + next_scheduled_run_at: Optional[datetime] + overview: AgentInsightsOverview + run_interval_hours: float + suspension: AgentInsightSuspension + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightMonitorCreate(_Model): + agent_name: str + enabled: Optional[bool] + model_deployment_name: str + run_interval_hours: Optional[float] + + @overload + def __init__( + self, + *, + agent_name: str, + enabled: Optional[bool] = ..., + model_deployment_name: str, + run_interval_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightMonitorListItem(_Model): + agent_name: str + enabled: bool + estimated_cost: Optional[AgentInsightEstimatedCost] + id: str + model_deployment_name: str + next_scheduled_run_at: Optional[datetime] + run_interval_hours: float + suspension: AgentInsightSuspension + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightMonitorUpdate(_Model): + enabled: Optional[bool] + model_deployment_name: Optional[str] + overview_override: Optional[AgentInsightsOverviewOverride] + run_interval_hours: Optional[float] + + @overload + def __init__( + self, + *, + enabled: Optional[bool] = ..., + model_deployment_name: Optional[str] = ..., + overview_override: Optional[AgentInsightsOverviewOverride] = ..., + run_interval_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightOverviewSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GENERATED = "generated" + USER_OVERRIDE = "user_override" + + + class azure.ai.projects.models.AgentInsightPromptSurface(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INSTRUCTIONS = "instructions" + TOOL = "tool" + + + class azure.ai.projects.models.AgentInsightProposedFix(_Model): + changes: Optional[list[AgentInsightProposedFixChange]] + kind: Union[str, AgentInsightProposedFixKind] + text: str + + @overload + def __init__( + self, + *, + changes: Optional[list[AgentInsightProposedFixChange]] = ..., + kind: Union[str, AgentInsightProposedFixKind], + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightProposedFixChange(_Model): + diff: Optional[str] + language: Optional[str] + new_value: Optional[Any] + old_value: Optional[Any] + path: Optional[str] + surface: Optional[Union[str, AgentInsightPromptSurface]] + target: Optional[str] + + @overload + def __init__( + self, + *, + diff: Optional[str] = ..., + language: Optional[str] = ..., + new_value: Optional[Any] = ..., + old_value: Optional[Any] = ..., + path: Optional[str] = ..., + surface: Optional[Union[str, AgentInsightPromptSurface]] = ..., + target: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightProposedFixKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE_CHANGE = "code_change" + PROMPT_CHANGE = "prompt_change" + PROSE = "prose" + + + class azure.ai.projects.models.AgentInsightRecommendedAction(_Model): + proposed_fix: AgentInsightProposedFix + + @overload + def __init__( + self, + *, + proposed_fix: AgentInsightProposedFix + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRun(_Model): + agent_name: str + completed_at: Optional[datetime] + created_at: datetime + error: Optional[ApiError] + id: str + inputs: Optional[AgentInsightRunCreate] + model_deployment_name: str + monitor_id: str + result: Optional[AgentInsightRunResult] + started_at: Optional[datetime] + status: Union[str, JobStatus] + trigger: Union[str, AgentInsightRunTrigger] + updated_at: datetime + window_end: datetime + window_start: datetime + + @overload + def __init__( + self, + *, + inputs: Optional[AgentInsightRunCreate] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunCreate(_Model): + lookback_hours: Optional[float] + + @overload + def __init__( + self, + *, + lookback_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunLROPoller(LROPoller[AgentInsightRunResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[AgentInsightRunResult], + continuation_token: str, + **kwargs: Any + ) -> AgentInsightRunLROPoller: ... + + + class azure.ai.projects.models.AgentInsightRunResult(_Model): + insights_created: int + insights_reopened: int + insights_updated: int + token_usage: AgentInsightTokenUsage + traces_analyzed: int + traces_in_window: int + + @overload + def __init__( + self, + *, + insights_created: int, + insights_reopened: int, + insights_updated: int, + token_usage: AgentInsightTokenUsage, + traces_analyzed: int, + traces_in_window: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ON_DEMAND = "on_demand" + SCHEDULED = "scheduled" + + + class azure.ai.projects.models.AgentInsightSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + + + class azure.ai.projects.models.AgentInsightStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + IGNORED = "ignored" + RESOLVED = "resolved" + + + class azure.ai.projects.models.AgentInsightSuspension(_Model): + code: str + details: Optional[dict[str, Any]] + message: str + occurred_at: datetime + + @overload + def __init__( + self, + *, + code: str, + details: Optional[dict[str, Any]] = ..., + message: str, + occurred_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightTokenUsage(_Model): + cached_tokens: Optional[int] + input_tokens: int + output_tokens: int + total_tokens: int + + @overload + def __init__( + self, + *, + cached_tokens: Optional[int] = ..., + input_tokens: int, + output_tokens: int, + total_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightUpdate(_Model): + status: Optional[Union[str, AgentInsightStatus]] + + @overload + def __init__( + self, + *, + status: Optional[Union[str, AgentInsightStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightsOverview(_Model): + content: str + source: Union[str, AgentInsightOverviewSource] + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + source: Union[str, AgentInsightOverviewSource], + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightsOverviewOverride(_Model): + content: str + + @overload + def __init__( + self, + *, + content: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EXTERNAL = "external" + HOSTED = "hosted" + PROMPT = "prompt" + VOICE = "voice" + WORKFLOW = "workflow" + + + class azure.ai.projects.models.AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + AGENT_CONTAINER = "agent.container" + AGENT_DELETED = "agent.deleted" + AGENT_VERSION = "agent.version" + AGENT_VERSION_DELETED = "agent.version.deleted" + + + class azure.ai.projects.models.AgentObjectVersions(_Model): + latest: AgentVersionDetails + + @overload + def __init__( + self, + *, + latest: AgentVersionDetails + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationCandidate(_Model): + avg_score: float + avg_tokens: float + candidate_id: Optional[str] + eval_id: Optional[str] + eval_run_id: Optional[str] + mutations: Optional[dict[str, Any]] + name: str + promotion: Optional[PromotionInfo] + + @overload + def __init__( + self, + *, + avg_score: float, + avg_tokens: float, + candidate_id: Optional[str] = ..., + eval_id: Optional[str] = ..., + eval_run_id: Optional[str] = ..., + mutations: Optional[dict[str, Any]] = ..., + name: str, + promotion: Optional[PromotionInfo] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetCriterion(_Model): + instruction: str + name: str + + @overload + def __init__( + self, + *, + instruction: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetInput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INLINE = "inline" + REFERENCE = "reference" + + + class azure.ai.projects.models.AgentOptimizationDatasetItem(_Model): + criteria: Optional[list[AgentOptimizationDatasetCriterion]] + desired_num_turns: Optional[int] + ground_truth: Optional[str] + query: Optional[str] + + @overload + def __init__( + self, + *, + criteria: Optional[list[AgentOptimizationDatasetCriterion]] = ..., + desired_num_turns: Optional[int] = ..., + ground_truth: Optional[str] = ..., + query: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationEvaluatorRef(_Model): + name: str + 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.projects.models.AgentOptimizationInlineDatasetInput(AgentOptimizationDatasetInput, discriminator='inline'): + dataset_items: list[AgentOptimizationDatasetItem] + type: Literal[AgentOptimizationDatasetInputType.INLINE] + + @overload + def __init__( + self, + *, + dataset_items: list[AgentOptimizationDatasetItem] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJob(_Model): + created_at: datetime + error: Optional[ApiError] + id: str + inputs: Optional[AgentOptimizationJobInputs] + progress: Optional[AgentOptimizationJobProgress] + result: Optional[AgentOptimizationJobResult] + status: Union[str, JobStatus] + updated_at: datetime + warnings: Optional[list[str]] + + @overload + def __init__( + self, + *, + inputs: Optional[AgentOptimizationJobInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobInputs(_Model): + agent: OptimizedAgentIdentifier + evaluators: list[AgentOptimizationEvaluatorRef] + options: Optional[AgentOptimizationOptions] + train_dataset: AgentOptimizationDatasetInput + validation_dataset: Optional[AgentOptimizationDatasetInput] + + @overload + def __init__( + self, + *, + agent: OptimizedAgentIdentifier, + evaluators: list[AgentOptimizationEvaluatorRef], + options: Optional[AgentOptimizationOptions] = ..., + train_dataset: AgentOptimizationDatasetInput, + validation_dataset: Optional[AgentOptimizationDatasetInput] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobListItem(_Model): + agent: Optional[OptimizedAgentIdentifier] + created_at: datetime + error: Optional[ApiError] + id: str + progress: Optional[AgentOptimizationJobProgress] + status: Union[str, JobStatus] + updated_at: datetime + + + class azure.ai.projects.models.AgentOptimizationJobProgress(_Model): + best_score: float + candidates_completed: int + elapsed_seconds: float + + @overload + def __init__( + self, + *, + best_score: float, + candidates_completed: int, + elapsed_seconds: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobResult(_Model): + baseline: Optional[str] + best: Optional[str] + candidates: Optional[list[AgentOptimizationCandidate]] + + @overload + def __init__( + self, + *, + baseline: Optional[str] = ..., + best: Optional[str] = ..., + candidates: Optional[list[AgentOptimizationCandidate]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationLROPoller(LROPoller[AgentOptimizationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[AgentOptimizationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AgentOptimizationLROPoller: ... + + + class azure.ai.projects.models.AgentOptimizationOptions(_Model): + eval_model: Optional[str] + evaluation_level: Optional[Union[str, EvaluationLevel]] + max_candidates: Optional[int] + max_stalls: Optional[int] + optimization_config: Optional[dict[str, Any]] + optimization_model: Optional[str] + + @overload + def __init__( + self, + *, + eval_model: Optional[str] = ..., + evaluation_level: Optional[Union[str, EvaluationLevel]] = ..., + max_candidates: Optional[int] = ..., + max_stalls: Optional[int] = ..., + optimization_config: Optional[dict[str, Any]] = ..., + optimization_model: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationReferenceDatasetInput(AgentOptimizationDatasetInput, discriminator='reference'): + name: str + type: Literal[AgentOptimizationDatasetInputType.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.projects.models.AgentSessionResource(_Model): + agent_session_id: str + created_at: datetime + expires_at: datetime + last_accessed_at: datetime + status: Union[str, AgentSessionStatus] + version_indicator: VersionIndicator + + @overload + def __init__( + self, + *, + agent_session_id: str, + status: Union[str, AgentSessionStatus], + version_indicator: VersionIndicator + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentSessionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + CREATING = "creating" + DELETED = "deleted" + DELETING = "deleting" + EXPIRED = "expired" + FAILED = "failed" + IDLE = "idle" + UPDATING = "updating" + + + class azure.ai.projects.models.AgentState(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DISABLED = "disabled" + ENABLED = "enabled" + + + class azure.ai.projects.models.AgentStateSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_BLUEPRINT = "agent_blueprint" + AGENT_INSTANCE_IDENTITY = "agent_instance_identity" + + + class azure.ai.projects.models.AgentTaxonomyInput(EvaluationTaxonomyInput, discriminator='agent'): + risk_categories: list[Union[str, RiskCategory]] + target: EvaluationTarget + type: Literal[EvaluationTaxonomyInputType.AGENT] + + @overload + def __init__( + self, + *, + risk_categories: list[Union[str, RiskCategory]], + target: EvaluationTarget + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentVersionDetails(_Model): + agent_guid: Optional[str] + blueprint: Optional[AgentIdentity] + blueprint_reference: Optional[AgentBlueprintReference] + created_at: datetime + definition: AgentDefinition + description: Optional[str] + draft: Optional[bool] + id: str + instance_identity: Optional[AgentIdentity] + metadata: dict[str, str] + name: str + object: Literal[AgentObjectType.AGENT_VERSION] + status: Optional[Union[str, AgentVersionStatus]] + version: str + + @overload + def __init__( + self, + *, + created_at: datetime, + definition: AgentDefinition, + description: Optional[str] = ..., + draft: Optional[bool] = ..., + id: str, + metadata: dict[str, str], + name: str, + object: Literal[AgentObjectType.AGENT_VERSION], + status: Optional[Union[str, AgentVersionStatus]] = ..., + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentVersionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + CREATING = "creating" + DELETED = "deleted" + DELETING = "deleting" + FAILED = "failed" + + + class azure.ai.projects.models.AgenticIdentityPreviewCredentials(BaseCredentials, discriminator='AgenticIdentityToken_Preview'): + type: Literal[CredentialType.AGENTIC_IDENTITY_PREVIEW] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiError(_Model): + additional_info: Optional[dict[str, Any]] + code: str + debug_info: Optional[dict[str, Any]] + details: Optional[list[ApiError]] + 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[ApiError]] = ..., + message: str, + param: Optional[str] = ..., + type: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiErrorResponse(_Model): + error: ApiError + + @overload + def __init__( + self, + *, + error: ApiError + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiKeyCredentials(BaseCredentials, discriminator='ApiKey'): + api_key: Optional[str] + type: Literal[CredentialType.API_KEY] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApplyPatchToolParam(Tool, discriminator='apply_patch'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + type: Literal[ToolType.APPLY_PATCH] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.ArtifactProfile(_Model): + category: Union[str, FoundryModelArtifactProfileCategory] + signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] + + @overload + def __init__( + self, + *, + category: Union[str, FoundryModelArtifactProfileCategory], + signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AsyncAgentInsightRunLROPoller(AsyncLROPoller[AgentInsightRunResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[AgentInsightRunResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncAgentInsightRunLROPoller: ... + + + class azure.ai.projects.models.AsyncAgentOptimizationLROPoller(AsyncLROPoller[AgentOptimizationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[AgentOptimizationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncAgentOptimizationLROPoller: ... + + + class azure.ai.projects.models.AsyncDatasetGenerationLROPoller(AsyncLROPoller[DataGenerationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[DataGenerationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncDatasetGenerationLROPoller: ... + + + class azure.ai.projects.models.AsyncEvaluatorGenerationLROPoller(AsyncLROPoller[EvaluatorVersion]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[EvaluatorVersion], + continuation_token: str, + **kwargs: Any + ) -> AsyncEvaluatorGenerationLROPoller: ... + + + class azure.ai.projects.models.AsyncUpdateMemoriesLROPoller(AsyncLROPoller[MemoryStoreUpdateCompletedResult]): + property superseded_by: Optional[str] # Read-only + property update_id: str # Read-only + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[MemoryStoreUpdateCompletedResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncUpdateMemoriesLROPoller: ... + + + class azure.ai.projects.models.AttackStrategy(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANSI_ATTACK = "ansi_attack" + ASCII_ART = "ascii_art" + ASCII_SMUGGLER = "ascii_smuggler" + ATBASH = "atbash" + BASE64 = "base64" + BASELINE = "baseline" + BINARY = "binary" + CAESAR = "caesar" + CHARACTER_SPACE = "character_space" + CHARACTER_SWAP = "character_swap" + CRESCENDO = "crescendo" + DIACRITIC = "diacritic" + DIFFICULT = "difficult" + EASY = "easy" + FLIP = "flip" + INDIRECT_JAILBREAK = "indirect_jailbreak" + JAILBREAK = "jailbreak" + LEETSPEAK = "leetspeak" + MODERATE = "moderate" + MORSE = "morse" + MULTI_TURN = "multi_turn" + ROT13 = "rot13" + STRING_JOIN = "string_join" + SUFFIX_APPEND = "suffix_append" + TENSE = "tense" + UNICODE_CONFUSABLE = "unicode_confusable" + UNICODE_SUBSTITUTION = "unicode_substitution" + URL = "url" + + + class azure.ai.projects.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.projects.models.AzureAIAgentTarget(EvaluationTarget, discriminator='azure_ai_agent'): + name: str + tool_descriptions: Optional[list[ToolDescription]] + tools: Optional[list[Tool]] + type: Literal["azure_ai_agent"] + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + tool_descriptions: Optional[list[ToolDescription]] = ..., + tools: Optional[list[Tool]] = ..., + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAIAgentTargetParam(TypedDict, total=False): + key "name": Required[str] + key "tool_descriptions": List[ToolDescriptionParam] + key "type": Required[Literal["azure_ai_agent"]] + key "version": str + + + class azure.ai.projects.models.AzureAIBenchmarkPreviewEvalRunDataSource(TypedDict, total=False): + key "input_messages": InputMessagesItemReference + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_benchmark_preview"]] + + + class azure.ai.projects.models.AzureAIDataSourceConfig(TypedDict, total=False): + key "scenario": Required[str] + key "type": Required[Literal["azure_ai_source"]] + + + class azure.ai.projects.models.AzureAIModelTarget(EvaluationTarget, discriminator='azure_ai_model'): + model: Optional[str] + sampling_params: Optional[ModelSamplingParams] + type: Literal["azure_ai_model"] + + @overload + def __init__( + self, + *, + model: Optional[str] = ..., + sampling_params: Optional[ModelSamplingParams] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAIModelTargetParam(TypedDict, total=False): + key "model": str + key "sampling_params": ModelSamplingConfigParam + key "type": Required[Literal["azure_ai_model"]] + + + class azure.ai.projects.models.AzureAIResponsesEvalRunDataSource(TypedDict, total=False): + key "event_configuration_id": str + key "item_generation_params": Required[ResponseRetrievalItemGenerationParams] + key "max_runs_hourly": int + key "type": Required[Literal["azure_ai_responses"]] + + + class azure.ai.projects.models.AzureAISearchIndex(Index, discriminator='AzureSearch'): + connection_name: str + description: str + field_mapping: Optional[FieldMapping] + id: str + index_name: str + name: str + tags: dict[str, str] + type: Literal[IndexType.AZURE_SEARCH] + version: str + + @overload + def __init__( + self, + *, + connection_name: str, + description: Optional[str] = ..., + field_mapping: Optional[FieldMapping] = ..., + index_name: str, + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.AzureAISearchTool(Tool, discriminator='azure_ai_search'): + azure_ai_search: AzureAISearchToolResource + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.AZURE_AI_SEARCH] + + @overload + def __init__( + self, + *, + azure_ai_search: AzureAISearchToolResource, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAISearchToolResource(_Model): + indexes: list[AISearchIndexResource] + + @overload + def __init__( + self, + *, + indexes: list[AISearchIndexResource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAISearchToolboxTool(ToolboxTool, discriminator='azure_ai_search'): + azure_ai_search: AzureAISearchToolResource + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.AZURE_AI_SEARCH] + + @overload + def __init__( + self, + *, + azure_ai_search: AzureAISearchToolResource, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.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.projects.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.projects.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.projects.models.AzureFunctionTool(Tool, discriminator='azure_function'): + azure_function: AzureFunctionDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.AZURE_FUNCTION] + + @overload + def __init__( + self, + *, + azure_function: AzureFunctionDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureOpenAIModelConfiguration(RedTeamTargetConfig, discriminator='AzureOpenAIModel'): + model_deployment_name: str + type: Literal["AzureOpenAIModel"] + + @overload + def __init__( + self, + *, + model_deployment_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BaseCredentials(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchConfiguration(_Model): + count: Optional[int] + freshness: Optional[str] + instance_name: str + market: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + freshness: Optional[str] = ..., + instance_name: str, + market: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchPreviewTool(Tool, discriminator='bing_custom_search_preview'): + bing_custom_search_preview: BingCustomSearchToolParameters + type: Literal[ToolType.BING_CUSTOM_SEARCH_PREVIEW] + + @overload + def __init__( + self, + *, + bing_custom_search_preview: BingCustomSearchToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchToolParameters(_Model): + search_configurations: list[BingCustomSearchConfiguration] + + @overload + def __init__( + self, + *, + search_configurations: list[BingCustomSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingSearchConfiguration(_Model): + count: Optional[int] + freshness: Optional[str] + market: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + freshness: Optional[str] = ..., + market: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingSearchToolParameters(_Model): + search_configurations: list[BingGroundingSearchConfiguration] + + @overload + def __init__( + self, + *, + search_configurations: list[BingGroundingSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingTool(Tool, discriminator='bing_grounding'): + bing_grounding: BingGroundingSearchToolParameters + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.BING_GROUNDING] + + @overload + def __init__( + self, + *, + bing_grounding: BingGroundingSearchToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BlobReference(_Model): + blob_uri: str + credential: BlobReferenceSasCredential + storage_account_arm_id: str + + @overload + def __init__( + self, + *, + blob_uri: str, + credential: BlobReferenceSasCredential, + storage_account_arm_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BlobReferenceSasCredential(_Model): + sas_uri: str + type: Literal["SAS"] + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + + class azure.ai.projects.models.BotServiceAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotService'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BotServiceRbacAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceRbac'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_RBAC] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BotServiceTenantAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceTenant'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_TENANT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationPreviewTool(Tool, discriminator='browser_automation_preview'): + browser_automation_preview: BrowserAutomationToolParameters + type: Literal[ToolType.BROWSER_AUTOMATION_PREVIEW] + + @overload + def __init__( + self, + *, + browser_automation_preview: BrowserAutomationToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationPreviewToolboxTool(ToolboxTool, discriminator='browser_automation_preview'): + browser_automation_preview: BrowserAutomationToolParameters + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.BROWSER_AUTOMATION_PREVIEW] + + @overload + def __init__( + self, + *, + browser_automation_preview: BrowserAutomationToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationToolConnectionParameters(_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.projects.models.BrowserAutomationToolParameters(_Model): + connection: BrowserAutomationToolConnectionParameters + + @overload + def __init__( + self, + *, + connection: BrowserAutomationToolConnectionParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CallableToolAllowedCaller(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DIRECT = "direct" + PROGRAMMATIC = "programmatic" + + + class azure.ai.projects.models.CaptureStructuredOutputsTool(Tool, discriminator='capture_structured_outputs'): + description: Optional[str] + name: Optional[str] + outputs: StructuredOutputDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.CAPTURE_STRUCTURED_OUTPUTS] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + outputs: StructuredOutputDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ChartCoordinate(_Model): + size: int + x: int + y: int + + @overload + def __init__( + self, + *, + size: int, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.ClusterInsightResult(_Model): + clusters: list[InsightCluster] + coordinates: Optional[dict[str, ChartCoordinate]] + summary: InsightSummary + + @overload + def __init__( + self, + *, + clusters: list[InsightCluster], + coordinates: Optional[dict[str, ChartCoordinate]] = ..., + summary: InsightSummary + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ClusterTokenUsage(_Model): + input_token_usage: int + output_token_usage: int + total_token_usage: int + + @overload + def __init__( + self, + *, + input_token_usage: int, + output_token_usage: int, + total_token_usage: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='code'): + blob_uri: Optional[str] + code_text: Optional[str] + data_schema: dict[str, any] + entry_point: Optional[str] + image_tag: Optional[str] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + type: Literal[EvaluatorDefinitionType.CODE] + + @overload + def __init__( + self, + *, + blob_uri: Optional[str] = ..., + code_text: Optional[str] = ..., + data_schema: Optional[dict[str, Any]] = ..., + entry_point: Optional[str] = ..., + image_tag: Optional[str] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeConfiguration(_Model): + content_hash: Optional[str] + dependency_resolution: Union[str, CodeDependencyResolution] + entry_point: list[str] + runtime: str + + @overload + def __init__( + self, + *, + dependency_resolution: Union[str, CodeDependencyResolution], + entry_point: list[str], + runtime: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeDependencyResolution(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BUNDLED = "bundled" + REMOTE_BUILD = "remote_build" + + + class azure.ai.projects.models.CodeInterpreterTool(Tool, discriminator='code_interpreter'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + container: Optional[Union[str, AutoCodeInterpreterToolParam]] + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.CODE_INTERPRETER] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeInterpreterToolboxTool(ToolboxTool, discriminator='code_interpreter'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + container: Optional[Union[str, AutoCodeInterpreterToolParam]] + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.CODE_INTERPRETER] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ComparisonFilter(_Model): + key: str + type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"] + value: Union[str, float, bool, list[Union[str, float]]] + + @overload + def __init__( + self, + *, + key: str, + type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"], + value: Union[str, float, bool, list[Union[str, float]]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.ComputerEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BROWSER = "browser" + LINUX = "linux" + MAC = "mac" + UBUNTU = "ubuntu" + WINDOWS = "windows" + + + class azure.ai.projects.models.ComputerTool(Tool, discriminator='computer'): + type: Literal[ToolType.COMPUTER] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.Connection(_Model): + credentials: BaseCredentials + id: str + is_default: bool + metadata: dict[str, str] + name: str + target: str + type: Union[str, ConnectionType] + + + class azure.ai.projects.models.ConnectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + API_KEY = "ApiKey" + APPLICATION_CONFIGURATION = "AppConfig" + APPLICATION_INSIGHTS = "AppInsights" + AZURE_AI_SEARCH = "CognitiveSearch" + AZURE_BLOB_STORAGE = "AzureBlob" + AZURE_OPEN_AI = "AzureOpenAI" + AZURE_STORAGE_ACCOUNT = "AzureStorageAccount" + COSMOS_DB = "CosmosDB" + CUSTOM = "CustomKeys" + REMOTE_TOOL = "RemoteTool_Preview" + + + class azure.ai.projects.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.projects.models.ContainerConfiguration(_Model): + image: str + registry_connection_id: Optional[str] + + @overload + def __init__( + self, + *, + image: str, + registry_connection_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerMemoryLimit(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MEMORY_16GB = "16g" + MEMORY_1GB = "1g" + MEMORY_4GB = "4g" + MEMORY_64GB = "64g" + + + class azure.ai.projects.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.projects.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.projects.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.projects.models.ContainerNetworkPolicyParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerNetworkPolicyParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWLIST = "allowlist" + DISABLED = "disabled" + + + class azure.ai.projects.models.ContainerSkill(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INLINE = "inline" + SKILL_REFERENCE = "skill_reference" + + + class azure.ai.projects.models.ContinuousEvaluationRuleAction(EvaluationRuleAction, discriminator='continuousEvaluation'): + eval_id: str + max_hourly_runs: Optional[int] + sampling_rate: Optional[float] + type: Literal[EvaluationRuleActionType.CONTINUOUS_EVALUATION] + + @overload + def __init__( + self, + *, + eval_id: str, + max_hourly_runs: Optional[int] = ..., + sampling_rate: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CosmosDBIndex(Index, discriminator='CosmosDBNoSqlVectorStore'): + connection_name: str + container_name: str + database_name: str + description: str + embedding_configuration: EmbeddingConfiguration + field_mapping: FieldMapping + id: str + name: str + tags: dict[str, str] + type: Literal[IndexType.COSMOS_DB] + version: str + + @overload + def __init__( + self, + *, + connection_name: str, + container_name: str, + database_name: str, + description: Optional[str] = ..., + embedding_configuration: EmbeddingConfiguration, + field_mapping: FieldMapping, + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateAsyncResponse(_Model): + location: Optional[str] + operation_result: Optional[str] + + @overload + def __init__( + self, + *, + location: Optional[str] = ..., + operation_result: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateSkillVersionFromFilesBody(_Model): + default: Optional[bool] + files: list[Union[str, bytes, IO[str], IO[bytes], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]]], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]], Optional[str]]]] + + @overload + def __init__( + self, + *, + default: Optional[bool] = ..., + files: list[FileType] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTeamsPhoneExtensionTelephonyBindingRequest(CreateTelephonyBindingRequest, discriminator='teams_phone_extension'): + connection: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + + @overload + def __init__( + self, + *, + connection: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTelephonyBindingRequest(_Model): + connection: str + label: Optional[str] + provider: str + + @overload + def __init__( + self, + *, + connection: str, + label: Optional[str] = ..., + provider: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTelephonyCallJobRequest(_Model): + destination: TelephonyOutboundDestination + purpose: Optional[str] + retry_policy: Optional[TelephonyOutboundRetryPolicy] + schedule: Optional[TelephonyCallJobSchedule] + structured_inputs: Optional[dict[str, Any]] + telephony_binding_id: str + + @overload + def __init__( + self, + *, + destination: TelephonyOutboundDestination, + purpose: Optional[str] = ..., + retry_policy: Optional[TelephonyOutboundRetryPolicy] = ..., + schedule: Optional[TelephonyCallJobSchedule] = ..., + structured_inputs: Optional[dict[str, Any]] = ..., + telephony_binding_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTelephonyCampaignRequest(_Model): + display_name: str + purpose: Optional[str] + retry_policy: Optional[TelephonyOutboundRetryPolicy] + schedule: Optional[TelephonyCampaignSchedule] + telephony_binding_id: str + + @overload + def __init__( + self, + *, + display_name: str, + purpose: Optional[str] = ..., + retry_policy: Optional[TelephonyOutboundRetryPolicy] = ..., + schedule: Optional[TelephonyCampaignSchedule] = ..., + telephony_binding_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTranscriptionResponseJsonUsage(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DURATION = "duration" + TOKENS = "tokens" + + + class azure.ai.projects.models.CreateTwilioTelephonyBindingRequest(CreateTelephonyBindingRequest, discriminator='twilio'): + connection: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + + @overload + def __init__( + self, + *, + connection: str, + label: Optional[str] = ..., + phone_number: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENTIC_IDENTITY_PREVIEW = "AgenticIdentityToken_Preview" + API_KEY = "ApiKey" + CUSTOM = "CustomKeys" + ENTRA_ID = "AAD" + NONE = "None" + SAS = "SAS" + + + class azure.ai.projects.models.CronTrigger(Trigger, discriminator='Cron'): + end_time: Optional[datetime] + expression: str + start_time: Optional[datetime] + time_zone: Optional[str] + type: Literal[TriggerType.CRON] + + @overload + def __init__( + self, + *, + end_time: Optional[datetime] = ..., + expression: str, + start_time: Optional[datetime] = ..., + time_zone: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomCredential(CustomCredentialGenerated, discriminator='CustomKeys'): + credential_keys: Dict[str, str] + type: Union[str, CredentialType] + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + + class azure.ai.projects.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.projects.models.CustomRoutineTrigger(RoutineTrigger, discriminator='custom'): + event_name: Optional[str] + parameters: dict[str, Any] + provider: str + type: Literal[RoutineTriggerType.CUSTOM] + + @overload + def __init__( + self, + *, + event_name: Optional[str] = ..., + parameters: dict[str, Any], + provider: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.models.CustomToolParam(Tool, discriminator='custom'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] + description: Optional[str] + format: Optional[CustomToolParamFormat] + name: str + type: Literal[ToolType.CUSTOM] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + format: Optional[CustomToolParamFormat] = ..., + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomToolParamFormat(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomToolParamFormatType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GRAMMAR = "grammar" + TEXT = "text" + + + class azure.ai.projects.models.DailyRecurrenceSchedule(RecurrenceSchedule, discriminator='Daily'): + hours: list[int] + type: Literal[RecurrenceType.DAILY] + + @overload + def __init__( + self, + *, + hours: list[int] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJob(_Model): + created_at: datetime + error: Optional[ApiError] + finished_at: Optional[datetime] + id: str + inputs: Optional[DataGenerationJobInputs] + result: Optional[DataGenerationJobResult] + status: Union[str, JobStatus] + + @overload + def __init__( + self, + *, + inputs: Optional[DataGenerationJobInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobInputs(_Model): + name: str + options: DataGenerationJobOptions + output_options: Optional[DataGenerationJobOutputOptions] + scenario: Union[str, DataGenerationJobScenario] + sources: list[DataGenerationJobSource] + + @overload + def __init__( + self, + *, + name: str, + options: DataGenerationJobOptions, + output_options: Optional[DataGenerationJobOutputOptions] = ..., + scenario: Union[str, DataGenerationJobScenario], + sources: list[DataGenerationJobSource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOptions(_Model): + max_samples: int + model_options: Optional[DataGenerationModelOptions] + train_split: Optional[float] + type: str + + @overload + def __init__( + self, + *, + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutputOptions(_Model): + description: Optional[str] + name: Optional[str] + tags: Optional[dict[str, str]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DATASET = "dataset" + FILE = "file" + + + class azure.ai.projects.models.DataGenerationJobResult(_Model): + generated_samples: int + outputs: Optional[list[DataGenerationJobOutput]] + token_usage: Optional[DataGenerationTokenUsage] + + @overload + def __init__( + self, + *, + generated_samples: int, + outputs: Optional[list[DataGenerationJobOutput]] = ..., + token_usage: Optional[DataGenerationTokenUsage] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobScenario(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION = "evaluation" + REINFORCEMENT_FINETUNING = "reinforcement_finetuning" + SUPERVISED_FINETUNING = "supervised_finetuning" + + + class azure.ai.projects.models.DataGenerationJobSource(_Model): + description: Optional[str] + type: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + FILE = "file" + PROMPT = "prompt" + TRACES = "traces" + + + class azure.ai.projects.models.DataGenerationJobType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SIMPLE_QNA = "simple_qna" + SIMULATION_SEED = "simulation_seed" + TOOL_USE = "tool_use" + TRACES = "traces" + + + class azure.ai.projects.models.DataGenerationModelOptions(_Model): + model: str + + @overload + def __init__( + self, + *, + model: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationTokenUsage(_Model): + completion_tokens: int + prompt_tokens: int + total_tokens: int + + + class azure.ai.projects.models.DatasetCredential(_Model): + blob_reference: BlobReference + + @overload + def __init__( + self, + *, + blob_reference: BlobReference + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetDataGenerationJobOutput(DataGenerationJobOutput, discriminator='dataset'): + description: Optional[str] + id: Optional[str] + name: Optional[str] + tags: Optional[dict[str, str]] + type: Literal[DataGenerationJobOutputType.DATASET] + version: Optional[str] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='dataset'): + description: Optional[str] + name: str + type: Literal[EvaluatorGenerationJobSourceType.DATASET] + version: Optional[str] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetGenerationLROPoller(LROPoller[DataGenerationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[DataGenerationJobResult], + continuation_token: str, + **kwargs: Any + ) -> DatasetGenerationLROPoller: ... + + + class azure.ai.projects.models.DatasetReference(_Model): + name: str + version: str + + @overload + def __init__( + self, + *, + name: str, + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + URI_FILE = "uri_file" + URI_FOLDER = "uri_folder" + + + class azure.ai.projects.models.DatasetVersion(_Model): + connection_name: Optional[str] + data_uri: str + description: Optional[str] + id: Optional[str] + is_reference: Optional[bool] + name: str + tags: Optional[dict[str, str]] + type: str + version: str + + @overload + def __init__( + self, + *, + connection_name: Optional[str] = ..., + data_uri: str, + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DayOfWeek(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FRIDAY = "Friday" + MONDAY = "Monday" + SATURDAY = "Saturday" + SUNDAY = "Sunday" + THURSDAY = "Thursday" + TUESDAY = "Tuesday" + WEDNESDAY = "Wednesday" + + + class azure.ai.projects.models.DeleteAgentResponse(_Model): + deleted: bool + name: str + object: Literal[AgentObjectType.AGENT_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[AgentObjectType.AGENT_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteAgentVersionResponse(_Model): + deleted: bool + name: str + object: Literal[AgentObjectType.AGENT_VERSION_DELETED] + version: str + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[AgentObjectType.AGENT_VERSION_DELETED], + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteMemoryResult(_Model): + deleted: bool + memory_id: str + object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + memory_id: str, + object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteMemoryStoreResult(_Model): + deleted: bool + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteSkillResult(_Model): + deleted: bool + id: str + name: str + + @overload + def __init__( + self, + *, + deleted: bool, + id: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteSkillVersionResult(_Model): + deleted: bool + id: str + name: str + version: str + + @overload + def __init__( + self, + *, + deleted: bool, + id: str, + name: str, + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.Deployment(_Model): + name: str + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeploymentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MODEL_DEPLOYMENT = "ModelDeployment" + + + class azure.ai.projects.models.DigitalWorkerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + M365 = "m365" + + + class azure.ai.projects.models.Dimension(_Model): + always_applicable: Optional[bool] + description: str + id: str + weight: int + + @overload + def __init__( + self, + *, + always_applicable: Optional[bool] = ..., + description: str, + id: str, + weight: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DispatchRoutineResult(_Model): + action_correlation_id: Optional[str] + dispatch_id: Optional[str] + task_id: Optional[str] + + @overload + def __init__( + self, + *, + action_correlation_id: Optional[str] = ..., + dispatch_id: Optional[str] = ..., + task_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EmbeddingConfiguration(_Model): + embedding_field: str + model_deployment_name: str + + @overload + def __init__( + self, + *, + embedding_field: str, + model_deployment_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EmptyModelParam(_Model): + + + class azure.ai.projects.models.EndpointBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='endpoint'): + connection_name: str + data_schema: dict[str, any] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + type: Literal[EvaluatorDefinitionType.ENDPOINT] + + @overload + def __init__( + self, + *, + connection_name: str, + data_schema: Optional[dict[str, Any]] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EntraAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='Entra'): + type: Literal[AgentEndpointAuthorizationSchemeType.ENTRA] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EntraIDCredentials(BaseCredentials, discriminator='AAD'): + type: Literal[CredentialType.ENTRA_ID] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalCsvFileIdSource(TypedDict, total=False): + key "id": Required[str] + key "type": Required[Literal["file_id"]] + + + class azure.ai.projects.models.EvalCsvRunDataSource(TypedDict, total=False): + key "source": Required[EvalCsvFileIdSource] + key "type": Required[Literal["csv"]] + + + class azure.ai.projects.models.EvalResult(_Model): + name: str + passed: bool + score: float + type: str + + @overload + def __init__( + self, + *, + name: str, + passed: bool, + score: float, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultCompareItem(_Model): + delta_estimate: float + p_value: float + treatment_effect: Union[str, TreatmentEffectType] + treatment_run_id: str + treatment_run_summary: EvalRunResultSummary + + @overload + def __init__( + self, + *, + delta_estimate: float, + p_value: float, + treatment_effect: Union[str, TreatmentEffectType], + treatment_run_id: str, + treatment_run_summary: EvalRunResultSummary + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultComparison(_Model): + baseline_run_summary: EvalRunResultSummary + compare_items: list[EvalRunResultCompareItem] + evaluator: str + metric: str + testing_criteria: str + + @overload + def __init__( + self, + *, + baseline_run_summary: EvalRunResultSummary, + compare_items: list[EvalRunResultCompareItem], + evaluator: str, + metric: str, + testing_criteria: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultSummary(_Model): + average: float + run_id: str + sample_count: int + standard_deviation: float + + @overload + def __init__( + self, + *, + average: float, + run_id: str, + sample_count: int, + standard_deviation: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationComparisonInsightRequest(InsightRequest, discriminator='EvaluationComparison'): + baseline_run_id: str + eval_id: str + treatment_run_ids: list[str] + type: Literal[InsightType.EVALUATION_COMPARISON] + + @overload + def __init__( + self, + *, + baseline_run_id: str, + eval_id: str, + treatment_run_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationComparisonInsightResult(InsightResult, discriminator='EvaluationComparison'): + comparisons: list[EvalRunResultComparison] + method: str + type: Literal[InsightType.EVALUATION_COMPARISON] + + @overload + def __init__( + self, + *, + comparisons: list[EvalRunResultComparison], + method: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION = "conversation" + TURN = "turn" + + + class azure.ai.projects.models.EvaluationResultSample(InsightSample, discriminator='EvaluationResultSample'): + correlation_info: dict[str, any] + evaluation_result: EvalResult + features: dict[str, any] + id: str + type: Literal[SampleType.EVALUATION_RESULT_SAMPLE] + + @overload + def __init__( + self, + *, + correlation_info: dict[str, Any], + evaluation_result: EvalResult, + features: dict[str, Any], + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRule(_Model): + action: EvaluationRuleAction + description: Optional[str] + display_name: Optional[str] + enabled: bool + event_type: Union[str, EvaluationRuleEventType] + filter: Optional[EvaluationRuleFilter] + id: str + system_data: dict[str, str] + + @overload + def __init__( + self, + *, + action: EvaluationRuleAction, + description: Optional[str] = ..., + display_name: Optional[str] = ..., + enabled: bool, + event_type: Union[str, EvaluationRuleEventType], + filter: Optional[EvaluationRuleFilter] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRuleAction(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRuleActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTINUOUS_EVALUATION = "continuousEvaluation" + HUMAN_EVALUATION_PREVIEW = "humanEvaluationPreview" + + + class azure.ai.projects.models.EvaluationRuleEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANUAL = "manual" + RESPONSE_COMPLETED = "responseCompleted" + + + class azure.ai.projects.models.EvaluationRuleFilter(_Model): + agent_name: str + + @overload + def __init__( + self, + *, + agent_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRunClusterInsightRequest(InsightRequest, discriminator='EvaluationRunClusterInsight'): + eval_id: str + model_configuration: Optional[InsightModelConfiguration] + run_ids: list[str] + type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + eval_id: str, + model_configuration: Optional[InsightModelConfiguration] = ..., + run_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRunClusterInsightResult(InsightResult, discriminator='EvaluationRunClusterInsight'): + cluster_insight: ClusterInsightResult + type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + cluster_insight: ClusterInsightResult + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationScheduleTask(ScheduleTask, discriminator='Evaluation'): + configuration: dict[str, str] + eval_id: str + eval_run: dict[str, Any] + type: Literal[ScheduleTaskType.EVALUATION] + + @overload + def __init__( + self, + *, + configuration: Optional[dict[str, str]] = ..., + eval_id: str, + eval_run: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTarget(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomy(_Model): + description: Optional[str] + id: Optional[str] + name: str + properties: Optional[dict[str, str]] + tags: Optional[dict[str, str]] + taxonomy_categories: Optional[list[TaxonomyCategory]] + taxonomy_input: EvaluationTaxonomyInput + version: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + properties: Optional[dict[str, str]] = ..., + tags: Optional[dict[str, str]] = ..., + taxonomy_categories: Optional[list[TaxonomyCategory]] = ..., + taxonomy_input: EvaluationTaxonomyInput + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomyInput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomyInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + POLICY = "policy" + + + class azure.ai.projects.models.EvaluatorCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENTS = "agents" + QUALITY = "quality" + SAFETY = "safety" + + + class azure.ai.projects.models.EvaluatorCredentialRequest(_Model): + blob_uri: str + + @overload + def __init__( + self, + *, + blob_uri: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorDefinition(_Model): + data_schema: Optional[dict[str, Any]] + init_parameters: Optional[dict[str, Any]] + metrics: Optional[dict[str, EvaluatorMetric]] + type: str + + @overload + def __init__( + self, + *, + data_schema: Optional[dict[str, Any]] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorDefinitionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE = "code" + ENDPOINT = "endpoint" + OPENAI_GRADERS = "openai_graders" + PROMPT = "prompt" + PROMPT_AND_CODE = "prompt_and_code" + RUBRIC = "rubric" + SERVICE = "service" + + + class azure.ai.projects.models.EvaluatorGenerationArtifacts(_Model): + dataset: DatasetReference + kinds: list[str] + + @overload + def __init__( + self, + *, + dataset: DatasetReference, + kinds: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationInputs(_Model): + evaluator_description: Optional[str] + evaluator_display_name: Optional[str] + evaluator_name: str + model: str + sources: list[EvaluatorGenerationJobSource] + + @overload + def __init__( + self, + *, + evaluator_description: Optional[str] = ..., + evaluator_display_name: Optional[str] = ..., + evaluator_name: str, + model: str, + sources: list[EvaluatorGenerationJobSource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJob(_Model): + created_at: datetime + error: Optional[ApiError] + finished_at: Optional[datetime] + id: str + input_quality_warnings: Optional[list[RubricGenerationInputQualityWarning]] + inputs: Optional[EvaluatorGenerationInputs] + result: Optional[EvaluatorVersion] + status: Union[str, JobStatus] + usage: Optional[EvaluatorGenerationTokenUsage] + + @overload + def __init__( + self, + *, + inputs: Optional[EvaluatorGenerationInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJobSource(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + DATASET = "dataset" + PROMPT = "prompt" + TRACES = "traces" + + + class azure.ai.projects.models.EvaluatorGenerationLROPoller(LROPoller[EvaluatorVersion]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[EvaluatorVersion], + continuation_token: str, + **kwargs: Any + ) -> EvaluatorGenerationLROPoller: ... + + + class azure.ai.projects.models.EvaluatorGenerationTokenUsage(_Model): + input_tokens: int + output_tokens: int + total_tokens: int + + @overload + def __init__( + self, + *, + input_tokens: int, + output_tokens: int, + total_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorMetric(_Model): + desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] + is_primary: Optional[bool] + max_value: Optional[float] + min_value: Optional[float] + threshold: Optional[float] + type: Optional[Union[str, EvaluatorMetricType]] + + @overload + def __init__( + self, + *, + desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] = ..., + is_primary: Optional[bool] = ..., + max_value: Optional[float] = ..., + min_value: Optional[float] = ..., + threshold: Optional[float] = ..., + type: Optional[Union[str, EvaluatorMetricType]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorMetricDirection(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DECREASE = "decrease" + INCREASE = "increase" + NEUTRAL = "neutral" + + + class azure.ai.projects.models.EvaluatorMetricType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOOLEAN = "boolean" + CONTINUOUS = "continuous" + ORDINAL = "ordinal" + + + class azure.ai.projects.models.EvaluatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BUILT_IN = "builtin" + CUSTOM = "custom" + + + class azure.ai.projects.models.EvaluatorVersion(_Model): + categories: list[Union[str, EvaluatorCategory]] + created_at: datetime + created_by: str + definition: EvaluatorDefinition + description: Optional[str] + display_name: Optional[str] + evaluator_type: Union[str, EvaluatorType] + generation_artifacts: Optional[EvaluatorGenerationArtifacts] + generation_job_id: Optional[str] + id: Optional[str] + metadata: Optional[dict[str, str]] + modified_at: datetime + name: str + supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] + tags: Optional[dict[str, str]] + version: str + warnings: Optional[list[Union[str, GenerationWarningType]]] + + @overload + def __init__( + self, + *, + categories: list[Union[str, EvaluatorCategory]], + definition: EvaluatorDefinition, + description: Optional[str] = ..., + display_name: Optional[str] = ..., + evaluator_type: Union[str, EvaluatorType], + metadata: Optional[dict[str, str]] = ..., + supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ExternalAgentDefinition(AgentDefinition, discriminator='external'): + kind: Literal[AgentKind.EXTERNAL] + otel_agent_id: Optional[str] + rai_config: RaiConfig + + @overload + def __init__( + self, + *, + otel_agent_id: Optional[str] = ..., + rai_config: Optional[RaiConfig] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricDataAgentToolParameters(_Model): + project_connections: Optional[list[ToolProjectConnection]] + + @overload + def __init__( + self, + *, + project_connections: Optional[list[ToolProjectConnection]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricIQPreviewTool(Tool, discriminator='fabric_iq_preview'): + project_connection_id: str + require_approval: Optional[Union[MCPToolRequireApproval, str]] + server_label: Optional[str] + server_url: Optional[str] + type: Literal[ToolType.FABRIC_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + project_connection_id: str, + require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., + server_label: Optional[str] = ..., + server_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricIQPreviewToolboxTool(ToolboxTool, discriminator='fabric_iq_preview'): + description: str + name: str + project_connection_id: str + require_approval: Optional[Union[MCPToolRequireApproval, str]] + server_label: Optional[str] + server_url: Optional[str] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.FABRIC_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str, + require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., + server_label: Optional[str] = ..., + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FieldMapping(_Model): + content_fields: list[str] + filepath_field: Optional[str] + metadata_fields: Optional[list[str]] + title_field: Optional[str] + url_field: Optional[str] + vector_fields: Optional[list[str]] + + @overload + def __init__( + self, + *, + content_fields: list[str], + filepath_field: Optional[str] = ..., + metadata_fields: Optional[list[str]] = ..., + title_field: Optional[str] = ..., + url_field: Optional[str] = ..., + vector_fields: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileDataGenerationJobOutput(DataGenerationJobOutput, discriminator='file'): + filename: str + id: str + type: Literal[DataGenerationJobOutputType.FILE] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileDataGenerationJobSource(DataGenerationJobSource, discriminator='file'): + description: str + id: str + type: Literal[DataGenerationJobSourceType.FILE] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileDatasetVersion(DatasetVersion, discriminator='uri_file'): + connection_name: str + data_uri: str + description: str + id: str + is_reference: bool + name: str + tags: dict[str, str] + type: Literal[DatasetType.URI_FILE] + version: str + + @overload + def __init__( + self, + *, + connection_name: Optional[str] = ..., + data_uri: str, + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileSearchTool(Tool, discriminator='file_search'): + description: Optional[str] + filters: Optional[Filters] + max_num_results: Optional[int] + name: Optional[str] + ranking_options: Optional[RankingOptions] + tool_configs: Optional[dict[str, ToolConfig]] + 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] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + vector_store_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileSearchToolboxTool(ToolboxTool, discriminator='file_search'): + description: str + filters: Optional[Filters] + max_num_results: Optional[int] + name: str + ranking_options: Optional[RankingOptions] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.FILE_SEARCH] + vector_store_ids: Optional[list[str]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + filters: Optional[Filters] = ..., + max_num_results: Optional[int] = ..., + name: Optional[str] = ..., + ranking_options: Optional[RankingOptions] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + vector_store_ids: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FixedRatioVersionSelectionRule(VersionSelectionRule, discriminator='FixedRatio'): + agent_version: str + traffic_percentage: int + type: Literal[VersionSelectorType.FIXED_RATIO] + + @overload + def __init__( + self, + *, + agent_version: str, + traffic_percentage: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FolderDatasetVersion(DatasetVersion, discriminator='uri_folder'): + connection_name: str + data_uri: str + description: str + id: str + is_reference: bool + name: str + tags: dict[str, str] + type: Literal[DatasetType.URI_FOLDER] + version: str + + @overload + def __init__( + self, + *, + connection_name: Optional[str] = ..., + data_uri: str, + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FoundryModelArtifactProfileCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DATA_ONLY = "DataOnly" + RUNTIME_DEPENDENT = "RuntimeDependent" + UNKNOWN = "Unknown" + + + class azure.ai.projects.models.FoundryModelArtifactProfileSignal(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CUSTOM_PYTHON_CODE = "CustomPythonCode" + DYNAMIC_OPS = "DynamicOps" + NATIVE_BINARY = "NativeBinary" + PICKLE_DESERIALIZATION = "PickleDeserialization" + UNKNOWN_FORMAT = "UnknownFormat" + + + class azure.ai.projects.models.FoundryModelSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LOCAL_UPLOAD = "LocalUpload" + TRAINING_JOB = "TrainingJob" + + + class azure.ai.projects.models.FoundryModelWarning(_Model): + code: Optional[Union[str, FoundryModelWarningCode]] + message: Optional[str] + + @overload + def __init__( + self, + *, + code: Optional[Union[str, FoundryModelWarningCode]] = ..., + message: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FoundryModelWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + RUNTIME_DEPENDENT_ARTIFACT = "RuntimeDependentArtifact" + UNCLASSIFIED_ARTIFACT = "UnclassifiedArtifact" + + + class azure.ai.projects.models.FoundryModelWeightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DRAFT_MODEL = "DraftModel" + FULL_WEIGHT = "FullWeight" + LO_RA = "LoRA" + + + class azure.ai.projects.models.FunctionShellToolParam(Tool, discriminator='shell'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + description: Optional[str] + environment: Optional[FunctionShellToolParamEnvironment] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.SHELL] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + description: Optional[str] = ..., + environment: Optional[FunctionShellToolParamEnvironment] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FunctionShellToolParamEnvironment(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.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.projects.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.projects.models.FunctionShellToolParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_AUTO = "container_auto" + CONTAINER_REFERENCE = "container_reference" + LOCAL = "local" + + + class azure.ai.projects.models.FunctionTool(Tool, discriminator='function'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] + description: Optional[str] + name: str + output_schema: Optional[dict[str, Any]] + parameters: dict[str, Any] + strict: bool + type: Literal[ToolType.FUNCTION] + @overload - async def update( + def __init__( self, - name: str, - body: IO[bytes], *, - content_type: str = "application/json", - **kwargs: Any - ) -> ToolboxObject: ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + name: str, + output_schema: Optional[dict[str, Any]] = ..., + parameters: dict[str, Any], + strict: bool + ) -> None: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... -namespace azure.ai.projects.models - class azure.ai.projects.models.A2APreviewTool(Tool, discriminator='a2a_preview'): - agent_card_path: Optional[str] - base_url: Optional[str] - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - type: Literal[ToolType.A2A_PREVIEW] + class azure.ai.projects.models.FunctionToolParam(_Model): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] + description: Optional[str] + name: str + output_schema: Optional[dict[str, Any]] + parameters: Optional[EmptyModelParam] + strict: Optional[bool] + type: Literal["function"] @overload def __init__( self, *, - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + name: str, + output_schema: Optional[dict[str, Any]] = ..., + parameters: Optional[EmptyModelParam] = ..., + strict: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2APreviewToolboxTool(ToolboxTool, discriminator='a2a_preview'): - agent_card_path: Optional[str] - base_url: Optional[str] - description: str + class azure.ai.projects.models.GenerateVoiceAgentRequest(_Model): + description: Optional[str] + draft: Optional[bool] + goal: Optional[str] + kind: Literal[AgentKind.VOICE] + model: Optional[str] + model_type: Optional[Union[str, VoiceModelType]] name: str - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.A2A_PREVIEW] + tools: Optional[list[VoiceAgentTool]] + use_case: Optional[str] @overload def __init__( self, *, - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., description: Optional[str] = ..., - name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + draft: Optional[bool] = ..., + goal: Optional[str] = ..., + kind: Literal[AgentKind.VOICE], + model: Optional[str] = ..., + model_type: Optional[Union[str, VoiceModelType]] = ..., + name: str, + tools: Optional[list[VoiceAgentTool]] = ..., + use_case: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2AProtocolConfiguration(_Model): + class azure.ai.projects.models.GenerationWarningType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INPUT_QUALITY = "input_quality" - class azure.ai.projects.models.A2AProtocolVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): - V1_0 = "1.0" + class azure.ai.projects.models.GitHubIssueEvent(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLOSED = "closed" + OPENED = "opened" - class azure.ai.projects.models.A2ATool(Tool, discriminator='a2a'): - a2a_version: Union[str, A2AProtocolVersion] - agent_card_path: Optional[str] - base_url: Optional[str] - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - type: Literal[ToolType.A2_A] + class azure.ai.projects.models.GitHubIssueRoutineTrigger(RoutineTrigger, discriminator='github_issue'): + connection_id: str + issue_event: Union[str, GitHubIssueEvent] + owner: str + repository: str + type: Literal[RoutineTriggerType.GITHUB_ISSUE] @overload def __init__( self, *, - a2a_version: Union[str, A2AProtocolVersion], - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ... + connection_id: str, + issue_event: Union[str, GitHubIssueEvent], + owner: str, + repository: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2AToolboxTool(ToolboxTool, discriminator='a2a'): - a2a_version: Union[str, A2AProtocolVersion] - agent_card_path: Optional[str] - base_url: Optional[str] - description: str - name: str - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.A2_A] + class azure.ai.projects.models.GrammarSyntax1(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LARK = "lark" + REGEX = "regex" + + + class azure.ai.projects.models.HeaderTelemetryEndpointAuth(TelemetryEndpointAuth, discriminator='header'): + header_name: str + secret_id: str + secret_key: str + type: Literal[TelemetryEndpointAuthType.HEADER] @overload def __init__( self, *, - a2a_version: Union[str, A2AProtocolVersion], - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., - description: Optional[str] = ..., - name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + header_name: str, + secret_id: str, + secret_key: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AISearchIndexResource(_Model): - filter: Optional[str] - index_asset_id: Optional[str] - index_name: Optional[str] - project_connection_id: Optional[str] - query_type: Optional[Union[str, AzureAISearchQueryType]] - top_k: Optional[int] + class azure.ai.projects.models.HostedAgentDefinition(AgentDefinition, discriminator='hosted'): + code_configuration: Optional[CodeConfiguration] + container_configuration: Optional[ContainerConfiguration] + cpu: str + environment_variables: Optional[dict[str, str]] + kind: Literal[AgentKind.HOSTED] + memory: str + protocol_versions: Optional[list[ProtocolVersionRecord]] + rai_config: RaiConfig + session_configuration: Optional[SessionConfiguration] + telemetry_config: Optional[TelemetryConfig] @overload def __init__( self, *, - filter: Optional[str] = ..., - index_asset_id: Optional[str] = ..., - index_name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - query_type: Optional[Union[str, AzureAISearchQueryType]] = ..., - top_k: Optional[int] = ... + code_configuration: Optional[CodeConfiguration] = ..., + container_configuration: Optional[ContainerConfiguration] = ..., + cpu: str, + environment_variables: Optional[dict[str, str]] = ..., + memory: str, + protocol_versions: Optional[list[ProtocolVersionRecord]] = ..., + rai_config: Optional[RaiConfig] = ..., + session_configuration: Optional[SessionConfiguration] = ..., + telemetry_config: Optional[TelemetryConfig] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.HourlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Hourly'): + type: Literal[RecurrenceType.HOURLY] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.HumanEvaluationPreviewRuleAction(EvaluationRuleAction, discriminator='humanEvaluationPreview'): + template_id: str + type: Literal[EvaluationRuleActionType.HUMAN_EVALUATION_PREVIEW] + + @overload + def __init__( + self, + *, + template_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.HybridSearchOptions(_Model): + embedding_weight: float + text_weight: float + + @overload + def __init__( + self, + *, + embedding_weight: float, + text_weight: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ImageGenAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + EDIT = "edit" + GENERATE = "generate" + + + class azure.ai.projects.models.ImageGenTool(Tool, discriminator='image_generation'): + action: Optional[Union[str, ImageGenAction]] + 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[Union[Literal["1024x1024"], Literal["1024x1536"], Literal["1536x1024"], Literal["auto"], str]] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.IMAGE_GENERATION] + + @overload + def __init__( + self, + *, + action: Optional[Union[str, ImageGenAction]] = ..., + 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[Union[Literal[1024x1024], Literal[1024x1536], Literal[1536x1024], Literal[auto], str]] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ActivityProtocolAccessBoundary(str, Enum, metaclass=CaseInsensitiveEnumMeta): - READ1_ON1_ALLOWLISTED = "read.1on1.allowlisted" - READ1_ON1_DEVELOPERS = "read.1on1.developers" - READ1_ON1_MANAGER = "read.1on1.manager" - READ1_ON1_TENANT = "read.1on1.tenant" - READ_GROUP_ALLOWLISTED = "read.group.allowlisted" - READ_GROUP_DEVELOPERS = "read.group.developers" - READ_GROUP_MANAGER_INVITED = "read.group.manager-invited" - READ_GROUP_MANAGER_PRESENT = "read.group.manager-present" - READ_GROUP_TENANT = "read.group.tenant" - WRITE1_ON1_ALLOWLISTED = "write.1on1.allowlisted" - WRITE1_ON1_DEVELOPERS = "write.1on1.developers" - WRITE1_ON1_MANAGER = "write.1on1.manager" - WRITE1_ON1_TENANT = "write.1on1.tenant" - WRITE_GROUP_ALLOWLISTED = "write.group.allowlisted" - WRITE_GROUP_DEVELOPERS = "write.group.developers" - WRITE_GROUP_MANAGER_INVITED = "write.group.manager-invited" - WRITE_GROUP_MANAGER_PRESENT = "write.group.manager-present" - WRITE_GROUP_TENANT = "write.group.tenant" - - - class azure.ai.projects.models.ActivityProtocolConfiguration(_Model): - access_boundaries: Optional[list[Union[str, ActivityProtocolAccessBoundary]]] - enable_m365_public_endpoint: Optional[bool] + class azure.ai.projects.models.ImageGenToolInputImageMask(_Model): + file_id: Optional[str] + image_url: Optional[str] @overload def __init__( self, *, - enable_m365_public_endpoint: Optional[bool] = ... + file_id: Optional[str] = ..., + image_url: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentBlueprintReference(_Model): - type: str + class azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest(_Model): + duplicate_handling: Optional[Union[str, TelephonyCampaignDuplicateHandling]] + mapping: Optional[TelephonyCampaignRecipientMappingRequest] + source: TelephonyCampaignRecipientImportSource @overload def __init__( self, *, - type: str + duplicate_handling: Optional[Union[str, TelephonyCampaignDuplicateHandling]] = ..., + mapping: Optional[TelephonyCampaignRecipientMappingRequest] = ..., + source: TelephonyCampaignRecipientImportSource ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentBlueprintReferenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MANAGED_AGENT_IDENTITY_BLUEPRINT = "ManagedAgentIdentityBlueprint" - - - class azure.ai.projects.models.AgentCard(_Model): + class azure.ai.projects.models.Index(_Model): description: Optional[str] - skills: list[AgentCardSkill] + id: Optional[str] + name: str + tags: Optional[dict[str, str]] + type: str version: str @overload @@ -2850,135 +7922,137 @@ namespace azure.ai.projects.models self, *, description: Optional[str] = ..., - skills: list[AgentCardSkill], - version: str + tags: Optional[dict[str, str]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentCardSkill(_Model): - description: Optional[str] - examples: Optional[list[str]] - id: str + class azure.ai.projects.models.IndexType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SEARCH = "AzureSearch" + COSMOS_DB = "CosmosDBNoSqlVectorStore" + MANAGED_AZURE_SEARCH = "ManagedAzureSearch" + + + class azure.ai.projects.models.InlineSkillParam(ContainerSkill, discriminator='inline'): + description: str name: str - tags: Optional[list[str]] + source: InlineSkillSourceParam + type: Literal[ContainerSkillType.INLINE] @overload def __init__( self, *, - description: Optional[str] = ..., - examples: Optional[list[str]] = ..., - id: str, + description: str, name: str, - tags: Optional[list[str]] = ... + source: InlineSkillSourceParam ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentClusterInsightRequest(InsightRequest, discriminator='AgentClusterInsight'): - agent_name: str - model_configuration: Optional[InsightModelConfiguration] - type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + class azure.ai.projects.models.InlineSkillSourceParam(_Model): + data: str + media_type: Literal["application/zip"] + type: Literal["base64"] @overload def __init__( self, *, - agent_name: str, - model_configuration: Optional[InsightModelConfiguration] = ... + data: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentClusterInsightResult(InsightResult, discriminator='AgentClusterInsight'): - cluster_insight: ClusterInsightResult - type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + class azure.ai.projects.models.InputFidelity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + + + class azure.ai.projects.models.Insight(_Model): + display_name: str + insight_id: str + metadata: InsightsMetadata + request: InsightRequest + result: Optional[InsightResult] + state: Union[str, OperationState] @overload def __init__( self, *, - cluster_insight: ClusterInsightResult + display_name: str, + request: InsightRequest ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentDataGenerationJobSource(DataGenerationJobSource, discriminator='agent'): - agent_name: str - agent_version: Optional[str] + class azure.ai.projects.models.InsightCluster(_Model): description: str - type: Literal[DataGenerationJobSourceType.AGENT] + id: str + label: str + samples: Optional[list[InsightSample]] + sub_clusters: Optional[list[InsightCluster]] + suggestion: str + suggestion_title: str + weight: int @overload def __init__( self, *, - agent_name: str, - agent_version: Optional[str] = ..., - description: Optional[str] = ... + description: str, + id: str, + label: str, + samples: Optional[list[InsightSample]] = ..., + sub_clusters: Optional[list[InsightCluster]] = ..., + suggestion: str, + suggestion_title: str, + weight: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentDefinition(_Model): - kind: str - rai_config: Optional[RaiConfig] + class azure.ai.projects.models.InsightModelConfiguration(_Model): + model_deployment_name: str @overload def __init__( self, *, - kind: str, - rai_config: Optional[RaiConfig] = ... + model_deployment_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentDetails(_Model): - agent_card: Optional[AgentCard] - agent_endpoint: Optional[AgentEndpointConfig] - blueprint: Optional[AgentIdentity] - blueprint_reference: Optional[AgentBlueprintReference] - digital_worker_type: Optional[Union[str, DigitalWorkerType]] - id: str - instance_identity: Optional[AgentIdentity] - name: str - object: Literal[AgentObjectType.AGENT] - state: Union[str, AgentState] - state_source: Optional[Union[str, AgentStateSource]] - versions: AgentObjectVersions + class azure.ai.projects.models.InsightRequest(_Model): + type: str @overload def __init__( self, *, - agent_card: Optional[AgentCard] = ..., - agent_endpoint: Optional[AgentEndpointConfig] = ..., - digital_worker_type: Optional[Union[str, DigitalWorkerType]] = ..., - id: str, - name: str, - object: Literal[AgentObjectType.AGENT], - versions: AgentObjectVersions + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointAuthorizationScheme(_Model): + class azure.ai.projects.models.InsightResult(_Model): type: str @overload @@ -2992,936 +8066,850 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointAuthorizationSchemeType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BOT_SERVICE = "BotService" - BOT_SERVICE_RBAC = "BotServiceRbac" - BOT_SERVICE_TENANT = "BotServiceTenant" - ENTRA = "Entra" - - - class azure.ai.projects.models.AgentEndpointConfig(_Model): - authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] - protocol_configuration: Optional[ProtocolConfiguration] - publish_approval_status: Optional[Union[str, PublishApprovalStatus]] - version_selector: Optional[VersionSelector] + class azure.ai.projects.models.InsightSample(_Model): + correlation_info: dict[str, Any] + features: dict[str, Any] + id: str + type: str @overload def __init__( self, *, - authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] = ..., - protocol_configuration: Optional[ProtocolConfiguration] = ..., - version_selector: Optional[VersionSelector] = ... + correlation_info: dict[str, Any], + features: dict[str, Any], + id: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A = "a2a" - ACTIVITY = "activity" - INVOCATIONS = "invocations" - INVOCATIONS_WS = "invocations_ws" - MCP = "mcp" - RESPONSES = "responses" - - - class azure.ai.projects.models.AgentEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='agent'): - agent_name: str - agent_version: Optional[str] - description: Optional[str] - type: Literal[EvaluatorGenerationJobSourceType.AGENT] + class azure.ai.projects.models.InsightScheduleTask(ScheduleTask, discriminator='Insight'): + configuration: dict[str, str] + insight: Insight + type: Literal[ScheduleTaskType.INSIGHT] @overload def __init__( self, *, - agent_name: str, - agent_version: Optional[str] = ..., - description: Optional[str] = ... + configuration: Optional[dict[str, str]] = ..., + insight: Insight ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentIdentity(_Model): - client_id: str - principal_id: str - status: Optional[Union[str, AgentIdentityStatus]] + class azure.ai.projects.models.InsightSummary(_Model): + method: str + sample_count: int + unique_cluster_count: int + unique_subcluster_count: int + usage: ClusterTokenUsage @overload def __init__( self, *, - client_id: str, - principal_id: str, - status: Optional[Union[str, AgentIdentityStatus]] = ... + method: str, + sample_count: int, + unique_cluster_count: int, + unique_subcluster_count: int, + usage: ClusterTokenUsage ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentIdentityStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - DISABLED = "disabled" - - - class azure.ai.projects.models.AgentInsight(_Model): - agent_name: str - agent_version: str - category: str - created_at: datetime - description: str - details: Optional[AgentInsightDetails] - id: str - monitor_id: str - severity: Union[str, AgentInsightSeverity] - status: Union[str, AgentInsightStatus] - title: str - trace_count: int - updated_at: datetime - - - class azure.ai.projects.models.AgentInsightDetails(_Model): - highlighted_traces: list[AgentInsightHighlightedTrace] - linked_traces: list[AgentInsightLinkedTrace] - recommended_actions: AgentInsightRecommendedAction + class azure.ai.projects.models.InsightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_CLUSTER_INSIGHT = "AgentClusterInsight" + EVALUATION_COMPARISON = "EvaluationComparison" + EVALUATION_RUN_CLUSTER_INSIGHT = "EvaluationRunClusterInsight" + + + class azure.ai.projects.models.InsightsMetadata(_Model): + completed_at: Optional[datetime] + created_at: datetime @overload def __init__( self, *, - highlighted_traces: list[AgentInsightHighlightedTrace], - linked_traces: list[AgentInsightLinkedTrace], - recommended_actions: AgentInsightRecommendedAction + completed_at: Optional[datetime] = ..., + created_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightEstimatedCost(_Model): - amount: float - currency: Literal["USD"] + class azure.ai.projects.models.InvocationsProtocolConfiguration(_Model): + + + class azure.ai.projects.models.InvocationsWsProtocolConfiguration(_Model): + + + class azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_invocations_api'): + input: Any + type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_INVOCATIONS_API] @overload def __init__( self, *, - amount: float + input: Any ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightHighlightedTrace(_Model): - duration_ms: timedelta - summary: str - timestamp: datetime - total_tokens: Optional[int] - trace_id: str + class azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction(RoutineAction, discriminator='invoke_agent_invocations_api'): + agent_endpoint_id: Optional[str] + agent_name: Optional[str] + input: Optional[Any] + session_id: Optional[str] + type: Literal[RoutineActionType.INVOKE_AGENT_INVOCATIONS_API] @overload def __init__( self, *, - duration_ms: timedelta, - summary: str, - timestamp: datetime, - total_tokens: Optional[int] = ... + agent_endpoint_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + input: Optional[Any] = ..., + session_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightLinkedTrace(_Model): - timestamp: datetime - trace_id: str - - - class azure.ai.projects.models.AgentInsightMonitor(_Model): - agent_name: str - enabled: bool - estimated_cost: Optional[AgentInsightEstimatedCost] - id: str - model_deployment_name: str - next_scheduled_run_at: Optional[datetime] - overview: AgentInsightsOverview - run_interval_hours: float - suspension: AgentInsightSuspension - updated_at: datetime - - - class azure.ai.projects.models.AgentInsightMonitorCreate(_Model): - agent_name: str - enabled: Optional[bool] - model_deployment_name: str - run_interval_hours: Optional[float] + class azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_responses_api'): + input: Any + type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_RESPONSES_API] @overload def __init__( self, *, - agent_name: str, - enabled: Optional[bool] = ..., - model_deployment_name: str, - run_interval_hours: Optional[float] = ... + input: Any ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightMonitorListItem(_Model): - agent_name: str - enabled: bool - estimated_cost: Optional[AgentInsightEstimatedCost] - id: str - model_deployment_name: str - next_scheduled_run_at: Optional[datetime] - run_interval_hours: float - suspension: AgentInsightSuspension - updated_at: datetime - - - class azure.ai.projects.models.AgentInsightMonitorUpdate(_Model): - enabled: Optional[bool] - model_deployment_name: Optional[str] - overview_override: Optional[AgentInsightsOverviewOverride] - run_interval_hours: Optional[float] + class azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction(RoutineAction, discriminator='invoke_agent_responses_api'): + agent_endpoint_id: Optional[str] + agent_name: Optional[str] + conversation: Optional[str] + input: Optional[Any] + type: Literal[RoutineActionType.INVOKE_AGENT_RESPONSES_API] @overload def __init__( self, *, - enabled: Optional[bool] = ..., - model_deployment_name: Optional[str] = ..., - overview_override: Optional[AgentInsightsOverviewOverride] = ..., - run_interval_hours: Optional[float] = ... + agent_endpoint_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + conversation: Optional[str] = ..., + input: Optional[Any] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightOverviewSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GENERATED = "generated" - USER_OVERRIDE = "user_override" - - - class azure.ai.projects.models.AgentInsightPromptSurface(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INSTRUCTIONS = "instructions" - TOOL = "tool" + class azure.ai.projects.models.JobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + SUCCEEDED = "succeeded" - class azure.ai.projects.models.AgentInsightProposedFix(_Model): - changes: Optional[list[AgentInsightProposedFixChange]] - kind: Union[str, AgentInsightProposedFixKind] - text: str + class azure.ai.projects.models.LocalShellToolParam(Tool, discriminator='local_shell'): + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.LOCAL_SHELL] @overload def __init__( self, *, - changes: Optional[list[AgentInsightProposedFixChange]] = ..., - kind: Union[str, AgentInsightProposedFixKind], - text: str + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightProposedFixChange(_Model): - diff: Optional[str] - language: Optional[str] - new_value: Optional[Any] - old_value: Optional[Any] - path: Optional[str] - surface: Optional[Union[str, AgentInsightPromptSurface]] - target: Optional[str] + class azure.ai.projects.models.LocalSkillParam(_Model): + description: str + name: str + path: str @overload def __init__( self, *, - diff: Optional[str] = ..., - language: Optional[str] = ..., - new_value: Optional[Any] = ..., - old_value: Optional[Any] = ..., - path: Optional[str] = ..., - surface: Optional[Union[str, AgentInsightPromptSurface]] = ..., - target: Optional[str] = ... + description: str, + name: str, + path: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightProposedFixKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE_CHANGE = "code_change" - PROMPT_CHANGE = "prompt_change" - PROSE = "prose" - - - class azure.ai.projects.models.AgentInsightRecommendedAction(_Model): - proposed_fix: AgentInsightProposedFix + class azure.ai.projects.models.LogProbProperties(_Model): + bytes: list[int] + logprob: float + token: str @overload def __init__( self, *, - proposed_fix: AgentInsightProposedFix + bytes: list[int], + logprob: float, + token: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRun(_Model): - agent_name: str - completed_at: Optional[datetime] - created_at: datetime - error: Optional[ApiError] - id: str - inputs: Optional[AgentInsightRunCreate] - model_deployment_name: str - monitor_id: str - result: Optional[AgentInsightRunResult] - started_at: Optional[datetime] - status: Union[str, JobStatus] - trigger: Union[str, AgentInsightRunTrigger] - updated_at: datetime - window_end: datetime - window_start: datetime + class azure.ai.projects.models.LoraConfig(_Model): + alpha: Optional[int] + dropout: Optional[float] + rank: Optional[int] + target_modules: Optional[list[str]] @overload def __init__( self, *, - inputs: Optional[AgentInsightRunCreate] = ... + alpha: Optional[int] = ..., + dropout: Optional[float] = ..., + rank: Optional[int] = ..., + target_modules: Optional[list[str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunCreate(_Model): - lookback_hours: Optional[float] + class azure.ai.projects.models.MCPListToolsTool(_Model): + annotations: Optional[MCPListToolsToolAnnotations] + description: Optional[str] + input_schema: MCPListToolsToolInputSchema + name: str @overload def __init__( self, *, - lookback_hours: Optional[float] = ... + annotations: Optional[MCPListToolsToolAnnotations] = ..., + description: Optional[str] = ..., + input_schema: MCPListToolsToolInputSchema, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunLROPoller(LROPoller[AgentInsightRunResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.MCPListToolsToolAnnotations(_Model): - def __init__( - self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any - ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[AgentInsightRunResult], - continuation_token: str, - **kwargs: Any - ) -> AgentInsightRunLROPoller: ... + class azure.ai.projects.models.MCPListToolsToolInputSchema(_Model): - class azure.ai.projects.models.AgentInsightRunResult(_Model): - insights_created: int - insights_reopened: int - insights_updated: int - token_usage: AgentInsightTokenUsage - traces_analyzed: int - traces_in_window: int + class azure.ai.projects.models.MCPTool(Tool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + 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"]] + defer_loading: Optional[bool] + 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] + tool_configs: Optional[dict[str, ToolConfig]] + tunnel_id: Optional[str] + type: Literal[ToolType.MCP] @overload def __init__( self, *, - insights_created: int, - insights_reopened: int, - insights_updated: int, - token_usage: AgentInsightTokenUsage, - traces_analyzed: int, - traces_in_window: int + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + 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]] = ..., + defer_loading: Optional[bool] = ..., + 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] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + tunnel_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ON_DEMAND = "on_demand" - SCHEDULED = "scheduled" - - - class azure.ai.projects.models.AgentInsightSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MEDIUM = "medium" - - - class azure.ai.projects.models.AgentInsightStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - IGNORED = "ignored" - RESOLVED = "resolved" - - - class azure.ai.projects.models.AgentInsightSuspension(_Model): - code: str - details: Optional[dict[str, Any]] - message: str - occurred_at: datetime + class azure.ai.projects.models.MCPToolFilter(_Model): + read_only: Optional[bool] + tool_names: Optional[list[str]] @overload def __init__( self, *, - code: str, - details: Optional[dict[str, Any]] = ..., - message: str, - occurred_at: datetime + read_only: Optional[bool] = ..., + tool_names: Optional[list[str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightTokenUsage(_Model): - cached_tokens: Optional[int] - input_tokens: int - output_tokens: int - total_tokens: int + class azure.ai.projects.models.MCPToolRequireApproval(_Model): + always: Optional[MCPToolFilter] + never: Optional[MCPToolFilter] @overload def __init__( self, *, - cached_tokens: Optional[int] = ..., - input_tokens: int, - output_tokens: int, - total_tokens: int + always: Optional[MCPToolFilter] = ..., + never: Optional[MCPToolFilter] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightUpdate(_Model): - status: Optional[Union[str, AgentInsightStatus]] + class azure.ai.projects.models.MCPToolboxTool(ToolboxTool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + 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"]] + defer_loading: Optional[bool] + description: str + headers: Optional[dict[str, str]] + name: 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] + tool_configs: dict[str, ToolConfig] + tunnel_id: Optional[str] + type: Literal[ToolboxToolType.MCP] @overload def __init__( self, *, - status: Optional[Union[str, AgentInsightStatus]] = ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + 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]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + headers: Optional[dict[str, str]] = ..., + name: Optional[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] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + tunnel_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightsOverview(_Model): - content: str - source: Union[str, AgentInsightOverviewSource] - updated_at: datetime + class azure.ai.projects.models.ManagedAgentIdentityBlueprintReference(AgentBlueprintReference, discriminator='ManagedAgentIdentityBlueprint'): + blueprint_id: str + type: Literal[AgentBlueprintReferenceType.MANAGED_AGENT_IDENTITY_BLUEPRINT] @overload def __init__( self, *, - content: str, - source: Union[str, AgentInsightOverviewSource], - updated_at: datetime + blueprint_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightsOverviewOverride(_Model): - content: str + class azure.ai.projects.models.ManagedAzureAISearchIndex(Index, discriminator='ManagedAzureSearch'): + description: str + id: str + name: str + tags: dict[str, str] + type: Literal[IndexType.MANAGED_AZURE_SEARCH] + vector_store_id: str + version: str @overload def __init__( self, *, - content: str + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + vector_store_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EXTERNAL = "external" - HOSTED = "hosted" - PROMPT = "prompt" - WORKFLOW = "workflow" - - - class azure.ai.projects.models.AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - AGENT_CONTAINER = "agent.container" - AGENT_DELETED = "agent.deleted" - AGENT_VERSION = "agent.version" - AGENT_VERSION_DELETED = "agent.version.deleted" + class azure.ai.projects.models.McpProtocolConfiguration(_Model): - class azure.ai.projects.models.AgentObjectVersions(_Model): - latest: AgentVersionDetails + class azure.ai.projects.models.MemoryItem(_Model): + content: str + kind: str + memory_id: str + scope: str + updated_at: datetime @overload def __init__( self, *, - latest: AgentVersionDetails + 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.projects.models.AgentOptimizationCandidate(_Model): - avg_score: float - avg_tokens: float - candidate_id: Optional[str] - eval_id: Optional[str] - eval_run_id: Optional[str] - mutations: Optional[dict[str, Any]] - name: str - promotion: Optional[PromotionInfo] + class azure.ai.projects.models.MemoryItemKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHAT_SUMMARY = "chat_summary" + PROCEDURAL = "procedural" + USER_PROFILE = "user_profile" + + + class azure.ai.projects.models.MemoryOperation(_Model): + kind: Union[str, MemoryOperationKind] + memory_item: MemoryItem @overload def __init__( self, *, - avg_score: float, - avg_tokens: float, - candidate_id: Optional[str] = ..., - eval_id: Optional[str] = ..., - eval_run_id: Optional[str] = ..., - mutations: Optional[dict[str, Any]] = ..., - name: str, - promotion: Optional[PromotionInfo] = ... + kind: Union[str, MemoryOperationKind], + memory_item: MemoryItem ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetCriterion(_Model): - instruction: str - name: str + class azure.ai.projects.models.MemoryOperationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATE = "create" + DELETE = "delete" + UPDATE = "update" + + + class azure.ai.projects.models.MemorySearchItem(_Model): + memory_item: MemoryItem @overload def __init__( self, *, - instruction: str, - name: str + memory_item: MemoryItem ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetInput(_Model): - type: str + class azure.ai.projects.models.MemorySearchOptions(_Model): + max_memories: Optional[int] @overload def __init__( self, *, - type: str + max_memories: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INLINE = "inline" - REFERENCE = "reference" - - - class azure.ai.projects.models.AgentOptimizationDatasetItem(_Model): - criteria: Optional[list[AgentOptimizationDatasetCriterion]] - desired_num_turns: Optional[int] - ground_truth: Optional[str] - query: Optional[str] + class azure.ai.projects.models.MemorySearchPreviewTool(Tool, discriminator='memory_search_preview'): + memory_store_name: str + scope: str + search_options: Optional[MemorySearchOptions] + type: Literal[ToolType.MEMORY_SEARCH_PREVIEW] + update_delay: Optional[int] @overload def __init__( self, *, - criteria: Optional[list[AgentOptimizationDatasetCriterion]] = ..., - desired_num_turns: Optional[int] = ..., - ground_truth: Optional[str] = ..., - query: Optional[str] = ... + memory_store_name: str, + scope: str, + search_options: Optional[MemorySearchOptions] = ..., + update_delay: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationEvaluatorRef(_Model): - name: str - version: Optional[str] + class azure.ai.projects.models.MemoryStoreDefaultDefinition(MemoryStoreDefinition, discriminator='default'): + chat_model: str + embedding_model: str + kind: Literal[MemoryStoreKind.DEFAULT] + options: Optional[MemoryStoreDefaultOptions] @overload def __init__( self, *, - name: str, - version: Optional[str] = ... + chat_model: str, + embedding_model: str, + options: Optional[MemoryStoreDefaultOptions] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationInlineDatasetInput(AgentOptimizationDatasetInput, discriminator='inline'): - dataset_items: list[AgentOptimizationDatasetItem] - type: Literal[AgentOptimizationDatasetInputType.INLINE] + class azure.ai.projects.models.MemoryStoreDefaultOptions(_Model): + chat_summary_enabled: bool + default_ttl_seconds: Optional[timedelta] + procedural_memory_enabled: Optional[bool] + user_profile_details: Optional[str] + user_profile_enabled: bool @overload def __init__( self, *, - dataset_items: list[AgentOptimizationDatasetItem] + chat_summary_enabled: bool, + default_ttl_seconds: Optional[timedelta] = ..., + procedural_memory_enabled: Optional[bool] = ..., + user_profile_details: Optional[str] = ..., + user_profile_enabled: bool ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJob(_Model): - created_at: datetime - error: Optional[ApiError] - id: str - inputs: Optional[AgentOptimizationJobInputs] - progress: Optional[AgentOptimizationJobProgress] - result: Optional[AgentOptimizationJobResult] - status: Union[str, JobStatus] - updated_at: datetime - warnings: Optional[list[str]] + class azure.ai.projects.models.MemoryStoreDefinition(_Model): + kind: str @overload def __init__( self, *, - inputs: Optional[AgentOptimizationJobInputs] = ... + kind: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobInputs(_Model): - agent: OptimizedAgentIdentifier - evaluators: list[AgentOptimizationEvaluatorRef] - options: Optional[AgentOptimizationOptions] - train_dataset: AgentOptimizationDatasetInput - validation_dataset: Optional[AgentOptimizationDatasetInput] + class azure.ai.projects.models.MemoryStoreDeleteScopeResult(_Model): + deleted: bool + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED] + scope: str @overload def __init__( self, *, - agent: OptimizedAgentIdentifier, - evaluators: list[AgentOptimizationEvaluatorRef], - options: Optional[AgentOptimizationOptions] = ..., - train_dataset: AgentOptimizationDatasetInput, - validation_dataset: Optional[AgentOptimizationDatasetInput] = ... + deleted: bool, + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED], + scope: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobListItem(_Model): - agent: Optional[OptimizedAgentIdentifier] + class azure.ai.projects.models.MemoryStoreDetails(_Model): created_at: datetime - error: Optional[ApiError] + definition: MemoryStoreDefinition + description: Optional[str] id: str - progress: Optional[AgentOptimizationJobProgress] - status: Union[str, JobStatus] + metadata: Optional[dict[str, str]] + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE] updated_at: datetime - - class azure.ai.projects.models.AgentOptimizationJobProgress(_Model): - best_score: float - candidates_completed: int - elapsed_seconds: float - @overload def __init__( self, *, - best_score: float, - candidates_completed: int, - elapsed_seconds: float + created_at: datetime, + definition: MemoryStoreDefinition, + description: Optional[str] = ..., + id: str, + metadata: Optional[dict[str, str]] = ..., + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE], + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobResult(_Model): - baseline: Optional[str] - best: Optional[str] - candidates: Optional[list[AgentOptimizationCandidate]] + class azure.ai.projects.models.MemoryStoreKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DEFAULT = "default" - @overload - def __init__( - self, - *, - baseline: Optional[str] = ..., - best: Optional[str] = ..., - candidates: Optional[list[AgentOptimizationCandidate]] = ... - ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.MemoryStoreObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MEMORY_DELETED = "memory_store.item.deleted" + MEMORY_STORE = "memory_store" + MEMORY_STORE_DELETED = "memory_store.deleted" + MEMORY_STORE_SCOPE_DELETED = "memory_store.scope.deleted" - class azure.ai.projects.models.AgentOptimizationLROPoller(LROPoller[AgentOptimizationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.MemoryStoreOperationUsage(_Model): + embedding_tokens: int + input_tokens: int + input_tokens_details: ResponseUsageInputTokensDetails + output_tokens: int + output_tokens_details: ResponseUsageOutputTokensDetails + total_tokens: int + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + embedding_tokens: int, + input_tokens: int, + input_tokens_details: ResponseUsageInputTokensDetails, + output_tokens: int, + output_tokens_details: ResponseUsageOutputTokensDetails, + total_tokens: int ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[AgentOptimizationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AgentOptimizationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationOptions(_Model): - eval_model: Optional[str] - evaluation_level: Optional[Union[str, EvaluationLevel]] - max_candidates: Optional[int] - max_stalls: Optional[int] - optimization_config: Optional[dict[str, Any]] - optimization_model: Optional[str] + class azure.ai.projects.models.MemoryStoreSearchResult(_Model): + memories: list[MemorySearchItem] + search_id: str + usage: MemoryStoreOperationUsage @overload def __init__( self, *, - eval_model: Optional[str] = ..., - evaluation_level: Optional[Union[str, EvaluationLevel]] = ..., - max_candidates: Optional[int] = ..., - max_stalls: Optional[int] = ..., - optimization_config: Optional[dict[str, Any]] = ..., - optimization_model: Optional[str] = ... + memories: list[MemorySearchItem], + search_id: str, + usage: MemoryStoreOperationUsage ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationReferenceDatasetInput(AgentOptimizationDatasetInput, discriminator='reference'): - name: str - type: Literal[AgentOptimizationDatasetInputType.REFERENCE] - version: Optional[str] + class azure.ai.projects.models.MemoryStoreUpdateCompletedResult(_Model): + memory_operations: list[MemoryOperation] + usage: MemoryStoreOperationUsage @overload def __init__( self, *, - name: str, - version: Optional[str] = ... + memory_operations: list[MemoryOperation], + usage: MemoryStoreOperationUsage ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentSessionResource(_Model): - agent_session_id: str - created_at: datetime - expires_at: datetime - last_accessed_at: datetime - status: Union[str, AgentSessionStatus] - version_indicator: VersionIndicator + class azure.ai.projects.models.MemoryStoreUpdateResult(_Model): + error: Optional[ApiError] + result: Optional[MemoryStoreUpdateCompletedResult] + status: Union[str, MemoryStoreUpdateStatus] + superseded_by: Optional[str] + update_id: str @overload def __init__( self, *, - agent_session_id: str, - status: Union[str, AgentSessionStatus], - version_indicator: VersionIndicator + error: Optional[ApiError] = ..., + result: Optional[MemoryStoreUpdateCompletedResult] = ..., + status: Union[str, MemoryStoreUpdateStatus], + superseded_by: Optional[str] = ..., + update_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentSessionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - CREATING = "creating" - DELETED = "deleted" - DELETING = "deleting" - EXPIRED = "expired" + class azure.ai.projects.models.MemoryStoreUpdateStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" FAILED = "failed" - IDLE = "idle" - UPDATING = "updating" - - - class azure.ai.projects.models.AgentState(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DISABLED = "disabled" - ENABLED = "enabled" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + SUPERSEDED = "superseded" - class azure.ai.projects.models.AgentStateSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT_BLUEPRINT = "agent_blueprint" - AGENT_INSTANCE_IDENTITY = "agent_instance_identity" + class azure.ai.projects.models.Metadata(_Model): - class azure.ai.projects.models.AgentTaxonomyInput(EvaluationTaxonomyInput, discriminator='agent'): - risk_categories: list[Union[str, RiskCategory]] - target: EvaluationTarget - type: Literal[EvaluationTaxonomyInputType.AGENT] + class azure.ai.projects.models.Microsoft365PermissionScopes(_Model): + resource_app_id: str + scopes: list[str] @overload def __init__( self, *, - risk_categories: list[Union[str, RiskCategory]], - target: EvaluationTarget + resource_app_id: str, + scopes: list[str] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentVersionDetails(_Model): - agent_guid: Optional[str] - blueprint: Optional[AgentIdentity] - blueprint_reference: Optional[AgentBlueprintReference] - created_at: datetime - definition: AgentDefinition - description: Optional[str] - draft: Optional[bool] - id: str - instance_identity: Optional[AgentIdentity] - metadata: dict[str, str] - name: str - object: Literal[AgentObjectType.AGENT_VERSION] - status: Optional[Union[str, AgentVersionStatus]] - version: str + class azure.ai.projects.models.Microsoft365PublishDefaults(_Model): + agent_display_name: Optional[str] + agent_name: Optional[str] + app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] + app_registration_client_id: Optional[str] + app_version: Optional[str] + bot_service_arm_id: Optional[str] + developer_name: Optional[str] + developer_website_url: Optional[str] + full_description: Optional[str] + privacy_url: Optional[str] + recommended_next_app_version: Optional[str] + short_description: Optional[str] + teams_app_id: Optional[str] + terms_of_use_url: Optional[str] + title_id: Optional[str] @overload def __init__( self, *, - created_at: datetime, - definition: AgentDefinition, - description: Optional[str] = ..., - draft: Optional[bool] = ..., - id: str, - metadata: dict[str, str], - name: str, - object: Literal[AgentObjectType.AGENT_VERSION], - status: Optional[Union[str, AgentVersionStatus]] = ..., - version: str + agent_display_name: Optional[str] = ..., + agent_name: Optional[str] = ..., + app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] = ..., + app_registration_client_id: Optional[str] = ..., + app_version: Optional[str] = ..., + bot_service_arm_id: Optional[str] = ..., + developer_name: Optional[str] = ..., + developer_website_url: Optional[str] = ..., + full_description: Optional[str] = ..., + privacy_url: Optional[str] = ..., + recommended_next_app_version: Optional[str] = ..., + short_description: Optional[str] = ..., + teams_app_id: Optional[str] = ..., + terms_of_use_url: Optional[str] = ..., + title_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentVersionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - CREATING = "creating" - DELETED = "deleted" - DELETING = "deleting" - FAILED = "failed" - - - class azure.ai.projects.models.AgenticIdentityPreviewCredentials(BaseCredentials, discriminator='AgenticIdentityToken_Preview'): - type: Literal[CredentialType.AGENTIC_IDENTITY_PREVIEW] + class azure.ai.projects.models.Microsoft365PublishResult(_Model): + teams_app_id: Optional[str] + title_id: Optional[str] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + teams_app_id: Optional[str] = ..., + title_id: Optional[str] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiError(_Model): - additional_info: Optional[dict[str, Any]] - code: str - debug_info: Optional[dict[str, Any]] - details: Optional[list[ApiError]] - message: str - param: Optional[str] - type: Optional[str] + class azure.ai.projects.models.Microsoft365PublishScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PERSONAL = "Personal" + SHARED = "Shared" + TENANT = "Tenant" + + + class azure.ai.projects.models.MicrosoftFabricPreviewTool(Tool, discriminator='fabric_dataagent_preview'): + fabric_dataagent_preview: FabricDataAgentToolParameters + type: Literal[ToolType.FABRIC_DATAAGENT_PREVIEW] @overload def __init__( self, *, - additional_info: Optional[dict[str, Any]] = ..., - code: str, - debug_info: Optional[dict[str, Any]] = ..., - details: Optional[list[ApiError]] = ..., - message: str, - param: Optional[str] = ..., - type: Optional[str] = ... + fabric_dataagent_preview: FabricDataAgentToolParameters ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiErrorResponse(_Model): - error: ApiError + class azure.ai.projects.models.ModelCredentialRequest(_Model): + blob_uri: str @overload def __init__( self, *, - error: ApiError + blob_uri: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiKeyCredentials(BaseCredentials, discriminator='ApiKey'): - api_key: Optional[str] - type: Literal[CredentialType.API_KEY] + class azure.ai.projects.models.ModelDeployment(Deployment, discriminator='ModelDeployment'): + capabilities: dict[str, str] + connection_name: Optional[str] + model_name: str + model_publisher: str + model_version: str + name: str + sku: ModelDeploymentSku + type: Literal[DeploymentType.MODEL_DEPLOYMENT] @overload def __init__(self) -> None: ... @@ -3930,437 +8918,361 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApplyPatchToolParam(Tool, discriminator='apply_patch'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - type: Literal[ToolType.APPLY_PATCH] + class azure.ai.projects.models.ModelDeploymentSku(_Model): + capacity: int + family: str + name: str + size: str + tier: str @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ... + capacity: int, + family: str, + name: str, + size: str, + tier: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApproximateLocation(_Model): - city: Optional[str] - country: Optional[str] - region: Optional[str] - timezone: Optional[str] - type: Literal["approximate"] + class azure.ai.projects.models.ModelPendingUploadRequest(_Model): + connection_name: Optional[str] + pending_upload_id: Optional[str] + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] @overload def __init__( self, *, - city: Optional[str] = ..., - country: Optional[str] = ..., - region: Optional[str] = ..., - timezone: Optional[str] = ... + connection_name: Optional[str] = ..., + pending_upload_id: Optional[str] = ..., + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ArtifactProfile(_Model): - category: Union[str, FoundryModelArtifactProfileCategory] - signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] + class azure.ai.projects.models.ModelPendingUploadResponse(_Model): + blob_reference: BlobReference + pending_upload_id: str + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - category: Union[str, FoundryModelArtifactProfileCategory], - signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] = ... + blob_reference: BlobReference, + pending_upload_id: str, + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE], + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncAgentInsightRunLROPoller(AsyncLROPoller[AgentInsightRunResult]): - property details: Mapping[str, Any] # Read-only - - def __init__( - self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any - ) -> None: ... - - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[AgentInsightRunResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncAgentInsightRunLROPoller: ... + class azure.ai.projects.models.ModelSamplingConfigParam(TypedDict, total=False): + key "max_completion_tokens": int + key "seed": int + key "temperature": float + key "top_p": float - class azure.ai.projects.models.AsyncAgentOptimizationLROPoller(AsyncLROPoller[AgentOptimizationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.ModelSamplingParams(_Model): + max_completion_tokens: Optional[int] + seed: Optional[int] + temperature: Optional[float] + top_p: Optional[float] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + max_completion_tokens: Optional[int] = ..., + seed: Optional[int] = ..., + temperature: Optional[float] = ..., + top_p: Optional[float] = ... ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[AgentOptimizationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncAgentOptimizationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncDatasetGenerationLROPoller(AsyncLROPoller[DataGenerationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.ModelSourceData(_Model): + job_id: Optional[str] + source_type: Optional[Union[str, FoundryModelSourceType]] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + job_id: Optional[str] = ..., + source_type: Optional[Union[str, FoundryModelSourceType]] = ... ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[DataGenerationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncDatasetGenerationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncEvaluatorGenerationLROPoller(AsyncLROPoller[EvaluatorVersion]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.ModelVersion(_Model): + artifact_profile: Optional[ArtifactProfile] + base_model: Optional[str] + blob_uri: str + description: Optional[str] + id: Optional[str] + lora_config: Optional[LoraConfig] + name: str + source: Optional[ModelSourceData] + tags: Optional[dict[str, str]] + version: str + warnings: Optional[list[FoundryModelWarning]] + weight_type: Optional[Union[str, FoundryModelWeightType]] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + base_model: Optional[str] = ..., + blob_uri: str, + description: Optional[str] = ..., + lora_config: Optional[LoraConfig] = ..., + source: Optional[ModelSourceData] = ..., + tags: Optional[dict[str, str]] = ..., + weight_type: Optional[Union[str, FoundryModelWeightType]] = ... ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[EvaluatorVersion], - continuation_token: str, - **kwargs: Any - ) -> AsyncEvaluatorGenerationLROPoller: ... - - - class azure.ai.projects.models.AsyncUpdateMemoriesLROPoller(AsyncLROPoller[MemoryStoreUpdateCompletedResult]): - property superseded_by: Optional[str] # Read-only - property update_id: str # Read-only - - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[MemoryStoreUpdateCompletedResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncUpdateMemoriesLROPoller: ... - - - class azure.ai.projects.models.AttackStrategy(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ANSI_ATTACK = "ansi_attack" - ASCII_ART = "ascii_art" - ASCII_SMUGGLER = "ascii_smuggler" - ATBASH = "atbash" - BASE64 = "base64" - BASELINE = "baseline" - BINARY = "binary" - CAESAR = "caesar" - CHARACTER_SPACE = "character_space" - CHARACTER_SWAP = "character_swap" - CRESCENDO = "crescendo" - DIACRITIC = "diacritic" - DIFFICULT = "difficult" - EASY = "easy" - FLIP = "flip" - INDIRECT_JAILBREAK = "indirect_jailbreak" - JAILBREAK = "jailbreak" - LEETSPEAK = "leetspeak" - MODERATE = "moderate" - MORSE = "morse" - MULTI_TURN = "multi_turn" - ROT13 = "rot13" - STRING_JOIN = "string_join" - SUFFIX_APPEND = "suffix_append" - TENSE = "tense" - UNICODE_CONFUSABLE = "unicode_confusable" - UNICODE_SUBSTITUTION = "unicode_substitution" - URL = "url" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AutoCodeInterpreterToolParam(_Model): - file_ids: Optional[list[str]] - memory_limit: Optional[Union[str, ContainerMemoryLimit]] - network_policy: Optional[ContainerNetworkPolicyParam] - type: Literal["auto"] + class azure.ai.projects.models.MonthlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Monthly'): + days_of_month: list[int] + type: Literal[RecurrenceType.MONTHLY] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ContainerNetworkPolicyParam] = ... + days_of_month: list[int] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIAgentTarget(EvaluationTarget, discriminator='azure_ai_agent'): - name: str - tool_descriptions: Optional[list[ToolDescription]] - tools: Optional[list[Tool]] - type: Literal["azure_ai_agent"] - version: Optional[str] + class azure.ai.projects.models.NamespaceToolParam(Tool, discriminator='namespace'): + description: str + name: str + tools: list[Union[FunctionToolParam, CustomToolParam]] + type: Literal[ToolType.NAMESPACE] @overload def __init__( self, *, + description: str, name: str, - tool_descriptions: Optional[list[ToolDescription]] = ..., - tools: Optional[list[Tool]] = ..., - version: Optional[str] = ... + tools: list[Union[FunctionToolParam, CustomToolParam]] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIAgentTargetParam(TypedDict, total=False): - key "name": Required[str] - key "tool_descriptions": List[ToolDescriptionParam] - key "type": Required[Literal["azure_ai_agent"]] - key "version": str - - - class azure.ai.projects.models.AzureAIBenchmarkPreviewEvalRunDataSource(TypedDict, total=False): - key "input_messages": InputMessagesItemReference - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_benchmark_preview"]] + class azure.ai.projects.models.NoAuthenticationCredentials(BaseCredentials, discriminator='None'): + type: Literal[CredentialType.NONE] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.AzureAIDataSourceConfig(TypedDict, total=False): - key "scenario": Required[str] - key "type": Required[Literal["azure_ai_source"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIModelTarget(EvaluationTarget, discriminator='azure_ai_model'): - model: Optional[str] - sampling_params: Optional[ModelSamplingParams] - type: Literal["azure_ai_model"] + class azure.ai.projects.models.OneTimeTrigger(Trigger, discriminator='OneTime'): + time_zone: Optional[str] + trigger_at: datetime + type: Literal[TriggerType.ONE_TIME] @overload def __init__( self, *, - model: Optional[str] = ..., - sampling_params: Optional[ModelSamplingParams] = ... + time_zone: Optional[str] = ..., + trigger_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIModelTargetParam(TypedDict, total=False): - key "model": str - key "sampling_params": ModelSamplingConfigParam - key "type": Required[Literal["azure_ai_model"]] + class azure.ai.projects.models.OpenApiAnonymousAuthDetails(OpenApiAuthDetails, discriminator='anonymous'): + type: Literal[OpenApiAuthType.ANONYMOUS] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.AzureAIResponsesEvalRunDataSource(TypedDict, total=False): - key "event_configuration_id": str - key "item_generation_params": Required[ResponseRetrievalItemGenerationParams] - key "max_runs_hourly": int - key "type": Required[Literal["azure_ai_responses"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchIndex(Index, discriminator='AzureSearch'): - connection_name: str - description: str - field_mapping: Optional[FieldMapping] - id: str - index_name: str - name: str - tags: dict[str, str] - type: Literal[IndexType.AZURE_SEARCH] - version: str + class azure.ai.projects.models.OpenApiAuthDetails(_Model): + type: str @overload def __init__( self, *, - connection_name: str, - description: Optional[str] = ..., - field_mapping: Optional[FieldMapping] = ..., - index_name: str, - tags: Optional[dict[str, str]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.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.projects.models.OpenApiAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANONYMOUS = "anonymous" + MANAGED_IDENTITY = "managed_identity" + PROJECT_CONNECTION = "project_connection" - class azure.ai.projects.models.AzureAISearchTool(Tool, discriminator='azure_ai_search'): - azure_ai_search: AzureAISearchToolResource + class azure.ai.projects.models.OpenApiFunctionDefinition(_Model): + auth: OpenApiAuthDetails + default_params: Optional[list[str]] description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.AZURE_AI_SEARCH] + functions: Optional[list[OpenApiFunctionDefinitionFunction]] + name: str + spec: dict[str, Any] @overload def __init__( self, *, - azure_ai_search: AzureAISearchToolResource, + auth: OpenApiAuthDetails, + default_params: Optional[list[str]] = ..., description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + name: str, + spec: dict[str, Any] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchToolResource(_Model): - indexes: list[AISearchIndexResource] + class azure.ai.projects.models.OpenApiFunctionDefinitionFunction(_Model): + description: Optional[str] + name: str + parameters: dict[str, Any] @overload def __init__( self, *, - indexes: list[AISearchIndexResource] + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchToolboxTool(ToolboxTool, discriminator='azure_ai_search'): - azure_ai_search: AzureAISearchToolResource - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.AZURE_AI_SEARCH] + class azure.ai.projects.models.OpenApiManagedAuthDetails(OpenApiAuthDetails, discriminator='managed_identity'): + security_scheme: OpenApiManagedSecurityScheme + type: Literal[OpenApiAuthType.MANAGED_IDENTITY] @overload def __init__( self, *, - azure_ai_search: AzureAISearchToolResource, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + security_scheme: OpenApiManagedSecurityScheme ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionBinding(_Model): - storage_queue: AzureFunctionStorageQueue - type: Literal["storage_queue"] + class azure.ai.projects.models.OpenApiManagedSecurityScheme(_Model): + audience: str @overload def __init__( self, *, - storage_queue: AzureFunctionStorageQueue + audience: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionDefinition(_Model): - function: AzureFunctionDefinitionFunction - input_binding: AzureFunctionBinding - output_binding: AzureFunctionBinding + class azure.ai.projects.models.OpenApiProjectConnectionAuthDetails(OpenApiAuthDetails, discriminator='project_connection'): + security_scheme: OpenApiProjectConnectionSecurityScheme + type: Literal[OpenApiAuthType.PROJECT_CONNECTION] @overload def __init__( self, *, - function: AzureFunctionDefinitionFunction, - input_binding: AzureFunctionBinding, - output_binding: AzureFunctionBinding + security_scheme: OpenApiProjectConnectionSecurityScheme ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionDefinitionFunction(_Model): - description: Optional[str] - name: str - parameters: dict[str, Any] + class azure.ai.projects.models.OpenApiProjectConnectionSecurityScheme(_Model): + project_connection_id: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - parameters: dict[str, Any] + project_connection_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionStorageQueue(_Model): - queue_name: str - queue_service_endpoint: str + class azure.ai.projects.models.OpenApiTool(Tool, discriminator='openapi'): + openapi: OpenApiFunctionDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.OPENAPI] @overload def __init__( self, *, - queue_name: str, - queue_service_endpoint: str + openapi: OpenApiFunctionDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionTool(Tool, discriminator='azure_function'): - azure_function: AzureFunctionDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.AZURE_FUNCTION] + class azure.ai.projects.models.OpenApiToolboxTool(ToolboxTool, discriminator='openapi'): + description: str + name: str + openapi: OpenApiFunctionDefinition + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.OPENAPI] @overload def __init__( self, *, - azure_function: AzureFunctionDefinition, + description: Optional[str] = ..., + name: Optional[str] = ..., + openapi: OpenApiFunctionDefinition, tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @@ -4368,650 +9280,688 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureOpenAIModelConfiguration(RedTeamTargetConfig, discriminator='AzureOpenAIModel'): - model_deployment_name: str - type: Literal["AzureOpenAIModel"] + class azure.ai.projects.models.OperationState(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELED = "Canceled" + FAILED = "Failed" + NOT_STARTED = "NotStarted" + RUNNING = "Running" + SUCCEEDED = "Succeeded" + + + class azure.ai.projects.models.OptimizedAgentIdentifier(_Model): + agent_name: str + agent_version: Optional[str] @overload def __init__( self, *, - model_deployment_name: str + agent_name: str, + agent_version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BaseCredentials(_Model): - type: str + class azure.ai.projects.models.OtlpTelemetryEndpoint(TelemetryEndpoint, discriminator='OTLP'): + auth: TelemetryEndpointAuth + data: Union[list[str, TelemetryDataKind]] + endpoint: str + kind: Literal[TelemetryEndpointKind.OTLP] + protocol: Union[str, TelemetryTransportProtocol] @overload def __init__( self, *, - type: str + auth: Optional[TelemetryEndpointAuth] = ..., + data: list[Union[str, TelemetryDataKind]], + endpoint: str, + protocol: Union[str, TelemetryTransportProtocol] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchConfiguration(_Model): - count: Optional[int] - freshness: Optional[str] - instance_name: str - market: Optional[str] - project_connection_id: str - set_lang: Optional[str] + class azure.ai.projects.models.PSTNTelephonyTransferDestination(TelephonyTransferDestination, discriminator='pstn'): + kind: Literal[TelephonyTransferDestinationKind.PSTN] + value: str @overload def __init__( self, *, - count: Optional[int] = ..., - freshness: Optional[str] = ..., - instance_name: str, - market: Optional[str] = ..., - project_connection_id: str, - set_lang: Optional[str] = ... + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchPreviewTool(Tool, discriminator='bing_custom_search_preview'): - bing_custom_search_preview: BingCustomSearchToolParameters - type: Literal[ToolType.BING_CUSTOM_SEARCH_PREVIEW] + class azure.ai.projects.models.PageOrder(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASC = "asc" + DESC = "desc" + + + class azure.ai.projects.models.PendingUploadRequest(_Model): + connection_name: Optional[str] + pending_upload_id: Optional[str] + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] @overload def __init__( self, *, - bing_custom_search_preview: BingCustomSearchToolParameters + connection_name: Optional[str] = ..., + pending_upload_id: Optional[str] = ..., + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchToolParameters(_Model): - search_configurations: list[BingCustomSearchConfiguration] + class azure.ai.projects.models.PendingUploadResponse(_Model): + blob_reference: BlobReference + pending_upload_id: str + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - search_configurations: list[BingCustomSearchConfiguration] + blob_reference: BlobReference, + pending_upload_id: str, + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE], + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingSearchConfiguration(_Model): - count: Optional[int] - freshness: Optional[str] - market: Optional[str] - project_connection_id: str - set_lang: Optional[str] + class azure.ai.projects.models.PendingUploadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BLOB_REFERENCE = "BlobReference" + NONE = "None" + TEMPORARY_BLOB_REFERENCE = "TemporaryBlobReference" + + + class azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig(_Model): + output: Optional[VoiceAgentAudioOutputConfig] @overload def __init__( self, *, - count: Optional[int] = ..., - freshness: Optional[str] = ..., - market: Optional[str] = ..., - project_connection_id: str, - set_lang: Optional[str] = ... + output: Optional[VoiceAgentAudioOutputConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingSearchToolParameters(_Model): - search_configurations: list[BingGroundingSearchConfiguration] + class azure.ai.projects.models.ProceduralMemoryItem(MemoryItem, discriminator='procedural'): + content: str + kind: Literal[MemoryItemKind.PROCEDURAL] + memory_id: str + scope: str + updated_at: datetime @overload def __init__( self, *, - search_configurations: list[BingGroundingSearchConfiguration] + content: str, + memory_id: str, + scope: str, + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingTool(Tool, discriminator='bing_grounding'): - bing_grounding: BingGroundingSearchToolParameters - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.BING_GROUNDING] + class azure.ai.projects.models.ProgrammaticToolCallingParam(Tool, discriminator='programmatic_tool_calling'): + type: Literal[ToolType.PROGRAMMATIC_TOOL_CALLING] @overload - def __init__( - self, - *, - bing_grounding: BingGroundingSearchToolParameters, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BlobReference(_Model): - blob_uri: str - credential: BlobReferenceSasCredential - storage_account_arm_id: str + class azure.ai.projects.models.PromotionInfo(_Model): + agent_name: str + agent_version: str + promoted_at: datetime @overload def __init__( self, *, - blob_uri: str, - credential: BlobReferenceSasCredential, - storage_account_arm_id: str + agent_name: str, + agent_version: str, + promoted_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BlobReferenceSasCredential(_Model): - sas_uri: str - type: Literal["SAS"] + class azure.ai.projects.models.PromptAgentDefinition(AgentDefinition, discriminator='prompt'): + instructions: Optional[str] + kind: Literal[AgentKind.PROMPT] + model: str + rai_config: RaiConfig + reasoning: Optional[Reasoning] + structured_inputs: Optional[dict[str, StructuredInputDefinition]] + temperature: Optional[float] + text: Optional[PromptAgentDefinitionTextOptions] + tool_choice: Optional[Union[str, ToolChoiceParam]] + tools: Optional[list[Tool]] + top_p: Optional[float] + @overload def __init__( self, - *args: Any, - **kwargs: Any + *, + instructions: Optional[str] = ..., + model: str, + rai_config: Optional[RaiConfig] = ..., + reasoning: Optional[Reasoning] = ..., + structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., + temperature: Optional[float] = ..., + text: Optional[PromptAgentDefinitionTextOptions] = ..., + tool_choice: Optional[Union[str, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_p: Optional[float] = ... ) -> None: ... - - class azure.ai.projects.models.BotServiceAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotService'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE] - - @overload - def __init__(self) -> None: ... - @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BotServiceRbacAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceRbac'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_RBAC] + class azure.ai.projects.models.PromptAgentDefinitionTextOptions(_Model): + format: Optional[TextResponseFormat] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + format: Optional[TextResponseFormat] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BotServiceTenantAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceTenant'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_TENANT] + class azure.ai.projects.models.PromptBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='prompt'): + data_schema: dict[str, any] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + prompt_text: str + type: Literal[EvaluatorDefinitionType.PROMPT] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + data_schema: Optional[dict[str, Any]] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + prompt_text: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationPreviewTool(Tool, discriminator='browser_automation_preview'): - browser_automation_preview: BrowserAutomationToolParameters - type: Literal[ToolType.BROWSER_AUTOMATION_PREVIEW] + class azure.ai.projects.models.PromptDataGenerationJobSource(DataGenerationJobSource, discriminator='prompt'): + description: str + prompt: str + type: Literal[DataGenerationJobSourceType.PROMPT] @overload def __init__( self, *, - browser_automation_preview: BrowserAutomationToolParameters + description: Optional[str] = ..., + prompt: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationPreviewToolboxTool(ToolboxTool, discriminator='browser_automation_preview'): - browser_automation_preview: BrowserAutomationToolParameters - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.BROWSER_AUTOMATION_PREVIEW] + class azure.ai.projects.models.PromptEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='prompt'): + description: Optional[str] + prompt: str + type: Literal[EvaluatorGenerationJobSourceType.PROMPT] @overload def __init__( self, *, - browser_automation_preview: BrowserAutomationToolParameters, description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + prompt: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationToolConnectionParameters(_Model): - project_connection_id: str + class azure.ai.projects.models.ProtocolConfiguration(_Model): + a2a: Optional[A2AProtocolConfiguration] + activity: Optional[ActivityProtocolConfiguration] + invocations: Optional[InvocationsProtocolConfiguration] + invocations_ws: Optional[InvocationsWsProtocolConfiguration] + mcp: Optional[McpProtocolConfiguration] + responses: Optional[ResponsesProtocolConfiguration] @overload def __init__( self, *, - project_connection_id: str + a2a: Optional[A2AProtocolConfiguration] = ..., + activity: Optional[ActivityProtocolConfiguration] = ..., + invocations: Optional[InvocationsProtocolConfiguration] = ..., + invocations_ws: Optional[InvocationsWsProtocolConfiguration] = ..., + mcp: Optional[McpProtocolConfiguration] = ..., + responses: Optional[ResponsesProtocolConfiguration] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationToolParameters(_Model): - connection: BrowserAutomationToolConnectionParameters + class azure.ai.projects.models.ProtocolVersionRecord(_Model): + protocol: Union[str, AgentEndpointProtocol] + version: str @overload def __init__( self, *, - connection: BrowserAutomationToolConnectionParameters + protocol: Union[str, AgentEndpointProtocol], + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CallableToolAllowedCaller(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DIRECT = "direct" - PROGRAMMATIC = "programmatic" + class azure.ai.projects.models.PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + APPROVED = "approved" + NOT_PUBLISHED = "not_published" + NO_APPROVAL_NEEDED = "no_approval_needed" + PENDING = "pending" + REJECTED = "rejected" - class azure.ai.projects.models.CaptureStructuredOutputsTool(Tool, discriminator='capture_structured_outputs'): - description: Optional[str] - name: Optional[str] - outputs: StructuredOutputDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.CAPTURE_STRUCTURED_OUTPUTS] + class azure.ai.projects.models.PublishTelephonyCampaignRequest(_Model): + validation_id: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - outputs: StructuredOutputDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + validation_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ChartCoordinate(_Model): - size: int - x: int - y: int + class azure.ai.projects.models.RaiConfig(_Model): + invocations_moderation: Optional[RaiInvocationModeration] + rai_policy_name: str @overload def __init__( self, *, - size: int, - x: int, - y: int + invocations_moderation: Optional[RaiInvocationModeration] = ..., + rai_policy_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ChatSummaryMemoryItem(MemoryItem, discriminator='chat_summary'): - content: str - kind: Literal[MemoryItemKind.CHAT_SUMMARY] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.RaiInvocationContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + JSON = "json" + TEXT = "text" + + + class azure.ai.projects.models.RaiInvocationMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOTH = "both" + NON_STREAMING = "non_streaming" + STREAMING = "streaming" + + + class azure.ai.projects.models.RaiInvocationModeration(_Model): + input_content_type: Optional[Union[str, RaiInvocationContentType]] + input_paths: Optional[list[str]] + output_content_type: Optional[Union[str, RaiInvocationContentType]] + output_paths: Optional[list[str]] + response_mode: Union[str, RaiInvocationMode] + stream_selectors: Optional[list[RaiSseTextSelector]] @overload def __init__( self, *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + input_content_type: Optional[Union[str, RaiInvocationContentType]] = ..., + input_paths: Optional[list[str]] = ..., + output_content_type: Optional[Union[str, RaiInvocationContentType]] = ..., + output_paths: Optional[list[str]] = ..., + response_mode: Union[str, RaiInvocationMode], + stream_selectors: Optional[list[RaiSseTextSelector]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ClusterInsightResult(_Model): - clusters: list[InsightCluster] - coordinates: Optional[dict[str, ChartCoordinate]] - summary: InsightSummary + class azure.ai.projects.models.RaiSseTextSelector(_Model): + event_type: str + text_field: Optional[str] @overload def __init__( self, *, - clusters: list[InsightCluster], - coordinates: Optional[dict[str, ChartCoordinate]] = ..., - summary: InsightSummary + event_type: str, + text_field: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ClusterTokenUsage(_Model): - input_token_usage: int - output_token_usage: int - total_token_usage: int + class azure.ai.projects.models.RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + DEFAULT_2024_11_15 = "default-2024-11-15" + + + class azure.ai.projects.models.RankingOptions(_Model): + hybrid_search: Optional[HybridSearchOptions] + ranker: Optional[Union[str, RankerVersionType]] + score_threshold: Optional[float] @overload def __init__( self, *, - input_token_usage: int, - output_token_usage: int, - total_token_usage: int + hybrid_search: Optional[HybridSearchOptions] = ..., + ranker: Optional[Union[str, RankerVersionType]] = ..., + score_threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='code'): - blob_uri: Optional[str] - code_text: Optional[str] - data_schema: dict[str, any] - entry_point: Optional[str] - image_tag: Optional[str] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - type: Literal[EvaluatorDefinitionType.CODE] + class azure.ai.projects.models.RealtimeAudioFormats(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcm(RealtimeAudioFormats, discriminator='audio/pcm'): + rate: Optional[Literal[24000]] + type: Literal[RealtimeAudioFormatsType.AUDIO_PCM] @overload def __init__( self, *, - blob_uri: Optional[str] = ..., - code_text: Optional[str] = ..., - data_schema: Optional[dict[str, Any]] = ..., - entry_point: Optional[str] = ..., - image_tag: Optional[str] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ... + rate: Optional[Literal[24000]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeConfiguration(_Model): - content_hash: Optional[str] - dependency_resolution: Union[str, CodeDependencyResolution] - entry_point: list[str] - runtime: str + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcma(RealtimeAudioFormats, discriminator='audio/pcma'): + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMA] @overload - def __init__( - self, - *, - dependency_resolution: Union[str, CodeDependencyResolution], - entry_point: list[str], - runtime: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeDependencyResolution(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BUNDLED = "bundled" - REMOTE_BUILD = "remote_build" + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcmu(RealtimeAudioFormats, discriminator='audio/pcmu'): + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMU] + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeAudioFormatsType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUDIO_PCM = "audio/pcm" + AUDIO_PCMA = "audio/pcma" + AUDIO_PCMU = "audio/pcmu" - class azure.ai.projects.models.CodeInterpreterTool(Tool, discriminator='code_interpreter'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - container: Optional[Union[str, AutoCodeInterpreterToolParam]] - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.CODE_INTERPRETER] + + class azure.ai.projects.models.RealtimeClientEvent(_Model): + type: str @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeInterpreterToolboxTool(ToolboxTool, discriminator='code_interpreter'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - container: Optional[Union[str, AutoCodeInterpreterToolParam]] - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.CODE_INTERPRETER] + class azure.ai.projects.models.RealtimeClientEventConversationItemCreate(RealtimeClientEvent, discriminator='conversation.item.create'): + event_id: Optional[str] + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_CREATE] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + event_id: Optional[str] = ..., + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComparisonFilter(_Model): - key: str - type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"] - value: Union[str, float, bool, list[Union[str, float]]] + class azure.ai.projects.models.RealtimeClientEventConversationItemDelete(RealtimeClientEvent, discriminator='conversation.item.delete'): + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_DELETE] @overload def __init__( self, *, - key: str, - type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"], - value: Union[str, float, bool, list[Union[str, float]]] + event_id: Optional[str] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CompoundFilter(_Model): - filters: list[Union[ComparisonFilter, Any]] - type: Literal["and", "or"] + class azure.ai.projects.models.RealtimeClientEventConversationItemRetrieve(RealtimeClientEvent, discriminator='conversation.item.retrieve'): + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE] @overload def __init__( self, *, - filters: list[Union[ComparisonFilter, Any]], - type: Literal["and", "or"] + event_id: Optional[str] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComputerEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BROWSER = "browser" - LINUX = "linux" - MAC = "mac" - UBUNTU = "ubuntu" - WINDOWS = "windows" - - - class azure.ai.projects.models.ComputerTool(Tool, discriminator='computer'): - type: Literal[ToolType.COMPUTER] + class azure.ai.projects.models.RealtimeClientEventConversationItemTruncate(RealtimeClientEvent, discriminator='conversation.item.truncate'): + audio_end_ms: int + content_index: int + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_end_ms: int, + content_index: int, + event_id: Optional[str] = ..., + item_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComputerUsePreviewTool(Tool, discriminator='computer_use_preview'): - display_height: int - display_width: int - environment: Union[str, ComputerEnvironment] - type: Literal[ToolType.COMPUTER_USE_PREVIEW] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferAppend(RealtimeClientEvent, discriminator='input_audio_buffer.append'): + audio: str + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND] @overload def __init__( self, *, - display_height: int, - display_width: int, - environment: Union[str, ComputerEnvironment] + audio: str, + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Connection(_Model): - credentials: BaseCredentials - id: str - is_default: bool - metadata: dict[str, str] - name: str - target: str - type: Union[str, ConnectionType] - - - class azure.ai.projects.models.ConnectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - API_KEY = "ApiKey" - APPLICATION_CONFIGURATION = "AppConfig" - APPLICATION_INSIGHTS = "AppInsights" - AZURE_AI_SEARCH = "CognitiveSearch" - AZURE_BLOB_STORAGE = "AzureBlob" - AZURE_OPEN_AI = "AzureOpenAI" - AZURE_STORAGE_ACCOUNT = "AzureStorageAccount" - COSMOS_DB = "CosmosDB" - CUSTOM = "CustomKeys" - REMOTE_TOOL = "RemoteTool_Preview" - - - class azure.ai.projects.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] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferClear(RealtimeClientEvent, discriminator='input_audio_buffer.clear'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ContainerNetworkPolicyParam] = ..., - skills: Optional[list[ContainerSkill]] = ... + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerConfiguration(_Model): - image: str - registry_connection_id: Optional[str] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferCommit(RealtimeClientEvent, discriminator='input_audio_buffer.commit'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT] @overload def __init__( self, *, - image: str, - registry_connection_id: Optional[str] = ... + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerMemoryLimit(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MEMORY_16GB = "16g" - MEMORY_1GB = "1g" - MEMORY_4GB = "4g" - MEMORY_64GB = "64g" - - - class azure.ai.projects.models.ContainerNetworkPolicyAllowlistParam(ContainerNetworkPolicyParam, discriminator='allowlist'): - allowed_domains: list[str] - domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] - type: Literal[ContainerNetworkPolicyParamType.ALLOWLIST] + class azure.ai.projects.models.RealtimeClientEventOutputAudioBufferClear(RealtimeClientEvent, discriminator='output_audio_buffer.clear'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR] @overload def __init__( self, *, - allowed_domains: list[str], - domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] = ... + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyDisabledParam(ContainerNetworkPolicyParam, discriminator='disabled'): - type: Literal[ContainerNetworkPolicyParamType.DISABLED] + class azure.ai.projects.models.RealtimeClientEventResponseCancel(RealtimeClientEvent, discriminator='response.cancel'): + event_id: Optional[str] + response_id: Optional[str] + type: Literal[RealtimeClientEventType.RESPONSE_CANCEL] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: Optional[str] = ..., + response_id: Optional[str] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyDomainSecretParam(_Model): - domain: str - name: str - value: str + class azure.ai.projects.models.RealtimeClientEventResponseCreate(RealtimeClientEvent, discriminator='response.create'): + event_id: Optional[str] + response: Optional[VoiceAgentResponseCreateParams] + type: Literal[RealtimeClientEventType.RESPONSE_CREATE] @overload def __init__( self, *, - domain: str, - name: str, - value: str + event_id: Optional[str] = ..., + response: Optional[VoiceAgentResponseCreateParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyParam(_Model): + class azure.ai.projects.models.RealtimeClientEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION_ITEM_CREATE = "conversation.item.create" + CONVERSATION_ITEM_DELETE = "conversation.item.delete" + CONVERSATION_ITEM_RETRIEVE = "conversation.item.retrieve" + CONVERSATION_ITEM_TRUNCATE = "conversation.item.truncate" + INPUT_AUDIO_BUFFER_APPEND = "input_audio_buffer.append" + INPUT_AUDIO_BUFFER_CLEAR = "input_audio_buffer.clear" + INPUT_AUDIO_BUFFER_COMMIT = "input_audio_buffer.commit" + OUTPUT_AUDIO_BUFFER_CLEAR = "output_audio_buffer.clear" + RESPONSE_CANCEL = "response.cancel" + RESPONSE_CREATE = "response.create" + RTC_CALL_SDP_CREATE = "rtc.call.sdp.create" + SESSION_AVATAR_CONNECT = "session.avatar.connect" + SESSION_UPDATE = "session.update" + + + class azure.ai.projects.models.RealtimeConversationItem(_Model): type: str @overload @@ -5025,1425 +9975,1747 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ALLOWLIST = "allowlist" - DISABLED = "disabled" - - - class azure.ai.projects.models.ContainerSkill(_Model): - type: str + class azure.ai.projects.models.RealtimeConversationItemFunctionCall(RealtimeConversationItem, discriminator='function_call'): + arguments: str + call_id: Optional[str] + created_at: Optional[datetime] + id: Optional[str] + name: str + object: Optional[Literal["item"]] + response_id: Optional[str] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Literal[RealtimeConversationItemType.FUNCTION_CALL] @overload def __init__( self, *, - type: str + arguments: str, + call_id: Optional[str] = ..., + id: Optional[str] = ..., + name: str, + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INLINE = "inline" - SKILL_REFERENCE = "skill_reference" - - - class azure.ai.projects.models.ContinuousEvaluationRuleAction(EvaluationRuleAction, discriminator='continuousEvaluation'): - eval_id: str - max_hourly_runs: Optional[int] - sampling_rate: Optional[float] - type: Literal[EvaluationRuleActionType.CONTINUOUS_EVALUATION] + class azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput(RealtimeConversationItem, discriminator='function_call_output'): + call_id: str + created_at: Optional[datetime] + id: Optional[str] + name: Optional[str] + object: Optional[Literal["item"]] + output: str + response_id: Optional[str] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Literal[RealtimeConversationItemType.FUNCTION_CALL_OUTPUT] @overload def __init__( self, *, - eval_id: str, - max_hourly_runs: Optional[int] = ..., - sampling_rate: Optional[float] = ... + call_id: str, + id: Optional[str] = ..., + name: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + output: str, + status: Optional[Literal[completed, incomplete, in_progress]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CosmosDBIndex(Index, discriminator='CosmosDBNoSqlVectorStore'): - connection_name: str - container_name: str - database_name: str - description: str - embedding_configuration: EmbeddingConfiguration - field_mapping: FieldMapping - id: str - name: str - tags: dict[str, str] - type: Literal[IndexType.COSMOS_DB] - version: str + class azure.ai.projects.models.RealtimeConversationItemMessage(RealtimeConversationItem, discriminator='message'): + role: str + type: Literal[RealtimeConversationItemType.MESSAGE] @overload def __init__( self, *, - connection_name: str, - container_name: str, - database_name: str, - description: Optional[str] = ..., - embedding_configuration: EmbeddingConfiguration, - field_mapping: FieldMapping, - tags: Optional[dict[str, str]] = ... + role: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CreateAsyncResponse(_Model): - location: Optional[str] - operation_result: Optional[str] + class azure.ai.projects.models.RealtimeConversationItemMessageAssistant(RealtimeConversationItemMessage, discriminator='assistant'): + content: list[RealtimeConversationItemMessageAssistantContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.ASSISTANT] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] @overload def __init__( self, *, - location: Optional[str] = ..., - operation_result: Optional[str] = ... + content: list[RealtimeConversationItemMessageAssistantContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CreateSkillVersionFromFilesBody(_Model): - default: Optional[bool] - files: list[Union[str, bytes, IO[str], IO[bytes], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]]], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]], Optional[str]]]] + class azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent(_Model): + audio: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["output_text", "output_audio"]] @overload def __init__( self, *, - default: Optional[bool] = ..., - files: list[FileType] + audio: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[output_text, output_audio]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENTIC_IDENTITY_PREVIEW = "AgenticIdentityToken_Preview" - API_KEY = "ApiKey" - CUSTOM = "CustomKeys" - ENTRA_ID = "AAD" - NONE = "None" - SAS = "SAS" + class azure.ai.projects.models.RealtimeConversationItemMessageSystem(RealtimeConversationItemMessage, discriminator='system'): + content: list[RealtimeConversationItemMessageSystemContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.SYSTEM] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] + + @overload + def __init__( + self, + *, + content: list[RealtimeConversationItemMessageSystemContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] + ) -> None: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CronTrigger(Trigger, discriminator='Cron'): - end_time: Optional[datetime] - expression: str - start_time: Optional[datetime] - time_zone: Optional[str] - type: Literal[TriggerType.CRON] + + class azure.ai.projects.models.RealtimeConversationItemMessageSystemContent(_Model): + text: Optional[str] + type: Optional[Literal["input_text"]] @overload def __init__( self, *, - end_time: Optional[datetime] = ..., - expression: str, - start_time: Optional[datetime] = ..., - time_zone: Optional[str] = ... + text: Optional[str] = ..., + type: Optional[Literal[input_text]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomCredential(CustomCredentialGenerated, discriminator='CustomKeys'): - credential_keys: Dict[str, str] - type: Union[str, CredentialType] - - def __init__( - self, - *args: Any, - **kwargs: Any - ) -> None: ... + class azure.ai.projects.models.RealtimeConversationItemMessageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASSISTANT = "assistant" + SYSTEM = "system" + USER = "user" - class azure.ai.projects.models.CustomGrammarFormatParam(CustomToolParamFormat, discriminator='grammar'): - definition: str - syntax: Union[str, GrammarSyntax1] - type: Literal[CustomToolParamFormatType.GRAMMAR] + class azure.ai.projects.models.RealtimeConversationItemMessageUser(RealtimeConversationItemMessage, discriminator='user'): + content: list[RealtimeConversationItemMessageUserContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.USER] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] @overload def __init__( self, *, - definition: str, - syntax: Union[str, GrammarSyntax1] + content: list[RealtimeConversationItemMessageUserContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomRoutineTrigger(RoutineTrigger, discriminator='custom'): - event_name: Optional[str] - parameters: dict[str, Any] - provider: str - type: Literal[RoutineTriggerType.CUSTOM] + class azure.ai.projects.models.RealtimeConversationItemMessageUserContent(_Model): + audio: Optional[str] + detail: Optional[Literal["auto", "low", "high"]] + image_url: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["input_text", "input_audio", "input_image"]] @overload def __init__( self, *, - event_name: Optional[str] = ..., - parameters: dict[str, Any], - provider: str + audio: Optional[str] = ..., + detail: Optional[Literal[auto, low, high]] = ..., + image_url: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[input_text, input_audio, input_image]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomTextFormatParam(CustomToolParamFormat, discriminator='text'): - type: Literal[CustomToolParamFormatType.TEXT] + class azure.ai.projects.models.RealtimeConversationItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FUNCTION_CALL = "function_call" + FUNCTION_CALL_OUTPUT = "function_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" + + + class azure.ai.projects.models.RealtimeFunctionTool(_Model): + description: Optional[str] + name: Optional[str] + parameters: Optional[RealtimeFunctionToolParameters] + type: Optional[Literal["function"]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + parameters: Optional[RealtimeFunctionToolParameters] = ..., + type: Optional[Literal[function]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParam(Tool, discriminator='custom'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] - description: Optional[str] - format: Optional[CustomToolParamFormat] + class azure.ai.projects.models.RealtimeFunctionToolParameters(_Model): + + + class azure.ai.projects.models.RealtimeMCPApprovalRequest(RealtimeConversationItem, discriminator='mcp_approval_request'): + arguments: str + created_at: Optional[datetime] + id: str name: str - type: Literal[ToolType.CUSTOM] + response_id: Optional[str] + server_label: str + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_REQUEST] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - format: Optional[CustomToolParamFormat] = ..., - name: str + arguments: str, + id: str, + name: str, + server_label: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParamFormat(_Model): - type: str + class azure.ai.projects.models.RealtimeMCPApprovalResponse(RealtimeConversationItem, discriminator='mcp_approval_response'): + approval_request_id: str + approve: bool + created_at: Optional[datetime] + id: str + reason: Optional[str] + response_id: Optional[str] + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_RESPONSE] @overload def __init__( self, *, - type: str + approval_request_id: str, + approve: bool, + id: str, + reason: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParamFormatType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GRAMMAR = "grammar" - TEXT = "text" - - - class azure.ai.projects.models.DailyRecurrenceSchedule(RecurrenceSchedule, discriminator='Daily'): - hours: list[int] - type: Literal[RecurrenceType.DAILY] + class azure.ai.projects.models.RealtimeMCPError(_Model): + type: str @overload def __init__( self, *, - hours: list[int] + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJob(_Model): - created_at: datetime - error: Optional[ApiError] - finished_at: Optional[datetime] - id: str - inputs: Optional[DataGenerationJobInputs] - result: Optional[DataGenerationJobResult] - status: Union[str, JobStatus] + class azure.ai.projects.models.RealtimeMCPHTTPError(RealtimeMCPError, discriminator='http_error'): + code: int + message: str + type: Literal[RealtimeMcpErrorType.HTTP_ERROR] @overload def __init__( self, *, - inputs: Optional[DataGenerationJobInputs] = ... + code: int, + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobInputs(_Model): - name: str - options: DataGenerationJobOptions - output_options: Optional[DataGenerationJobOutputOptions] - scenario: Union[str, DataGenerationJobScenario] - sources: list[DataGenerationJobSource] + class azure.ai.projects.models.RealtimeMCPListTools(RealtimeConversationItem, discriminator='mcp_list_tools'): + created_at: Optional[datetime] + id: Optional[str] + response_id: Optional[str] + server_label: str + tools: list[MCPListToolsTool] + type: Literal[RealtimeConversationItemType.MCP_LIST_TOOLS] @overload def __init__( self, *, - name: str, - options: DataGenerationJobOptions, - output_options: Optional[DataGenerationJobOutputOptions] = ..., - scenario: Union[str, DataGenerationJobScenario], - sources: list[DataGenerationJobSource] + id: Optional[str] = ..., + server_label: str, + tools: list[MCPListToolsTool] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOptions(_Model): - max_samples: int - model_options: Optional[DataGenerationModelOptions] - train_split: Optional[float] - type: str + class azure.ai.projects.models.RealtimeMCPProtocolError(RealtimeMCPError, discriminator='protocol_error'): + code: int + message: str + type: Literal[RealtimeMcpErrorType.PROTOCOL_ERROR] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ..., - type: str + code: int, + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutput(_Model): - type: str + class azure.ai.projects.models.RealtimeMCPToolCall(RealtimeConversationItem, discriminator='mcp_call'): + approval_request_id: Optional[str] + arguments: str + created_at: Optional[datetime] + error: Optional[RealtimeMCPError] + id: str + name: str + output: Optional[str] + response_id: Optional[str] + server_label: str + type: Literal[RealtimeConversationItemType.MCP_CALL] @overload def __init__( self, *, - type: str + approval_request_id: Optional[str] = ..., + arguments: str, + error: Optional[RealtimeMCPError] = ..., + id: str, + name: str, + output: Optional[str] = ..., + server_label: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutputOptions(_Model): - description: Optional[str] - name: Optional[str] - tags: Optional[dict[str, str]] + class azure.ai.projects.models.RealtimeMCPToolExecutionError(RealtimeMCPError, discriminator='tool_execution_error'): + message: str + type: Literal[RealtimeMcpErrorType.TOOL_EXECUTION_ERROR] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DATASET = "dataset" - FILE = "file" + class azure.ai.projects.models.RealtimeMcpErrorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HTTP_ERROR = "http_error" + PROTOCOL_ERROR = "protocol_error" + TOOL_EXECUTION_ERROR = "tool_execution_error" - class azure.ai.projects.models.DataGenerationJobResult(_Model): - generated_samples: int - outputs: Optional[list[DataGenerationJobOutput]] - token_usage: Optional[DataGenerationTokenUsage] + class azure.ai.projects.models.RealtimeReasoning(_Model): + effort: Optional[Union[str, RealtimeReasoningEffort]] @overload def __init__( self, *, - generated_samples: int, - outputs: Optional[list[DataGenerationJobOutput]] = ..., - token_usage: Optional[DataGenerationTokenUsage] = ... + effort: Optional[Union[str, RealtimeReasoningEffort]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobScenario(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION = "evaluation" - REINFORCEMENT_FINETUNING = "reinforcement_finetuning" - SUPERVISED_FINETUNING = "supervised_finetuning" + class azure.ai.projects.models.RealtimeReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + MINIMAL = "minimal" + XHIGH = "xhigh" - class azure.ai.projects.models.DataGenerationJobSource(_Model): - description: Optional[str] - type: str + class azure.ai.projects.models.RealtimeResponseStatusDetails(_Model): + error: Optional[RealtimeResponseStatusDetailsError] + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] @overload def __init__( self, *, - description: Optional[str] = ..., - type: str + error: Optional[RealtimeResponseStatusDetailsError] = ..., + reason: Optional[Literal[turn_detected, client_cancelled, max_output_tokens, content_filter]] = ..., + type: Optional[Literal[completed, cancelled, failed, incomplete]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - FILE = "file" - PROMPT = "prompt" - TRACES = "traces" + class azure.ai.projects.models.RealtimeResponseStatusDetailsError(_Model): + code: Optional[str] + type: Optional[str] + @overload + def __init__( + self, + *, + code: Optional[str] = ..., + type: Optional[str] = ... + ) -> None: ... - class azure.ai.projects.models.DataGenerationJobType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - SIMPLE_QNA = "simple_qna" - SIMULATION_SEED = "simulation_seed" - TOOL_USE = "tool_use" - TRACES = "traces" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationModelOptions(_Model): - model: str + class azure.ai.projects.models.RealtimeResponseUsage(_Model): + input_token_details: Optional[RealtimeResponseUsageInputTokenDetails] + input_tokens: Optional[int] + output_token_details: Optional[RealtimeResponseUsageOutputTokenDetails] + output_tokens: Optional[int] + total_tokens: Optional[int] @overload def __init__( self, *, - model: str + input_token_details: Optional[RealtimeResponseUsageInputTokenDetails] = ..., + input_tokens: Optional[int] = ..., + output_token_details: Optional[RealtimeResponseUsageOutputTokenDetails] = ..., + output_tokens: Optional[int] = ..., + total_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationTokenUsage(_Model): - completion_tokens: int - prompt_tokens: int - total_tokens: int - - - class azure.ai.projects.models.DatasetCredential(_Model): - blob_reference: BlobReference + class azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails(_Model): + audio_tokens: Optional[int] + cached_tokens: Optional[int] + cached_tokens_details: Optional[RealtimeResponseUsageInputTokenDetailsCachedTokensDetails] + image_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - blob_reference: BlobReference + audio_tokens: Optional[int] = ..., + cached_tokens: Optional[int] = ..., + cached_tokens_details: Optional[RealtimeResponseUsageInputTokenDetailsCachedTokensDetails] = ..., + image_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetDataGenerationJobOutput(DataGenerationJobOutput, discriminator='dataset'): - description: Optional[str] - id: Optional[str] - name: Optional[str] - tags: Optional[dict[str, str]] - type: Literal[DataGenerationJobOutputType.DATASET] - version: Optional[str] + class azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails(_Model): + audio_tokens: Optional[int] + image_tokens: Optional[int] + text_tokens: Optional[int] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_tokens: Optional[int] = ..., + image_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='dataset'): - description: Optional[str] - name: str - type: Literal[EvaluatorGenerationJobSourceType.DATASET] - version: Optional[str] + class azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails(_Model): + audio_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - version: Optional[str] = ... + audio_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetGenerationLROPoller(LROPoller[DataGenerationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.RealtimeServerEvent(_Model): + type: str + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + type: str ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[DataGenerationJobResult], - continuation_token: str, - **kwargs: Any - ) -> DatasetGenerationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetReference(_Model): - name: str - version: str + class azure.ai.projects.models.RealtimeServerEventConversationItemAdded(RealtimeServerEvent, discriminator='conversation.item.added'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_ADDED] @overload def __init__( self, *, - name: str, - version: str + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - URI_FILE = "uri_file" - URI_FOLDER = "uri_folder" + class azure.ai.projects.models.RealtimeServerEventConversationItemCreated(RealtimeServerEvent, discriminator='conversation.item.created'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_CREATED] + @overload + def __init__( + self, + *, + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... + ) -> None: ... - class azure.ai.projects.models.DatasetVersion(_Model): - connection_name: Optional[str] - data_uri: str - description: Optional[str] - id: Optional[str] - is_reference: Optional[bool] - name: str - tags: Optional[dict[str, str]] - type: str - version: str + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeServerEventConversationItemDeleted(RealtimeServerEvent, discriminator='conversation.item.deleted'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DELETED] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ..., - type: str + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DayOfWeek(str, Enum, metaclass=CaseInsensitiveEnumMeta): - FRIDAY = "Friday" - MONDAY = "Monday" - SATURDAY = "Saturday" - SUNDAY = "Sunday" - THURSDAY = "Thursday" - TUESDAY = "Tuesday" - WEDNESDAY = "Wednesday" - - - class azure.ai.projects.models.DeleteAgentResponse(_Model): - deleted: bool - name: str - object: Literal[AgentObjectType.AGENT_DELETED] + class azure.ai.projects.models.RealtimeServerEventConversationItemDone(RealtimeServerEvent, discriminator='conversation.item.done'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DONE] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[AgentObjectType.AGENT_DELETED] + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteAgentVersionResponse(_Model): - deleted: bool - name: str - object: Literal[AgentObjectType.AGENT_VERSION_DELETED] - version: str + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.completed'): + content_index: int + event_id: str + item_id: str + languages: Optional[list[TranscriptionLanguage]] + logprobs: Optional[list[LogProbProperties]] + phrases: Optional[list[VoiceAgentTranscriptionPhrase]] + transcript: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED] + usage: Union[TranscriptTextUsageTokens, TranscriptTextUsageDuration] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[AgentObjectType.AGENT_VERSION_DELETED], - version: str + content_index: int, + event_id: str, + item_id: str, + languages: Optional[list[TranscriptionLanguage]] = ..., + logprobs: Optional[list[LogProbProperties]] = ..., + phrases: Optional[list[VoiceAgentTranscriptionPhrase]] = ..., + transcript: str, + usage: Union[TranscriptTextUsageTokens, TranscriptTextUsageDuration] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteMemoryResult(_Model): - deleted: bool - memory_id: str - object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.delta'): + content_index: Optional[int] + delta: Optional[str] + event_id: str + item_id: str + logprobs: Optional[list[LogProbProperties]] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA] @overload def __init__( self, *, - deleted: bool, - memory_id: str, - object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + content_index: Optional[int] = ..., + delta: Optional[str] = ..., + event_id: str, + item_id: str, + logprobs: Optional[list[LogProbProperties]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteMemoryStoreResult(_Model): - deleted: bool - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.failed'): + content_index: int + error: RealtimeServerEventConversationItemInputAudioTranscriptionFailedError + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + content_index: int, + error: RealtimeServerEventConversationItemInputAudioTranscriptionFailedError, + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteSkillResult(_Model): - deleted: bool - id: str - name: str + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError(_Model): + code: Optional[str] + message: Optional[str] + param: Optional[str] + type: Optional[str] @overload def __init__( self, *, - deleted: bool, - id: str, - name: str + code: Optional[str] = ..., + message: Optional[str] = ..., + param: Optional[str] = ..., + type: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteSkillVersionResult(_Model): - deleted: bool + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.segment'): + content_index: int + end: float + event_id: str id: str - name: str - version: str + item_id: str + speaker: str + start: float + text: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT] @overload def __init__( self, *, - deleted: bool, + content_index: int, + end: float, + event_id: str, id: str, - name: str, - version: str + item_id: str, + speaker: str, + start: float, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Deployment(_Model): - name: str - type: str + class azure.ai.projects.models.RealtimeServerEventConversationItemRetrieved(RealtimeServerEvent, discriminator='conversation.item.retrieved'): + event_id: str + item: RealtimeConversationItem + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED] @overload def __init__( self, *, - type: str + event_id: str, + item: RealtimeConversationItem ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeploymentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MODEL_DEPLOYMENT = "ModelDeployment" + class azure.ai.projects.models.RealtimeServerEventConversationItemTruncated(RealtimeServerEvent, discriminator='conversation.item.truncated'): + audio_end_ms: int + content_index: int + event_id: str + item: Optional[RealtimeConversationItem] + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED] + @overload + def __init__( + self, + *, + audio_end_ms: int, + content_index: int, + event_id: str, + item: Optional[RealtimeConversationItem] = ..., + item_id: str + ) -> None: ... - class azure.ai.projects.models.DigitalWorkerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - M365 = "m365" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Dimension(_Model): - always_applicable: Optional[bool] - description: str - id: str - weight: int + class azure.ai.projects.models.RealtimeServerEventError(_Model): + error: RealtimeServerEventErrorError + event_id: str + type: Literal["error"] @overload def __init__( self, *, - always_applicable: Optional[bool] = ..., - description: str, - id: str, - weight: int + error: RealtimeServerEventErrorError, + event_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DispatchRoutineResult(_Model): - action_correlation_id: Optional[str] - dispatch_id: Optional[str] - task_id: Optional[str] + class azure.ai.projects.models.RealtimeServerEventErrorError(_Model): + code: Optional[str] + event_id: Optional[str] + message: str + param: Optional[str] + type: str @overload def __init__( self, *, - action_correlation_id: Optional[str] = ..., - dispatch_id: Optional[str] = ..., - task_id: Optional[str] = ... + code: Optional[str] = ..., + event_id: Optional[str] = ..., + message: str, + param: Optional[str] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EmbeddingConfiguration(_Model): - embedding_field: str - model_deployment_name: str + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferCleared(RealtimeServerEvent, discriminator='input_audio_buffer.cleared'): + event_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED] @overload def __init__( self, *, - embedding_field: str, - model_deployment_name: str + event_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EmptyModelParam(_Model): - - - class azure.ai.projects.models.EndpointBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='endpoint'): - connection_name: str - data_schema: dict[str, any] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - type: Literal[EvaluatorDefinitionType.ENDPOINT] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferCommitted(RealtimeServerEvent, discriminator='input_audio_buffer.committed'): + event_id: str + item_id: str + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED] @overload def __init__( self, *, - connection_name: str, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ... + event_id: str, + item_id: str, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EntraAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='Entra'): - type: Literal[AgentEndpointAuthorizationSchemeType.ENTRA] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStarted(RealtimeServerEvent, discriminator='input_audio_buffer.speech_started'): + audio_start_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_start_ms: int, + event_id: str, + item_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EntraIDCredentials(BaseCredentials, discriminator='AAD'): - type: Literal[CredentialType.ENTRA_ID] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStopped(RealtimeServerEvent, discriminator='input_audio_buffer.speech_stopped'): + audio_end_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_end_ms: int, + event_id: str, + item_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalCsvFileIdSource(TypedDict, total=False): - key "id": Required[str] - key "type": Required[Literal["file_id"]] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferTimeoutTriggered(RealtimeServerEvent, discriminator='input_audio_buffer.timeout_triggered'): + audio_end_ms: int + audio_start_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED] + @overload + def __init__( + self, + *, + audio_end_ms: int, + audio_start_ms: int, + event_id: str, + item_id: str + ) -> None: ... - class azure.ai.projects.models.EvalCsvRunDataSource(TypedDict, total=False): - key "source": Required[EvalCsvFileIdSource] - key "type": Required[Literal["csv"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalResult(_Model): - name: str - passed: bool - score: float - type: str + class azure.ai.projects.models.RealtimeServerEventMCPListToolsCompleted(RealtimeServerEvent, discriminator='mcp_list_tools.completed'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED] @overload def __init__( self, *, - name: str, - passed: bool, - score: float, - type: str + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultCompareItem(_Model): - delta_estimate: float - p_value: float - treatment_effect: Union[str, TreatmentEffectType] - treatment_run_id: str - treatment_run_summary: EvalRunResultSummary + class azure.ai.projects.models.RealtimeServerEventMCPListToolsFailed(RealtimeServerEvent, discriminator='mcp_list_tools.failed'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_FAILED] @overload def __init__( self, *, - delta_estimate: float, - p_value: float, - treatment_effect: Union[str, TreatmentEffectType], - treatment_run_id: str, - treatment_run_summary: EvalRunResultSummary + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultComparison(_Model): - baseline_run_summary: EvalRunResultSummary - compare_items: list[EvalRunResultCompareItem] - evaluator: str - metric: str - testing_criteria: str + class azure.ai.projects.models.RealtimeServerEventMCPListToolsInProgress(RealtimeServerEvent, discriminator='mcp_list_tools.in_progress'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS] @overload def __init__( self, *, - baseline_run_summary: EvalRunResultSummary, - compare_items: list[EvalRunResultCompareItem], - evaluator: str, - metric: str, - testing_criteria: str + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultSummary(_Model): - average: float - run_id: str - sample_count: int - standard_deviation: float + class azure.ai.projects.models.RealtimeServerEventOutputAudioBufferCleared(RealtimeServerEvent, discriminator='output_audio_buffer.cleared'): + event_id: str + response_id: str + type: Literal[RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED] @overload def __init__( self, *, - average: float, - run_id: str, - sample_count: int, - standard_deviation: float + event_id: str, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationComparisonInsightRequest(InsightRequest, discriminator='EvaluationComparison'): - baseline_run_id: str - eval_id: str - treatment_run_ids: list[str] - type: Literal[InsightType.EVALUATION_COMPARISON] + class azure.ai.projects.models.RealtimeServerEventRateLimitsUpdated(RealtimeServerEvent, discriminator='rate_limits.updated'): + event_id: str + rate_limits: list[RealtimeServerEventRateLimitsUpdatedRateLimits] + type: Literal[RealtimeServerEventType.RATE_LIMITS_UPDATED] @overload def __init__( self, *, - baseline_run_id: str, - eval_id: str, - treatment_run_ids: list[str] + event_id: str, + rate_limits: list[RealtimeServerEventRateLimitsUpdatedRateLimits] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationComparisonInsightResult(InsightResult, discriminator='EvaluationComparison'): - comparisons: list[EvalRunResultComparison] - method: str - type: Literal[InsightType.EVALUATION_COMPARISON] + class azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits(_Model): + limit: Optional[int] + name: Optional[Literal["requests", "tokens"]] + remaining: Optional[int] + reset_seconds: Optional[float] @overload def __init__( self, *, - comparisons: list[EvalRunResultComparison], - method: str + limit: Optional[int] = ..., + name: Optional[Literal[requests, tokens]] = ..., + remaining: Optional[int] = ..., + reset_seconds: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONVERSATION = "conversation" - TURN = "turn" + class azure.ai.projects.models.RealtimeServerEventResponseAudioDelta(RealtimeServerEvent, discriminator='response.output_audio.delta'): + content_index: int + delta: bytes + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA] + @overload + def __init__( + self, + *, + content_index: int, + delta: bytes, + event_id: str, + item_id: str, + output_index: int, + response_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationResultSample(InsightSample, discriminator='EvaluationResultSample'): - correlation_info: dict[str, any] - evaluation_result: EvalResult - features: dict[str, any] - id: str - type: Literal[SampleType.EVALUATION_RESULT_SAMPLE] + + class azure.ai.projects.models.RealtimeServerEventResponseAudioDone(RealtimeServerEvent, discriminator='response.output_audio.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE] @overload def __init__( self, *, - correlation_info: dict[str, Any], - evaluation_result: EvalResult, - features: dict[str, Any], - id: str + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRule(_Model): - action: EvaluationRuleAction - description: Optional[str] - display_name: Optional[str] - enabled: bool - event_type: Union[str, EvaluationRuleEventType] - filter: Optional[EvaluationRuleFilter] - id: str - system_data: dict[str, str] + class azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDelta(RealtimeServerEvent, discriminator='response.output_audio_transcript.delta'): + content_index: int + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA] @overload def __init__( self, *, - action: EvaluationRuleAction, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - enabled: bool, - event_type: Union[str, EvaluationRuleEventType], - filter: Optional[EvaluationRuleFilter] = ... + content_index: int, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRuleAction(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDone(RealtimeServerEvent, discriminator='response.output_audio_transcript.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + transcript: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE] @overload def __init__( self, *, - type: str + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + transcript: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRuleActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTINUOUS_EVALUATION = "continuousEvaluation" - HUMAN_EVALUATION_PREVIEW = "humanEvaluationPreview" + class azure.ai.projects.models.RealtimeServerEventResponseContentPartAdded(RealtimeServerEvent, discriminator='response.content_part.added'): + content_index: int + event_id: str + item_id: str + output_index: int + part: RealtimeServerEventResponseContentPartAddedPart + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED] + @overload + def __init__( + self, + *, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + part: RealtimeServerEventResponseContentPartAddedPart, + response_id: str + ) -> None: ... - class azure.ai.projects.models.EvaluationRuleEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MANUAL = "manual" - RESPONSE_COMPLETED = "responseCompleted" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRuleFilter(_Model): - agent_name: str + class azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart(_Model): + audio: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["audio", "text"]] @overload def __init__( self, *, - agent_name: str + audio: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[audio, text]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRunClusterInsightRequest(InsightRequest, discriminator='EvaluationRunClusterInsight'): - eval_id: str - model_configuration: Optional[InsightModelConfiguration] - run_ids: list[str] - type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + class azure.ai.projects.models.RealtimeServerEventResponseContentPartDone(RealtimeServerEvent, discriminator='response.content_part.done'): + content_index: int + event_id: str + item_id: str + output_index: int + part: RealtimeServerEventResponseContentPartDonePart + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE] @overload def __init__( self, *, - eval_id: str, - model_configuration: Optional[InsightModelConfiguration] = ..., - run_ids: list[str] + content_index: int, + event_id: str, + item_id: str, + output_index: int, + part: RealtimeServerEventResponseContentPartDonePart, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRunClusterInsightResult(InsightResult, discriminator='EvaluationRunClusterInsight'): - cluster_insight: ClusterInsightResult - type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + class azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart(_Model): + audio: Optional[str] + format: Optional[RealtimeAudioFormats] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["audio", "text"]] @overload def __init__( self, *, - cluster_insight: ClusterInsightResult + audio: Optional[str] = ..., + format: Optional[RealtimeAudioFormats] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[audio, text]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationScheduleTask(ScheduleTask, discriminator='Evaluation'): - configuration: dict[str, str] - eval_id: str - eval_run: dict[str, Any] - type: Literal[ScheduleTaskType.EVALUATION] + class azure.ai.projects.models.RealtimeServerEventResponseCreated(RealtimeServerEvent, discriminator='response.created'): + event_id: str + response: VoiceAgentRealtimeResponse + type: Literal[RealtimeServerEventType.RESPONSE_CREATED] @overload def __init__( self, *, - configuration: Optional[dict[str, str]] = ..., - eval_id: str, - eval_run: dict[str, Any] + event_id: str, + response: VoiceAgentRealtimeResponse ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTarget(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventResponseDone(RealtimeServerEvent, discriminator='response.done'): + event_id: str + response: VoiceAgentRealtimeResponse + type: Literal[RealtimeServerEventType.RESPONSE_DONE] @overload def __init__( self, *, - type: str + event_id: str, + response: VoiceAgentRealtimeResponse ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomy(_Model): - description: Optional[str] - id: Optional[str] - name: str - properties: Optional[dict[str, str]] - tags: Optional[dict[str, str]] - taxonomy_categories: Optional[list[TaxonomyCategory]] - taxonomy_input: EvaluationTaxonomyInput - version: str + class azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDelta(RealtimeServerEvent, discriminator='response.function_call_arguments.delta'): + call_id: str + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA] @overload def __init__( self, *, - description: Optional[str] = ..., - properties: Optional[dict[str, str]] = ..., - tags: Optional[dict[str, str]] = ..., - taxonomy_categories: Optional[list[TaxonomyCategory]] = ..., - taxonomy_input: EvaluationTaxonomyInput + call_id: str, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomyInput(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDone(RealtimeServerEvent, discriminator='response.function_call_arguments.done'): + arguments: str + call_id: str + event_id: str + item_id: str + name: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE] @overload def __init__( self, *, - type: str + arguments: str, + call_id: str, + event_id: str, + item_id: str, + name: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomyInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - POLICY = "policy" + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDelta(RealtimeServerEvent, discriminator='response.mcp_call_arguments.delta'): + delta: str + event_id: str + item_id: str + obfuscation: Optional[str] + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA] + @overload + def __init__( + self, + *, + delta: str, + event_id: str, + item_id: str, + obfuscation: Optional[str] = ..., + output_index: int, + response_id: str + ) -> None: ... - class azure.ai.projects.models.EvaluatorCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENTS = "agents" - QUALITY = "quality" - SAFETY = "safety" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorCredentialRequest(_Model): - blob_uri: str + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDone(RealtimeServerEvent, discriminator='response.mcp_call_arguments.done'): + arguments: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE] @overload def __init__( self, *, - blob_uri: str + arguments: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorDefinition(_Model): - data_schema: Optional[dict[str, Any]] - init_parameters: Optional[dict[str, Any]] - metrics: Optional[dict[str, EvaluatorMetric]] - type: str + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallCompleted(RealtimeServerEvent, discriminator='response.mcp_call.completed'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED] @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - type: str + event_id: str, + item_id: str, + output_index: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorDefinitionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE = "code" - ENDPOINT = "endpoint" - OPENAI_GRADERS = "openai_graders" - PROMPT = "prompt" - PROMPT_AND_CODE = "prompt_and_code" - RUBRIC = "rubric" - SERVICE = "service" - - - class azure.ai.projects.models.EvaluatorGenerationArtifacts(_Model): - dataset: DatasetReference - kinds: list[str] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallFailed(RealtimeServerEvent, discriminator='response.mcp_call.failed'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED] @overload def __init__( self, *, - dataset: DatasetReference, - kinds: list[str] + event_id: str, + item_id: str, + output_index: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationInputs(_Model): - evaluator_description: Optional[str] - evaluator_display_name: Optional[str] - evaluator_name: str - model: str - sources: list[EvaluatorGenerationJobSource] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallInProgress(RealtimeServerEvent, discriminator='response.mcp_call.in_progress'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS] @overload def __init__( self, *, - evaluator_description: Optional[str] = ..., - evaluator_display_name: Optional[str] = ..., - evaluator_name: str, - model: str, - sources: list[EvaluatorGenerationJobSource] + event_id: str, + item_id: str, + output_index: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJob(_Model): - created_at: datetime - error: Optional[ApiError] - finished_at: Optional[datetime] - id: str - input_quality_warnings: Optional[list[RubricGenerationInputQualityWarning]] - inputs: Optional[EvaluatorGenerationInputs] - result: Optional[EvaluatorVersion] - status: Union[str, JobStatus] - usage: Optional[EvaluatorGenerationTokenUsage] + class azure.ai.projects.models.RealtimeServerEventResponseOutputItemAdded(RealtimeServerEvent, discriminator='response.output_item.added'): + event_id: str + item: RealtimeConversationItem + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED] @overload def __init__( self, *, - inputs: Optional[EvaluatorGenerationInputs] = ... + event_id: str, + item: RealtimeConversationItem, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJobSource(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventResponseOutputItemDone(RealtimeServerEvent, discriminator='response.output_item.done'): + event_id: str + item: RealtimeConversationItem + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE] @overload def __init__( self, *, - type: str + event_id: str, + item: RealtimeConversationItem, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - DATASET = "dataset" - PROMPT = "prompt" - TRACES = "traces" - - - class azure.ai.projects.models.EvaluatorGenerationLROPoller(LROPoller[EvaluatorVersion]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.RealtimeServerEventResponseTextDelta(RealtimeServerEvent, discriminator='response.output_text.delta'): + content_index: int + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + content_index: int, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[EvaluatorVersion], - continuation_token: str, - **kwargs: Any - ) -> EvaluatorGenerationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationTokenUsage(_Model): - input_tokens: int - output_tokens: int - total_tokens: int + class azure.ai.projects.models.RealtimeServerEventResponseTextDone(RealtimeServerEvent, discriminator='response.output_text.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + text: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE] @overload def __init__( self, *, - input_tokens: int, - output_tokens: int, - total_tokens: int + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorMetric(_Model): - desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] - is_primary: Optional[bool] - max_value: Optional[float] - min_value: Optional[float] - threshold: Optional[float] - type: Optional[Union[str, EvaluatorMetricType]] + class azure.ai.projects.models.RealtimeServerEventSessionCreated(RealtimeServerEvent, discriminator='session.created'): + conversation_id: Optional[str] + event_id: str + session: VoiceAgentSessionResponseConfig + type: Literal[RealtimeServerEventType.SESSION_CREATED] @overload def __init__( self, *, - desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] = ..., - is_primary: Optional[bool] = ..., - max_value: Optional[float] = ..., - min_value: Optional[float] = ..., - threshold: Optional[float] = ..., - type: Optional[Union[str, EvaluatorMetricType]] = ... + conversation_id: Optional[str] = ..., + event_id: str, + session: VoiceAgentSessionResponseConfig + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeServerEventSessionUpdated(RealtimeServerEvent, discriminator='session.updated'): + event_id: str + session: VoiceAgentSessionResponseConfig + type: Literal[RealtimeServerEventType.SESSION_UPDATED] + + @overload + def __init__( + self, + *, + event_id: str, + session: VoiceAgentSessionResponseConfig + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeServerEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION_CREATED = "conversation.created" + CONVERSATION_ITEM_ADDED = "conversation.item.added" + CONVERSATION_ITEM_CREATED = "conversation.item.created" + CONVERSATION_ITEM_DELETED = "conversation.item.deleted" + CONVERSATION_ITEM_DONE = "conversation.item.done" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED = "conversation.item.input_audio_transcription.completed" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA = "conversation.item.input_audio_transcription.delta" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED = "conversation.item.input_audio_transcription.failed" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT = "conversation.item.input_audio_transcription.segment" + CONVERSATION_ITEM_RETRIEVED = "conversation.item.retrieved" + CONVERSATION_ITEM_TRUNCATED = "conversation.item.truncated" + ERROR = "error" + INPUT_AUDIO_BUFFER_CLEARED = "input_audio_buffer.cleared" + INPUT_AUDIO_BUFFER_COMMITTED = "input_audio_buffer.committed" + INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED = "input_audio_buffer.dtmf_event_received" + INPUT_AUDIO_BUFFER_SPEECH_STARTED = "input_audio_buffer.speech_started" + INPUT_AUDIO_BUFFER_SPEECH_STOPPED = "input_audio_buffer.speech_stopped" + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED = "input_audio_buffer.timeout_triggered" + MCP_LIST_TOOLS_COMPLETED = "mcp_list_tools.completed" + MCP_LIST_TOOLS_FAILED = "mcp_list_tools.failed" + MCP_LIST_TOOLS_IN_PROGRESS = "mcp_list_tools.in_progress" + OUTPUT_AUDIO_BUFFER_CLEARED = "output_audio_buffer.cleared" + OUTPUT_AUDIO_BUFFER_STARTED = "output_audio_buffer.started" + OUTPUT_AUDIO_BUFFER_STOPPED = "output_audio_buffer.stopped" + RATE_LIMITS_UPDATED = "rate_limits.updated" + RESPONSE_ANIMATION_BLENDSHAPES_DELTA = "response.animation_blendshapes.delta" + RESPONSE_ANIMATION_BLENDSHAPES_DONE = "response.animation_blendshapes.done" + RESPONSE_ANIMATION_VISEME_DELTA = "response.animation_viseme.delta" + RESPONSE_ANIMATION_VISEME_DONE = "response.animation_viseme.done" + RESPONSE_AUDIO_TIMESTAMP_DELTA = "response.audio_timestamp.delta" + RESPONSE_AUDIO_TIMESTAMP_DONE = "response.audio_timestamp.done" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + RESPONSE_CREATED = "response.created" + RESPONSE_DONE = "response.done" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + 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_OUTPUT_AUDIO_DELTA = "response.output_audio.delta" + RESPONSE_OUTPUT_AUDIO_DONE = "response.output_audio.done" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA = "response.output_audio_transcript.delta" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE = "response.output_audio_transcript.done" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + RESPONSE_VIDEO_DELTA = "response.video.delta" + RTC_CALL_ERROR = "rtc.call.error" + RTC_CALL_SDP_CREATED = "rtc.call.sdp.created" + SESSION_AVATAR_CONNECTING = "session.avatar.connecting" + SESSION_AVATAR_SWITCH_TO_IDLE = "session.avatar.switch_to_idle" + SESSION_AVATAR_SWITCH_TO_SPEAKING = "session.avatar.switch_to_speaking" + SESSION_CREATED = "session.created" + SESSION_SUBAGENT_ABORTED = "session.subagent.aborted" + SESSION_SUBAGENT_COMPLETED = "session.subagent.completed" + SESSION_SUBAGENT_STARTED = "session.subagent.started" + SESSION_UPDATED = "session.updated" + WARNING = "warning" + + + class azure.ai.projects.models.Reasoning(_Model): + context: Optional[Literal["auto", "current_turn", "all_turns"]] + effort: Optional[Union[str, ReasoningEffort]] + generate_summary: Optional[Literal["auto", "concise", "detailed"]] + mode: Optional[Union[str, ReasoningModeEnum]] + summary: Optional[Literal["auto", "concise", "detailed"]] + + @overload + def __init__( + self, + *, + context: Optional[Literal[auto, current_turn, all_turns]] = ..., + effort: Optional[Union[str, ReasoningEffort]] = ..., + generate_summary: Optional[Literal[auto, concise, detailed]] = ..., + mode: Optional[Union[str, ReasoningModeEnum]] = ..., + summary: Optional[Literal[auto, concise, detailed]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorMetricDirection(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DECREASE = "decrease" - INCREASE = "increase" - NEUTRAL = "neutral" - - - class azure.ai.projects.models.EvaluatorMetricType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BOOLEAN = "boolean" - CONTINUOUS = "continuous" - ORDINAL = "ordinal" + class azure.ai.projects.models.ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MAX = "max" + MEDIUM = "medium" + MINIMAL = "minimal" + NONE = "none" + XHIGH = "xhigh" - class azure.ai.projects.models.EvaluatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BUILT_IN = "builtin" - CUSTOM = "custom" + class azure.ai.projects.models.ReasoningModeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PRO = "pro" + STANDARD = "standard" - class azure.ai.projects.models.EvaluatorVersion(_Model): - categories: list[Union[str, EvaluatorCategory]] - created_at: datetime - created_by: str - definition: EvaluatorDefinition - description: Optional[str] - display_name: Optional[str] - evaluator_type: Union[str, EvaluatorType] - generation_artifacts: Optional[EvaluatorGenerationArtifacts] - generation_job_id: Optional[str] - id: Optional[str] - metadata: Optional[dict[str, str]] - modified_at: datetime - name: str - supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] - tags: Optional[dict[str, str]] - version: str - warnings: Optional[list[Union[str, GenerationWarningType]]] + class azure.ai.projects.models.RecurrenceSchedule(_Model): + type: str @overload def __init__( self, *, - categories: list[Union[str, EvaluatorCategory]], - definition: EvaluatorDefinition, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - evaluator_type: Union[str, EvaluatorType], - metadata: Optional[dict[str, str]] = ..., - supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] = ..., - tags: Optional[dict[str, str]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ExternalAgentDefinition(AgentDefinition, discriminator='external'): - kind: Literal[AgentKind.EXTERNAL] - otel_agent_id: Optional[str] - rai_config: RaiConfig + class azure.ai.projects.models.RecurrenceTrigger(Trigger, discriminator='Recurrence'): + end_time: Optional[datetime] + interval: int + schedule: RecurrenceSchedule + start_time: Optional[datetime] + time_zone: Optional[str] + type: Literal[TriggerType.RECURRENCE] @overload def __init__( self, *, - otel_agent_id: Optional[str] = ..., - rai_config: Optional[RaiConfig] = ... + end_time: Optional[datetime] = ..., + interval: int, + schedule: RecurrenceSchedule, + start_time: Optional[datetime] = ..., + time_zone: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricDataAgentToolParameters(_Model): - project_connections: Optional[list[ToolProjectConnection]] + class azure.ai.projects.models.RecurrenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DAILY = "Daily" + HOURLY = "Hourly" + MONTHLY = "Monthly" + WEEKLY = "Weekly" + + + class azure.ai.projects.models.RedTeam(_Model): + application_scenario: Optional[str] + attack_strategies: Optional[list[Union[str, AttackStrategy]]] + display_name: Optional[str] + name: str + num_turns: Optional[int] + properties: Optional[dict[str, str]] + risk_categories: Optional[list[Union[str, RiskCategory]]] + simulation_only: Optional[bool] + status: Optional[str] + tags: Optional[dict[str, str]] + target: RedTeamTargetConfig @overload def __init__( self, *, - project_connections: Optional[list[ToolProjectConnection]] = ... + application_scenario: Optional[str] = ..., + attack_strategies: Optional[list[Union[str, AttackStrategy]]] = ..., + display_name: Optional[str] = ..., + num_turns: Optional[int] = ..., + properties: Optional[dict[str, str]] = ..., + risk_categories: Optional[list[Union[str, RiskCategory]]] = ..., + simulation_only: Optional[bool] = ..., + tags: Optional[dict[str, str]] = ..., + target: RedTeamTargetConfig ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricIQPreviewTool(Tool, discriminator='fabric_iq_preview'): - project_connection_id: str - require_approval: Optional[Union[MCPToolRequireApproval, str]] - server_label: Optional[str] - server_url: Optional[str] - type: Literal[ToolType.FABRIC_IQ_PREVIEW] + class azure.ai.projects.models.RedTeamEvalRunDataSource(TypedDict, total=False): + key "item_generation_params": Required[Any] + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_red_team"]] + + + class azure.ai.projects.models.RedTeamTargetConfig(_Model): + type: str @overload def __init__( self, *, - project_connection_id: str, - require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., - server_label: Optional[str] = ..., - server_url: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricIQPreviewToolboxTool(ToolboxTool, discriminator='fabric_iq_preview'): + class azure.ai.projects.models.ReminderPreviewToolboxTool(ToolboxTool, discriminator='reminder_preview'): description: str name: str - project_connection_id: str - require_approval: Optional[Union[MCPToolRequireApproval, str]] - server_label: Optional[str] - server_url: Optional[str] tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.FABRIC_IQ_PREVIEW] + type: Literal[ToolboxToolType.REMINDER_PREVIEW] @overload def __init__( @@ -6451,10 +11723,6 @@ namespace azure.ai.projects.models *, description: Optional[str] = ..., name: Optional[str] = ..., - project_connection_id: str, - require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., - server_label: Optional[str] = ..., - server_url: Optional[str] = ..., tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @@ -6462,1674 +11730,1929 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FieldMapping(_Model): - content_fields: list[str] - filepath_field: Optional[str] - metadata_fields: Optional[list[str]] - title_field: Optional[str] - url_field: Optional[str] - vector_fields: Optional[list[str]] + class azure.ai.projects.models.ResponseRetrievalItemGenerationParams(TypedDict, total=False): + key "data_mapping": Required[Dict[str, str]] + key "max_num_turns": int + key "source": Required[Union[SourceFileContent, SourceFileID]] + key "type": Required[Literal["response_retrieval"]] + + + class azure.ai.projects.models.ResponseUsageInputTokensDetails(_Model): + cache_write_tokens: int + cached_tokens: int @overload def __init__( self, *, - content_fields: list[str], - filepath_field: Optional[str] = ..., - metadata_fields: Optional[list[str]] = ..., - title_field: Optional[str] = ..., - url_field: Optional[str] = ..., - vector_fields: Optional[list[str]] = ... + cache_write_tokens: int, + cached_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileDataGenerationJobOutput(DataGenerationJobOutput, discriminator='file'): - filename: str - id: str - type: Literal[DataGenerationJobOutputType.FILE] - - @overload - def __init__(self) -> None: ... - - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.FileDataGenerationJobSource(DataGenerationJobSource, discriminator='file'): - description: str - id: str - type: Literal[DataGenerationJobSourceType.FILE] + class azure.ai.projects.models.ResponseUsageOutputTokensDetails(_Model): + reasoning_tokens: int @overload def __init__( self, *, - description: Optional[str] = ..., - id: str + reasoning_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileDatasetVersion(DatasetVersion, discriminator='uri_file'): - connection_name: str - data_uri: str - description: str - id: str - is_reference: bool - name: str - tags: dict[str, str] - type: Literal[DatasetType.URI_FILE] - version: str + class azure.ai.projects.models.ResponsesProtocolConfiguration(_Model): + + + class azure.ai.projects.models.RiskCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE_VULNERABILITY = "CodeVulnerability" + HATE_UNFAIRNESS = "HateUnfairness" + PROHIBITED_ACTIONS = "ProhibitedActions" + PROTECTED_MATERIAL = "ProtectedMaterial" + SELF_HARM = "SelfHarm" + SENSITIVE_DATA_LEAKAGE = "SensitiveDataLeakage" + SEXUAL = "Sexual" + TASK_ADHERENCE = "TaskAdherence" + UNGROUNDED_ATTRIBUTES = "UngroundedAttributes" + VIOLENCE = "Violence" + + + class azure.ai.projects.models.Routine(_Model): + action: Optional[RoutineAction] + created_at: Optional[datetime] + description: Optional[str] + enabled: bool + name: Optional[str] + triggers: Optional[dict[str, RoutineTrigger]] + updated_at: Optional[datetime] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, + action: Optional[RoutineAction] = ..., + created_at: Optional[datetime] = ..., description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + enabled: bool, + name: Optional[str] = ..., + triggers: Optional[dict[str, RoutineTrigger]] = ..., + updated_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileSearchTool(Tool, discriminator='file_search'): - description: Optional[str] - filters: Optional[Filters] - max_num_results: Optional[int] - name: Optional[str] - ranking_options: Optional[RankingOptions] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.FILE_SEARCH] - vector_store_ids: list[str] + class azure.ai.projects.models.RoutineAction(_Model): + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - filters: Optional[Filters] = ..., - max_num_results: Optional[int] = ..., - name: Optional[str] = ..., - ranking_options: Optional[RankingOptions] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - vector_store_ids: list[str] + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileSearchToolboxTool(ToolboxTool, discriminator='file_search'): - description: str - filters: Optional[Filters] - max_num_results: Optional[int] - name: str - ranking_options: Optional[RankingOptions] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.FILE_SEARCH] - vector_store_ids: Optional[list[str]] + class azure.ai.projects.models.RoutineActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" + INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" + + + class azure.ai.projects.models.RoutineAttemptSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVENT_FIRE = "event_fire" + MANUAL_DISPATCH = "manual_dispatch" + QUEUED_DISPATCH = "queued_dispatch" + SCHEDULE_DELIVERY = "schedule_delivery" + TIMER_DELIVERY = "timer_delivery" + + + class azure.ai.projects.models.RoutineAuthorization(_Model): + identity: Optional[Union[str, RoutineDispatchIdentity]] @overload def __init__( self, *, - description: Optional[str] = ..., - filters: Optional[Filters] = ..., - max_num_results: Optional[int] = ..., - name: Optional[str] = ..., - ranking_options: Optional[RankingOptions] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - vector_store_ids: Optional[list[str]] = ... + identity: Optional[Union[str, RoutineDispatchIdentity]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FixedRatioVersionSelectionRule(VersionSelectionRule, discriminator='FixedRatio'): - agent_version: str - traffic_percentage: int - type: Literal[VersionSelectorType.FIXED_RATIO] + class azure.ai.projects.models.RoutineDispatchIdentity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + CREATOR = "creator" + + + class azure.ai.projects.models.RoutineDispatchPayload(_Model): + type: str @overload def __init__( self, *, - agent_version: str, - traffic_percentage: int + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FolderDatasetVersion(DatasetVersion, discriminator='uri_folder'): - connection_name: str - data_uri: str - description: str + class azure.ai.projects.models.RoutineDispatchPayloadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" + INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" + + + class azure.ai.projects.models.RoutineRun(_Model): + action_correlation_id: Optional[str] + action_type: Optional[Union[str, RoutineActionType]] + agent_endpoint_id: Optional[str] + agent_id: Optional[str] + attempt_source: Optional[Union[str, RoutineAttemptSource]] + conversation_id: Optional[str] + dispatch_id: Optional[str] + ended_at: Optional[datetime] + error_message: Optional[str] + error_status_code: Optional[int] + error_type: Optional[str] id: str - is_reference: bool - name: str - tags: dict[str, str] - type: Literal[DatasetType.URI_FOLDER] - version: str + phase: Optional[Union[str, RoutineRunPhase]] + response_id: Optional[str] + scheduled_fire_at: Optional[datetime] + session_id: Optional[str] + started_at: Optional[datetime] + status: Optional[RoutineRunStatus] + task_id: Optional[str] + trigger_event_payload: Optional[dict[str, Any]] + trigger_name: Optional[str] + trigger_type: Optional[Union[str, RoutineTriggerType]] + triggered_at: Optional[datetime] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + action_correlation_id: Optional[str] = ..., + action_type: Optional[Union[str, RoutineActionType]] = ..., + agent_endpoint_id: Optional[str] = ..., + agent_id: Optional[str] = ..., + attempt_source: Optional[Union[str, RoutineAttemptSource]] = ..., + conversation_id: Optional[str] = ..., + dispatch_id: Optional[str] = ..., + ended_at: Optional[datetime] = ..., + error_message: Optional[str] = ..., + error_status_code: Optional[int] = ..., + error_type: Optional[str] = ..., + phase: Optional[Union[str, RoutineRunPhase]] = ..., + response_id: Optional[str] = ..., + scheduled_fire_at: Optional[datetime] = ..., + session_id: Optional[str] = ..., + started_at: Optional[datetime] = ..., + status: Optional[RoutineRunStatus] = ..., + task_id: Optional[str] = ..., + trigger_event_payload: Optional[dict[str, Any]] = ..., + trigger_name: Optional[str] = ..., + trigger_type: Optional[Union[str, RoutineTriggerType]] = ..., + triggered_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FoundryModelArtifactProfileCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DATA_ONLY = "DataOnly" - RUNTIME_DEPENDENT = "RuntimeDependent" - UNKNOWN = "Unknown" - - - class azure.ai.projects.models.FoundryModelArtifactProfileSignal(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CUSTOM_PYTHON_CODE = "CustomPythonCode" - DYNAMIC_OPS = "DynamicOps" - NATIVE_BINARY = "NativeBinary" - PICKLE_DESERIALIZATION = "PickleDeserialization" - UNKNOWN_FORMAT = "UnknownFormat" - - - class azure.ai.projects.models.FoundryModelSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LOCAL_UPLOAD = "LocalUpload" - TRAINING_JOB = "TrainingJob" + class azure.ai.projects.models.RoutineRunPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + DISPATCHING = "dispatching" + FAILED = "failed" + QUEUED = "queued" - class azure.ai.projects.models.FoundryModelWarning(_Model): - code: Optional[Union[str, FoundryModelWarningCode]] - message: Optional[str] + class azure.ai.projects.models.RoutineTrigger(_Model): + type: str @overload def __init__( self, *, - code: Optional[Union[str, FoundryModelWarningCode]] = ..., - message: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FoundryModelWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): - RUNTIME_DEPENDENT_ARTIFACT = "RuntimeDependentArtifact" - UNCLASSIFIED_ARTIFACT = "UnclassifiedArtifact" - - - class azure.ai.projects.models.FoundryModelWeightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DRAFT_MODEL = "DraftModel" - FULL_WEIGHT = "FullWeight" - LO_RA = "LoRA" + class azure.ai.projects.models.RoutineTriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CUSTOM = "custom" + GITHUB_ISSUE = "github_issue" + SCHEDULE = "schedule" + TIMER = "timer" - class azure.ai.projects.models.FunctionShellToolParam(Tool, discriminator='shell'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - description: Optional[str] - environment: Optional[FunctionShellToolParamEnvironment] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.SHELL] + class azure.ai.projects.models.RubricBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='rubric'): + data_schema: dict[str, any] + dimensions: list[Dimension] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + pass_threshold: Optional[float] + type: Literal[EvaluatorDefinitionType.RUBRIC] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - description: Optional[str] = ..., - environment: Optional[FunctionShellToolParamEnvironment] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + data_schema: Optional[dict[str, Any]] = ..., + dimensions: list[Dimension], + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + pass_threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironment(_Model): - type: str + class azure.ai.projects.models.RubricGenerationInputQualityWarning(_Model): + code: Union[str, RubricGenerationInputQualityWarningCode] + message: str + severity: Union[str, RubricGenerationInputQualityWarningSeverity] + source: Union[str, RubricGenerationInputQualityWarningSource] + source_index: Optional[int] @overload def __init__( self, *, - type: str + code: Union[str, RubricGenerationInputQualityWarningCode], + message: str, + severity: Union[str, RubricGenerationInputQualityWarningSeverity], + source: Union[str, RubricGenerationInputQualityWarningSource], + source_index: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentContainerReferenceParam(FunctionShellToolParamEnvironment, discriminator='container_reference'): - container_id: str - type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_REFERENCE] + class azure.ai.projects.models.RubricGenerationInputQualityWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EMPTY_AGENT_INSTRUCTIONS = "empty_agent_instructions" + EMPTY_DATASET_CONTENT = "empty_dataset_content" + EMPTY_PROMPT = "empty_prompt" + INSUFFICIENT_TOTAL_INPUT = "insufficient_total_input" + LOW_TRACE_COUNT = "low_trace_count" + SHORT_AGENT_INSTRUCTIONS = "short_agent_instructions" + SHORT_DATASET_CONTENT = "short_dataset_content" + SHORT_PROMPT = "short_prompt" + + + class azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WARNING = "warning" + + + class azure.ai.projects.models.RubricGenerationInputQualityWarningSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + AGGREGATE = "aggregate" + DATASET = "dataset" + PROMPT = "prompt" + + + class azure.ai.projects.models.SASCredentials(BaseCredentials, discriminator='SAS'): + sas_token: Optional[str] + type: Literal[CredentialType.SAS] @overload - def __init__( - self, - *, - container_id: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam(FunctionShellToolParamEnvironment, discriminator='local'): - skills: Optional[list[LocalSkillParam]] - type: Literal[FunctionShellToolParamEnvironmentType.LOCAL] + class azure.ai.projects.models.SampleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION_RESULT_SAMPLE = "EvaluationResultSample" + + + class azure.ai.projects.models.Schedule(_Model): + description: Optional[str] + display_name: Optional[str] + enabled: bool + properties: Optional[dict[str, str]] + provisioning_status: Optional[Union[str, ScheduleProvisioningStatus]] + schedule_id: str + system_data: dict[str, str] + tags: Optional[dict[str, str]] + task: ScheduleTask + trigger: Trigger @overload def __init__( self, *, - skills: Optional[list[LocalSkillParam]] = ... + description: Optional[str] = ..., + display_name: Optional[str] = ..., + enabled: bool, + properties: Optional[dict[str, str]] = ..., + tags: Optional[dict[str, str]] = ..., + task: ScheduleTask, + trigger: Trigger ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTAINER_AUTO = "container_auto" - CONTAINER_REFERENCE = "container_reference" - LOCAL = "local" + class azure.ai.projects.models.ScheduleProvisioningStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATING = "Creating" + DELETING = "Deleting" + FAILED = "Failed" + SUCCEEDED = "Succeeded" + UPDATING = "Updating" - class azure.ai.projects.models.FunctionTool(Tool, discriminator='function'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] - description: Optional[str] - name: str - output_schema: Optional[dict[str, Any]] - parameters: dict[str, Any] - strict: bool - type: Literal[ToolType.FUNCTION] + class azure.ai.projects.models.ScheduleRoutineTrigger(RoutineTrigger, discriminator='schedule'): + cron_expression: str + time_zone: str + type: Literal[RoutineTriggerType.SCHEDULE] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - name: str, - output_schema: Optional[dict[str, Any]] = ..., - parameters: dict[str, Any], - strict: bool + cron_expression: str, + time_zone: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionToolParam(_Model): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] - description: Optional[str] - name: str - output_schema: Optional[dict[str, Any]] - parameters: Optional[EmptyModelParam] - strict: Optional[bool] - type: Literal["function"] + class azure.ai.projects.models.ScheduleRun(_Model): + error: Optional[str] + properties: dict[str, str] + run_id: str + schedule_id: str + success: bool + trigger_time: Optional[datetime] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - name: str, - output_schema: Optional[dict[str, Any]] = ..., - parameters: Optional[EmptyModelParam] = ..., - strict: Optional[bool] = ... + schedule_id: str, + trigger_time: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.GenerationWarningType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INPUT_QUALITY = "input_quality" - - - class azure.ai.projects.models.GitHubIssueEvent(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CLOSED = "closed" - OPENED = "opened" - - - class azure.ai.projects.models.GitHubIssueRoutineTrigger(RoutineTrigger, discriminator='github_issue'): - connection_id: str - issue_event: Union[str, GitHubIssueEvent] - owner: str - repository: str - type: Literal[RoutineTriggerType.GITHUB_ISSUE] + class azure.ai.projects.models.ScheduleTask(_Model): + configuration: Optional[dict[str, str]] + type: str @overload def __init__( self, *, - connection_id: str, - issue_event: Union[str, GitHubIssueEvent], - owner: str, - repository: str + configuration: Optional[dict[str, str]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.GrammarSyntax1(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LARK = "lark" - REGEX = "regex" + class azure.ai.projects.models.ScheduleTaskType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION = "Evaluation" + INSIGHT = "Insight" + + + class azure.ai.projects.models.SearchContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + IMAGE = "image" + TEXT = "text" + + + class azure.ai.projects.models.SearchContextSize(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" - class azure.ai.projects.models.HeaderTelemetryEndpointAuth(TelemetryEndpointAuth, discriminator='header'): - header_name: str - secret_id: str - secret_key: str - type: Literal[TelemetryEndpointAuthType.HEADER] + class azure.ai.projects.models.SessionConfiguration(_Model): + idle_timeout_seconds: Optional[timedelta] @overload def __init__( self, *, - header_name: str, - secret_id: str, - secret_key: str + idle_timeout_seconds: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HostedAgentDefinition(AgentDefinition, discriminator='hosted'): - code_configuration: Optional[CodeConfiguration] - container_configuration: Optional[ContainerConfiguration] - cpu: str - environment_variables: Optional[dict[str, str]] - kind: Literal[AgentKind.HOSTED] - memory: str - protocol_versions: Optional[list[ProtocolVersionRecord]] - rai_config: RaiConfig - session_configuration: Optional[SessionConfiguration] - telemetry_config: Optional[TelemetryConfig] + class azure.ai.projects.models.SessionDirectoryEntry(_Model): + is_directory: bool + modified_time: datetime + name: str + size: int @overload def __init__( self, *, - code_configuration: Optional[CodeConfiguration] = ..., - container_configuration: Optional[ContainerConfiguration] = ..., - cpu: str, - environment_variables: Optional[dict[str, str]] = ..., - memory: str, - protocol_versions: Optional[list[ProtocolVersionRecord]] = ..., - rai_config: Optional[RaiConfig] = ..., - session_configuration: Optional[SessionConfiguration] = ..., - telemetry_config: Optional[TelemetryConfig] = ... + is_directory: bool, + modified_time: datetime, + name: str, + size: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HourlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Hourly'): - type: Literal[RecurrenceType.HOURLY] + class azure.ai.projects.models.SessionFileWriteResult(_Model): + bytes_written: int + path: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + bytes_written: int, + path: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HumanEvaluationPreviewRuleAction(EvaluationRuleAction, discriminator='humanEvaluationPreview'): - template_id: str - type: Literal[EvaluationRuleActionType.HUMAN_EVALUATION_PREVIEW] + class azure.ai.projects.models.SessionLogEvent(_Model): + data: str + event: Union[str, SessionLogEventType] @overload def __init__( self, *, - template_id: str + data: str, + event: Union[str, SessionLogEventType] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HybridSearchOptions(_Model): - embedding_weight: float - text_weight: float + class azure.ai.projects.models.SessionLogEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LOG = "log" + + + class azure.ai.projects.models.SharepointGroundingToolParameters(_Model): + project_connections: Optional[list[ToolProjectConnection]] @overload def __init__( self, *, - embedding_weight: float, - text_weight: float + project_connections: Optional[list[ToolProjectConnection]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ImageGenAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AUTO = "auto" - EDIT = "edit" - GENERATE = "generate" - - - class azure.ai.projects.models.ImageGenTool(Tool, discriminator='image_generation'): - action: Optional[Union[str, ImageGenAction]] - 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[Union[Literal["1024x1024"], Literal["1024x1536"], Literal["1536x1024"], Literal["auto"], str]] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.IMAGE_GENERATION] + class azure.ai.projects.models.SharepointPreviewTool(Tool, discriminator='sharepoint_grounding_preview'): + sharepoint_grounding_preview: SharepointGroundingToolParameters + type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] @overload def __init__( self, *, - action: Optional[Union[str, ImageGenAction]] = ..., - 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[Union[Literal[1024x1024], Literal[1024x1536], Literal[1536x1024], Literal[auto], str]] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + sharepoint_grounding_preview: SharepointGroundingToolParameters ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ImageGenToolInputImageMask(_Model): - file_id: Optional[str] - image_url: Optional[str] + class azure.ai.projects.models.ShellToolboxTool(ToolboxTool, discriminator='shell'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + description: str + environment: ToolboxShellEnvironment + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.SHELL] @overload def __init__( self, *, - file_id: Optional[str] = ..., - image_url: Optional[str] = ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + description: Optional[str] = ..., + environment: ToolboxShellEnvironment, + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Index(_Model): - description: Optional[str] - id: Optional[str] - name: str - tags: Optional[dict[str, str]] - type: str - version: str + class azure.ai.projects.models.SimpleQnADataGenerationJobOptions(DataGenerationJobOptions, discriminator='simple_qna'): + max_samples: int + model_options: DataGenerationModelOptions + question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] + train_split: float + type: Literal[DataGenerationJobType.SIMPLE_QNA] @overload def __init__( self, *, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ..., - type: str + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.IndexType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AZURE_SEARCH = "AzureSearch" - COSMOS_DB = "CosmosDBNoSqlVectorStore" - MANAGED_AZURE_SEARCH = "ManagedAzureSearch" + class azure.ai.projects.models.SimpleQnAFineTuningQuestionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LONG_ANSWER = "long_answer" + SHORT_ANSWER = "short_answer" - class azure.ai.projects.models.InlineSkillParam(ContainerSkill, discriminator='inline'): - description: str - name: str - source: InlineSkillSourceParam - type: Literal[ContainerSkillType.INLINE] + class azure.ai.projects.models.SimulationSeedDataGenerationJobOptions(DataGenerationJobOptions, discriminator='simulation_seed'): + max_samples: int + model_options: DataGenerationModelOptions + train_split: float + type: Literal[DataGenerationJobType.SIMULATION_SEED] @overload def __init__( self, *, - description: str, - name: str, - source: InlineSkillSourceParam + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InlineSkillSourceParam(_Model): - data: str - media_type: Literal["application/zip"] - type: Literal["base64"] + class azure.ai.projects.models.SipTelephonyTransferDestination(TelephonyTransferDestination, discriminator='sip'): + kind: Literal[TelephonyTransferDestinationKind.SIP] + value: str @overload def __init__( self, *, - data: str + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InputFidelity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - - - class azure.ai.projects.models.Insight(_Model): - display_name: str - insight_id: str - metadata: InsightsMetadata - request: InsightRequest - result: Optional[InsightResult] - state: Union[str, OperationState] + class azure.ai.projects.models.SkillDetails(_Model): + created_at: datetime + default_version: str + description: str + id: str + latest_version: str + name: str @overload def __init__( self, *, - display_name: str, - request: InsightRequest + created_at: datetime, + default_version: str, + description: str, + id: str, + latest_version: str, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightCluster(_Model): + class azure.ai.projects.models.SkillInlineContent(_Model): + allowed_tools: Optional[list[str]] + compatibility: Optional[str] description: str - id: str - label: str - samples: Optional[list[InsightSample]] - sub_clusters: Optional[list[InsightCluster]] - suggestion: str - suggestion_title: str - weight: int + instructions: str + license: Optional[str] + metadata: Optional[dict[str, str]] @overload def __init__( self, *, + allowed_tools: Optional[list[str]] = ..., + compatibility: Optional[str] = ..., description: str, - id: str, - label: str, - samples: Optional[list[InsightSample]] = ..., - sub_clusters: Optional[list[InsightCluster]] = ..., - suggestion: str, - suggestion_title: str, - weight: int + instructions: str, + license: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightModelConfiguration(_Model): - model_deployment_name: str + class azure.ai.projects.models.SkillReferenceParam(ContainerSkill, discriminator='skill_reference'): + skill_id: str + type: Literal[ContainerSkillType.SKILL_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - model_deployment_name: str + skill_id: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightRequest(_Model): - type: str + class azure.ai.projects.models.SkillVersion(_Model): + created_at: datetime + description: str + id: str + name: str + skill_id: str + version: str @overload def __init__( self, *, - type: str + created_at: datetime, + description: str, + id: str, + name: str, + skill_id: str, + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightResult(_Model): - type: str + class azure.ai.projects.models.SpecificApplyPatchParam(ToolChoiceParam, discriminator='apply_patch'): + type: Literal[ToolChoiceParamType.APPLY_PATCH] @overload - def __init__( - self, - *, - type: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightSample(_Model): - correlation_info: dict[str, Any] - features: dict[str, Any] - id: str - type: str + class azure.ai.projects.models.SpecificFunctionShellParam(ToolChoiceParam, discriminator='shell'): + type: Literal[ToolChoiceParamType.SHELL] @overload - def __init__( - self, - *, - correlation_info: dict[str, Any], - features: dict[str, Any], - id: str, - type: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightScheduleTask(ScheduleTask, discriminator='Insight'): - configuration: dict[str, str] - insight: Insight - type: Literal[ScheduleTaskType.INSIGHT] + class azure.ai.projects.models.SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator='programmatic_tool_calling'): + type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] @overload - def __init__( - self, - *, - configuration: Optional[dict[str, str]] = ..., - insight: Insight - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightSummary(_Model): - method: str - sample_count: int - unique_cluster_count: int - unique_subcluster_count: int - usage: ClusterTokenUsage + class azure.ai.projects.models.StructuredInputDefinition(_Model): + default_value: Optional[Any] + description: Optional[str] + required: Optional[bool] + schema: Optional[dict[str, Any]] @overload def __init__( self, *, - method: str, - sample_count: int, - unique_cluster_count: int, - unique_subcluster_count: int, - usage: ClusterTokenUsage + default_value: Optional[Any] = ..., + description: Optional[str] = ..., + required: Optional[bool] = ..., + schema: Optional[dict[str, Any]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT_CLUSTER_INSIGHT = "AgentClusterInsight" - EVALUATION_COMPARISON = "EvaluationComparison" - EVALUATION_RUN_CLUSTER_INSIGHT = "EvaluationRunClusterInsight" - - - class azure.ai.projects.models.InsightsMetadata(_Model): - completed_at: Optional[datetime] - created_at: datetime + class azure.ai.projects.models.StructuredOutputDefinition(_Model): + description: str + name: str + schema: dict[str, Any] + strict: bool @overload def __init__( self, *, - completed_at: Optional[datetime] = ..., - created_at: datetime + description: str, + name: str, + schema: dict[str, Any], + strict: bool ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvocationsProtocolConfiguration(_Model): - - - class azure.ai.projects.models.InvocationsWsProtocolConfiguration(_Model): + class azure.ai.projects.models.TargetCompletionEvalRunDataSource(TypedDict, total=False): + key "input_messages": Required[InputMessagesItemReference] + key "source": Required[Union[SourceFileContent, SourceFileID]] + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_target_completions"]] - class azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_invocations_api'): - input: Any - type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_INVOCATIONS_API] + class azure.ai.projects.models.TaxonomyCategory(_Model): + description: Optional[str] + id: str + name: str + properties: Optional[dict[str, str]] + risk_category: Union[str, RiskCategory] + sub_categories: list[TaxonomySubCategory] @overload def __init__( self, *, - input: Any + description: Optional[str] = ..., + id: str, + name: str, + properties: Optional[dict[str, str]] = ..., + risk_category: Union[str, RiskCategory], + sub_categories: list[TaxonomySubCategory] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction(RoutineAction, discriminator='invoke_agent_invocations_api'): - agent_endpoint_id: Optional[str] - agent_name: Optional[str] - input: Optional[Any] - session_id: Optional[str] - type: Literal[RoutineActionType.INVOKE_AGENT_INVOCATIONS_API] + class azure.ai.projects.models.TaxonomySubCategory(_Model): + description: Optional[str] + enabled: bool + id: str + name: str + properties: Optional[dict[str, str]] @overload def __init__( self, *, - agent_endpoint_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - input: Optional[Any] = ..., - session_id: Optional[str] = ... + description: Optional[str] = ..., + enabled: bool, + id: str, + name: str, + properties: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_responses_api'): - input: Any - type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_RESPONSES_API] + class azure.ai.projects.models.TeamsPhoneExtensionTelephonyBinding(TelephonyBinding, discriminator='teams_phone_extension'): + connection: str + id: str + incoming_call_url: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - input: Any + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction(RoutineAction, discriminator='invoke_agent_responses_api'): - agent_endpoint_id: Optional[str] - agent_name: Optional[str] - conversation: Optional[str] - input: Optional[Any] - type: Literal[RoutineActionType.INVOKE_AGENT_RESPONSES_API] + class azure.ai.projects.models.TeamsPhoneExtensionTelephonyBindingListItem(TelephonyBindingListItem, discriminator='teams_phone_extension'): + connection: str + etag: str + id: str + incoming_call_url: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - agent_endpoint_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - conversation: Optional[str] = ..., - input: Optional[Any] = ... + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.JobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CANCELLED = "cancelled" - FAILED = "failed" - IN_PROGRESS = "in_progress" - QUEUED = "queued" - SUCCEEDED = "succeeded" - - - class azure.ai.projects.models.LocalShellToolParam(Tool, discriminator='local_shell'): - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.LOCAL_SHELL] + class azure.ai.projects.models.TeamsTelephonyTransferDestination(TelephonyTransferDestination, discriminator='teams'): + kind: Literal[TelephonyTransferDestinationKind.TEAMS] + value: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.LocalSkillParam(_Model): - description: str - name: str - path: str + class azure.ai.projects.models.TelemetryConfig(_Model): + endpoints: list[TelemetryEndpoint] @overload def __init__( self, *, - description: str, - name: str, - path: str + endpoints: list[TelemetryEndpoint] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.LoraConfig(_Model): - alpha: Optional[int] - dropout: Optional[float] - rank: Optional[int] - target_modules: Optional[list[str]] + class azure.ai.projects.models.TelemetryDataKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_OTEL = "ContainerOtel" + CONTAINER_STDOUT_STDERR = "ContainerStdoutStderr" + METRICS = "Metrics" + + + class azure.ai.projects.models.TelemetryEndpoint(_Model): + auth: Optional[TelemetryEndpointAuth] + data: list[Union[str, TelemetryDataKind]] + kind: str @overload def __init__( self, *, - alpha: Optional[int] = ..., - dropout: Optional[float] = ..., - rank: Optional[int] = ..., - target_modules: Optional[list[str]] = ... + auth: Optional[TelemetryEndpointAuth] = ..., + data: list[Union[str, TelemetryDataKind]], + kind: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPTool(Tool, discriminator='mcp'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - 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"]] - defer_loading: Optional[bool] - 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] - tool_configs: Optional[dict[str, ToolConfig]] - tunnel_id: Optional[str] - type: Literal[ToolType.MCP] + class azure.ai.projects.models.TelemetryEndpointAuth(_Model): + type: str @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - 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]] = ..., - defer_loading: Optional[bool] = ..., - 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] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - tunnel_id: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolFilter(_Model): - read_only: Optional[bool] - tool_names: Optional[list[str]] + class azure.ai.projects.models.TelemetryEndpointAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HEADER = "header" + + + class azure.ai.projects.models.TelemetryEndpointKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + OTLP = "OTLP" + + + class azure.ai.projects.models.TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GRPC = "Grpc" + HTTP = "Http" + + + class azure.ai.projects.models.TelephonyBinding(_Model): + connection: str + id: str + incoming_call_url: str + label: Optional[str] + provider: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - read_only: Optional[bool] = ..., - tool_names: Optional[list[str]] = ... + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + provider: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolRequireApproval(_Model): - always: Optional[MCPToolFilter] - never: Optional[MCPToolFilter] + class azure.ai.projects.models.TelephonyBindingListItem(_Model): + connection: str + etag: str + id: str + incoming_call_url: str + label: Optional[str] + provider: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - always: Optional[MCPToolFilter] = ..., - never: Optional[MCPToolFilter] = ... + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + provider: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolboxTool(ToolboxTool, discriminator='mcp'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - 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"]] - defer_loading: Optional[bool] - description: str - headers: Optional[dict[str, str]] - name: 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] - tool_configs: dict[str, ToolConfig] - tunnel_id: Optional[str] - type: Literal[ToolboxToolType.MCP] + class azure.ai.projects.models.TelephonyBindingStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + SUSPENDED = "suspended" + + + class azure.ai.projects.models.TelephonyCallDurationBasis(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANSWERED = "answered" + RECEIVED = "received" + + + class azure.ai.projects.models.TelephonyCallJob(_Model): + agent_name: str + attempt_count: int + cancellation: Optional[TelephonyCallJobCancellation] + created_at: datetime + destination: TelephonyOutboundDestination + id: str + next_attempt_at: Optional[datetime] + object: Literal["call_job"] + purpose: Optional[str] + retry_policy: TelephonyOutboundRetryPolicyResponse + revision: int + schedule: Optional[TelephonyCallJobSchedule] + status: Union[str, TelephonyCallJobStatus] + structured_inputs: Optional[dict[str, Any]] + telephony_binding_id: str + terminal_reason: Optional[str] + updated_at: datetime @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - 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]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - headers: Optional[dict[str, str]] = ..., - name: Optional[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] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - tunnel_id: Optional[str] = ... + agent_name: str, + attempt_count: int, + cancellation: Optional[TelephonyCallJobCancellation] = ..., + created_at: datetime, + destination: TelephonyOutboundDestination, + id: str, + next_attempt_at: Optional[datetime] = ..., + purpose: Optional[str] = ..., + retry_policy: TelephonyOutboundRetryPolicyResponse, + revision: int, + schedule: Optional[TelephonyCallJobSchedule] = ..., + status: Union[str, TelephonyCallJobStatus], + structured_inputs: Optional[dict[str, Any]] = ..., + telephony_binding_id: str, + terminal_reason: Optional[str] = ..., + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ManagedAgentIdentityBlueprintReference(AgentBlueprintReference, discriminator='ManagedAgentIdentityBlueprint'): - blueprint_id: str - type: Literal[AgentBlueprintReferenceType.MANAGED_AGENT_IDENTITY_BLUEPRINT] + class azure.ai.projects.models.TelephonyCallJobCancellation(_Model): + mode: str + requested_at: datetime + requested_by: str + revision: int @overload def __init__( self, *, - blueprint_id: str + mode: str, + requested_at: datetime, + requested_by: str, + revision: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ManagedAzureAISearchIndex(Index, discriminator='ManagedAzureSearch'): - description: str - id: str - name: str - tags: dict[str, str] - type: Literal[IndexType.MANAGED_AZURE_SEARCH] - vector_store_id: str - version: str + class azure.ai.projects.models.TelephonyCallJobSchedule(_Model): + expires_at: Optional[datetime] + not_before: Optional[datetime] @overload def __init__( self, *, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ..., - vector_store_id: str + expires_at: Optional[datetime] = ..., + not_before: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.McpProtocolConfiguration(_Model): + class azure.ai.projects.models.TelephonyCallJobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACCEPTED = "accepted" + BLOCKED = "blocked" + CANCELLATION_REQUESTED = "cancellation_requested" + CANCELLED = "cancelled" + COMPLETED = "completed" + DISPATCHING = "dispatching" + EXPIRED = "expired" + FAILED = "failed" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + WAITING_FOR_RETRY = "waiting_for_retry" + WAITING_FOR_SCHEDULE = "waiting_for_schedule" - class azure.ai.projects.models.MemoryItem(_Model): - content: str - kind: str - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.TelephonyCallLifecycleEvent(_Model): + name: Union[str, TelephonyCallLifecycleEventName] + observed_at: datetime + occurred_at: Optional[datetime] + outcome: Union[str, TelephonyCallLifecycleEventOutcome] + provider_event_id: Optional[str] + provider_sequence: Optional[int] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + reason: Optional[str] + sequence: int + source: Union[str, TelephonyCallLifecycleEventSource] + timestamp_source: Union[str, TelephonyCallTimestampSource] @overload def __init__( self, *, - content: str, - kind: str, - memory_id: str, - scope: str, - updated_at: datetime + name: Union[str, TelephonyCallLifecycleEventName], + observed_at: datetime, + occurred_at: Optional[datetime] = ..., + outcome: Union[str, TelephonyCallLifecycleEventOutcome], + provider_event_id: Optional[str] = ..., + provider_sequence: Optional[int] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + reason: Optional[str] = ..., + source: Union[str, TelephonyCallLifecycleEventSource], + timestamp_source: Union[str, TelephonyCallTimestampSource] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryItemKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CHAT_SUMMARY = "chat_summary" - PROCEDURAL = "procedural" - USER_PROFILE = "user_profile" + class azure.ai.projects.models.TelephonyCallLifecycleEventName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_SESSION_CONNECT = "telephony.agent_session.connect" + BINDING_RESOLVE = "telephony.binding.resolve" + CALL_DISCONNECT = "telephony.call.disconnect" + CALL_HANGUP = "telephony.call.hangup" + CALL_TRANSFER = "telephony.call.transfer" + FIRST_AGENT_AUDIO = "telephony.media.first_agent_audio" + FIRST_CALLER_AUDIO = "telephony.media.first_caller_audio" + MEDIA_CONNECT = "telephony.media.connect" + PROVIDER_ANSWER = "telephony.provider.answer" + WEBHOOK_RECEIVED = "telephony.webhook.received" + WEBHOOK_VALIDATION = "telephony.webhook.validation" - class azure.ai.projects.models.MemoryOperation(_Model): - kind: Union[str, MemoryOperationKind] - memory_item: MemoryItem + class azure.ai.projects.models.TelephonyCallLifecycleEventOutcome(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + OBSERVED = "observed" + REJECTED = "rejected" + STARTED = "started" + SUCCEEDED = "succeeded" + + + class azure.ai.projects.models.TelephonyCallLifecycleEventSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GATEWAY = "gateway" + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + TWILIO = "twilio" + VOICE_AGENT = "voice_agent" + + + class azure.ai.projects.models.TelephonyCallPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ADMITTED = "admitted" + AGENT_SESSION_READY = "agent_session_ready" + ANSWERED = "answered" + ANSWERING = "answering" + BRIDGING = "bridging" + COMPLETED = "completed" + FAILED = "failed" + MANAGING = "managing" + MEDIA_CONNECTED = "media_connected" + RECEIVED = "received" + REJECTED = "rejected" + VALIDATED = "validated" + + + class azure.ai.projects.models.TelephonyCallRecord(_Model): + agent_session_ready_at: Optional[datetime] + answered_at: Optional[datetime] + caller_number: Optional[str] + duration_ms: Optional[timedelta] + end_reason: Optional[str] + ended_at: Optional[datetime] + events: list[TelephonyCallLifecycleEvent] + events_truncated: bool + id: str + media_connected_at: Optional[datetime] + phase: Union[str, TelephonyCallPhase] + provider: Union[str, TelephonyProvider] + provider_call_id: Optional[str] + provider_message: Optional[str] + provider_number: Optional[str] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + started_at: datetime + status: Union[str, TelephonyCallStatus] + timing: TelephonyCallTiming + trace: Optional[TelephonyCallTrace] @overload def __init__( self, *, - kind: Union[str, MemoryOperationKind], - memory_item: MemoryItem + agent_session_ready_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + caller_number: Optional[str] = ..., + duration_ms: Optional[timedelta] = ..., + end_reason: Optional[str] = ..., + ended_at: Optional[datetime] = ..., + events: list[TelephonyCallLifecycleEvent], + events_truncated: bool, + id: str, + media_connected_at: Optional[datetime] = ..., + phase: Union[str, TelephonyCallPhase], + provider: Union[str, TelephonyProvider], + provider_call_id: Optional[str] = ..., + provider_message: Optional[str] = ..., + provider_number: Optional[str] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + started_at: datetime, + status: Union[str, TelephonyCallStatus], + timing: TelephonyCallTiming, + trace: Optional[TelephonyCallTrace] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryOperationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CREATE = "create" - DELETE = "delete" - UPDATE = "update" + class azure.ai.projects.models.TelephonyCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FAILED = "failed" + IN_PROGRESS = "in_progress" + SUCCESS = "success" - class azure.ai.projects.models.MemorySearchItem(_Model): - memory_item: MemoryItem + class azure.ai.projects.models.TelephonyCallSummary(_Model): + agent_session_ready_at: Optional[datetime] + answered_at: Optional[datetime] + caller_number: Optional[str] + duration_ms: Optional[timedelta] + end_reason: Optional[str] + ended_at: Optional[datetime] + id: str + media_connected_at: Optional[datetime] + phase: Union[str, TelephonyCallPhase] + provider: Union[str, TelephonyProvider] + provider_call_id: Optional[str] + provider_message: Optional[str] + provider_number: Optional[str] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + started_at: datetime + status: Union[str, TelephonyCallStatus] @overload def __init__( self, *, - memory_item: MemoryItem + agent_session_ready_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + caller_number: Optional[str] = ..., + duration_ms: Optional[timedelta] = ..., + end_reason: Optional[str] = ..., + ended_at: Optional[datetime] = ..., + id: str, + media_connected_at: Optional[datetime] = ..., + phase: Union[str, TelephonyCallPhase], + provider: Union[str, TelephonyProvider], + provider_call_id: Optional[str] = ..., + provider_message: Optional[str] = ..., + provider_number: Optional[str] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + started_at: datetime, + status: Union[str, TelephonyCallStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemorySearchOptions(_Model): - max_memories: Optional[int] + class azure.ai.projects.models.TelephonyCallTimestampSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DERIVED = "derived" + GATEWAY = "gateway" + PROVIDER = "provider" + + + class azure.ai.projects.models.TelephonyCallTiming(_Model): + admitted_at: Optional[datetime] + agent_session_ready_at: Optional[datetime] + answer_requested_at: Optional[datetime] + answered_at: Optional[datetime] + duration_basis: Optional[Union[str, TelephonyCallDurationBasis]] + ended_at: Optional[datetime] + first_agent_audio_at: Optional[datetime] + first_caller_audio_at: Optional[datetime] + media_connected_at: Optional[datetime] + received_at: Optional[datetime] + timestamp_source: Union[str, TelephonyCallTimestampSource] + validated_at: Optional[datetime] @overload def __init__( self, *, - max_memories: Optional[int] = ... + admitted_at: Optional[datetime] = ..., + agent_session_ready_at: Optional[datetime] = ..., + answer_requested_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + duration_basis: Optional[Union[str, TelephonyCallDurationBasis]] = ..., + ended_at: Optional[datetime] = ..., + first_agent_audio_at: Optional[datetime] = ..., + first_caller_audio_at: Optional[datetime] = ..., + media_connected_at: Optional[datetime] = ..., + received_at: Optional[datetime] = ..., + timestamp_source: Union[str, TelephonyCallTimestampSource], + validated_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemorySearchPreviewTool(Tool, discriminator='memory_search_preview'): - memory_store_name: str - scope: str - search_options: Optional[MemorySearchOptions] - type: Literal[ToolType.MEMORY_SEARCH_PREVIEW] - update_delay: Optional[int] + class azure.ai.projects.models.TelephonyCallTrace(_Model): + conversation_id: Optional[str] + mode: Optional[Union[str, TelephonyCallTraceMode]] + root_span_id: Optional[str] + status: Union[str, TelephonyCallTraceStatus] + trace_id: Optional[str] @overload def __init__( self, *, - memory_store_name: str, - scope: str, - search_options: Optional[MemorySearchOptions] = ..., - update_delay: Optional[int] = ... + conversation_id: Optional[str] = ..., + mode: Optional[Union[str, TelephonyCallTraceMode]] = ..., + root_span_id: Optional[str] = ..., + status: Union[str, TelephonyCallTraceStatus], + trace_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDefaultDefinition(MemoryStoreDefinition, discriminator='default'): - chat_model: str - embedding_model: str - kind: Literal[MemoryStoreKind.DEFAULT] - options: Optional[MemoryStoreDefaultOptions] + class azure.ai.projects.models.TelephonyCallTraceMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LIVE = "live" + POST_CALL = "post_call" + + + class azure.ai.projects.models.TelephonyCallTraceStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AVAILABLE = "available" + EMITTING = "emitting" + FAILED = "failed" + NOT_APPLICABLE = "not_applicable" + NOT_RECORDED = "not_recorded" + PENDING = "pending" + + + class azure.ai.projects.models.TelephonyCampaign(_Model): + active_recipient_import_id: Optional[str] + active_validation_id: Optional[str] + agent_name: str + call_job_counts: TelephonyCampaignCallJobCounts + configuration_status: Union[str, TelephonyCampaignConfigurationStatus] + created_at: datetime + display_name: str + execution_status: Union[str, TelephonyCampaignExecutionStatus] + id: str + latest_successful_validation_id: Optional[str] + object: Literal["campaign"] + published_at: Optional[datetime] + purpose: Optional[str] + retry_policy: TelephonyOutboundRetryPolicyResponse + schedule: Optional[TelephonyCampaignSchedule] + telephony_binding_id: str + updated_at: datetime @overload def __init__( self, *, - chat_model: str, - embedding_model: str, - options: Optional[MemoryStoreDefaultOptions] = ... + active_recipient_import_id: Optional[str] = ..., + active_validation_id: Optional[str] = ..., + agent_name: str, + call_job_counts: TelephonyCampaignCallJobCounts, + configuration_status: Union[str, TelephonyCampaignConfigurationStatus], + created_at: datetime, + display_name: str, + execution_status: Union[str, TelephonyCampaignExecutionStatus], + id: str, + latest_successful_validation_id: Optional[str] = ..., + published_at: Optional[datetime] = ..., + purpose: Optional[str] = ..., + retry_policy: TelephonyOutboundRetryPolicyResponse, + schedule: Optional[TelephonyCampaignSchedule] = ..., + telephony_binding_id: str, + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDefaultOptions(_Model): - chat_summary_enabled: bool - default_ttl_seconds: Optional[timedelta] - procedural_memory_enabled: Optional[bool] - user_profile_details: Optional[str] - user_profile_enabled: bool + class azure.ai.projects.models.TelephonyCampaignCallJobCounts(_Model): + blocked: int + cancelled: int + completed: int + expired: int + failed: int + in_progress: int + pending: int + total: int @overload def __init__( self, *, - chat_summary_enabled: bool, - default_ttl_seconds: Optional[timedelta] = ..., - procedural_memory_enabled: Optional[bool] = ..., - user_profile_details: Optional[str] = ..., - user_profile_enabled: bool + blocked: int, + cancelled: int, + completed: int, + expired: int, + failed: int, + in_progress: int, + pending: int, + total: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDefinition(_Model): - kind: str + class azure.ai.projects.models.TelephonyCampaignConfigurationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DRAFT = "draft" + IMPORTING = "importing" + PUBLISHED = "published" + PUBLISHING = "publishing" + PUBLISH_FAILED = "publish_failed" + VALIDATING = "validating" + + + class azure.ai.projects.models.TelephonyCampaignDuplicateHandling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + KEEP_EACH = "keep_each" + MERGE = "merge" + REJECT = "reject" + + + class azure.ai.projects.models.TelephonyCampaignExecutionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + COMPLETED = "completed" + FAILED = "failed" + NONE = "none" + PAUSED = "paused" + RUNNING = "running" + SCHEDULED = "scheduled" + + + class azure.ai.projects.models.TelephonyCampaignRecipientImport(_Model): + campaign_id: str + created_at: datetime + duplicate_handling: Union[str, TelephonyCampaignDuplicateHandling] + eligible_recipient_count: int + error_code: Optional[str] + error_message: Optional[str] + id: str + invalid_recipient_count: int + mapping: Optional[TelephonyCampaignRecipientMapping] + object: Literal["recipient_import"] + rows_processed: int + source: TelephonyCampaignRecipientImportSource + status: Union[str, TelephonyCampaignRecipientImportStatus] + updated_at: datetime @overload def __init__( self, *, - kind: str + campaign_id: str, + created_at: datetime, + duplicate_handling: Union[str, TelephonyCampaignDuplicateHandling], + eligible_recipient_count: int, + error_code: Optional[str] = ..., + error_message: Optional[str] = ..., + id: str, + invalid_recipient_count: int, + mapping: Optional[TelephonyCampaignRecipientMapping] = ..., + rows_processed: int, + source: TelephonyCampaignRecipientImportSource, + status: Union[str, TelephonyCampaignRecipientImportStatus], + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDeleteScopeResult(_Model): - deleted: bool - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED] - scope: str + class azure.ai.projects.models.TelephonyCampaignRecipientImportFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CSV = "csv" + JSON = "json" + JSONL = "jsonl" + + + class azure.ai.projects.models.TelephonyCampaignRecipientImportSource(_Model): + dataset_name: str + dataset_version: str + file_name: str + format: Union[str, TelephonyCampaignRecipientImportFormat] + type: Literal["dataset"] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED], - scope: str + dataset_name: str, + dataset_version: str, + file_name: str, + format: Union[str, TelephonyCampaignRecipientImportFormat] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDetails(_Model): - created_at: datetime - definition: MemoryStoreDefinition - description: Optional[str] - id: str - metadata: Optional[dict[str, str]] - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE] - updated_at: datetime + class azure.ai.projects.models.TelephonyCampaignRecipientImportStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FAILED = "failed" + RUNNING = "running" + SUCCEEDED = "succeeded" + + + class azure.ai.projects.models.TelephonyCampaignRecipientMapping(_Model): + destination: str + expires_at: Optional[str] + not_before: Optional[str] + recipient_item_key: Optional[str] + recipient_key: str @overload def __init__( self, *, - created_at: datetime, - definition: MemoryStoreDefinition, - description: Optional[str] = ..., - id: str, - metadata: Optional[dict[str, str]] = ..., - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE], - updated_at: datetime + destination: str, + expires_at: Optional[str] = ..., + not_before: Optional[str] = ..., + recipient_item_key: Optional[str] = ..., + recipient_key: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DEFAULT = "default" - - - class azure.ai.projects.models.MemoryStoreObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MEMORY_DELETED = "memory_store.item.deleted" - MEMORY_STORE = "memory_store" - MEMORY_STORE_DELETED = "memory_store.deleted" - MEMORY_STORE_SCOPE_DELETED = "memory_store.scope.deleted" - - - class azure.ai.projects.models.MemoryStoreOperationUsage(_Model): - embedding_tokens: int - input_tokens: int - input_tokens_details: ResponseUsageInputTokensDetails - output_tokens: int - output_tokens_details: ResponseUsageOutputTokensDetails - total_tokens: int + class azure.ai.projects.models.TelephonyCampaignRecipientMappingRequest(_Model): + destination: Optional[str] + expires_at: Optional[str] + not_before: Optional[str] + recipient_item_key: Optional[str] + recipient_key: Optional[str] @overload def __init__( - self, - *, - embedding_tokens: int, - input_tokens: int, - input_tokens_details: ResponseUsageInputTokensDetails, - output_tokens: int, - output_tokens_details: ResponseUsageOutputTokensDetails, - total_tokens: int + self, + *, + destination: Optional[str] = ..., + expires_at: Optional[str] = ..., + not_before: Optional[str] = ..., + recipient_item_key: Optional[str] = ..., + recipient_key: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreSearchResult(_Model): - memories: list[MemorySearchItem] - search_id: str - usage: MemoryStoreOperationUsage + class azure.ai.projects.models.TelephonyCampaignSchedule(_Model): + start_at: Optional[datetime] + type: Union[str, TelephonyCampaignScheduleType] @overload def __init__( self, *, - memories: list[MemorySearchItem], - search_id: str, - usage: MemoryStoreOperationUsage + start_at: Optional[datetime] = ..., + type: Union[str, TelephonyCampaignScheduleType] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateCompletedResult(_Model): - memory_operations: list[MemoryOperation] - usage: MemoryStoreOperationUsage + class azure.ai.projects.models.TelephonyCampaignScheduleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + IMMEDIATE = "immediate" + SCHEDULED = "scheduled" + + + class azure.ai.projects.models.TelephonyOperation(_Model): + created_at: Optional[datetime] + error: Optional[ApiError] + id: str + object: Literal["operation"] + resource: Optional[TelephonyOperationResource] + status: Union[str, TelephonyOperationStatus] @overload def __init__( self, *, - memory_operations: list[MemoryOperation], - usage: MemoryStoreOperationUsage + created_at: Optional[datetime] = ..., + error: Optional[ApiError] = ..., + id: str, + resource: Optional[TelephonyOperationResource] = ..., + status: Union[str, TelephonyOperationStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateResult(_Model): - error: Optional[ApiError] - result: Optional[MemoryStoreUpdateCompletedResult] - status: Union[str, MemoryStoreUpdateStatus] - superseded_by: Optional[str] - update_id: str + class azure.ai.projects.models.TelephonyOperationResource(_Model): + id: str + type: str @overload def __init__( self, *, - error: Optional[ApiError] = ..., - result: Optional[MemoryStoreUpdateCompletedResult] = ..., - status: Union[str, MemoryStoreUpdateStatus], - superseded_by: Optional[str] = ..., - update_id: str + id: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - COMPLETED = "completed" + class azure.ai.projects.models.TelephonyOperationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" FAILED = "failed" - IN_PROGRESS = "in_progress" - QUEUED = "queued" - SUPERSEDED = "superseded" + NOT_STARTED = "not_started" + RUNNING = "running" + SUCCEEDED = "succeeded" + UNKNOWN_STATUS = "unknown" - class azure.ai.projects.models.Microsoft365PermissionScopes(_Model): - resource_app_id: str - scopes: list[str] + class azure.ai.projects.models.TelephonyOutboundDestination(_Model): + type: Union[str, TelephonyOutboundDestinationType] + value: str @overload def __init__( self, *, - resource_app_id: str, - scopes: list[str] + type: Union[str, TelephonyOutboundDestinationType], + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishDefaults(_Model): - agent_display_name: Optional[str] - agent_name: Optional[str] - app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] - app_registration_client_id: Optional[str] - app_version: Optional[str] - bot_service_arm_id: Optional[str] - developer_name: Optional[str] - developer_website_url: Optional[str] - full_description: Optional[str] - privacy_url: Optional[str] - recommended_next_app_version: Optional[str] - short_description: Optional[str] - teams_app_id: Optional[str] - terms_of_use_url: Optional[str] - title_id: Optional[str] + class azure.ai.projects.models.TelephonyOutboundDestinationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PHONE_NUMBER = "phone_number" + + + class azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicy(TelephonyOutboundRetryPolicy, discriminator='fixed_interval'): + interval: Optional[timedelta] + max_attempts: int + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] @overload def __init__( self, *, - agent_display_name: Optional[str] = ..., - agent_name: Optional[str] = ..., - app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] = ..., - app_registration_client_id: Optional[str] = ..., - app_version: Optional[str] = ..., - bot_service_arm_id: Optional[str] = ..., - developer_name: Optional[str] = ..., - developer_website_url: Optional[str] = ..., - full_description: Optional[str] = ..., - privacy_url: Optional[str] = ..., - recommended_next_app_version: Optional[str] = ..., - short_description: Optional[str] = ..., - teams_app_id: Optional[str] = ..., - terms_of_use_url: Optional[str] = ..., - title_id: Optional[str] = ... + interval: Optional[timedelta] = ..., + max_attempts: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishResult(_Model): - teams_app_id: Optional[str] - title_id: Optional[str] + class azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicyResponse(TelephonyOutboundRetryPolicyResponse, discriminator='fixed_interval'): + interval: timedelta + max_attempts: int + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] @overload def __init__( self, *, - teams_app_id: Optional[str] = ..., - title_id: Optional[str] = ... + interval: timedelta, + max_attempts: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): - PERSONAL = "Personal" - SHARED = "Shared" - TENANT = "Tenant" - - - class azure.ai.projects.models.MicrosoftFabricPreviewTool(Tool, discriminator='fabric_dataagent_preview'): - fabric_dataagent_preview: FabricDataAgentToolParameters - type: Literal[ToolType.FABRIC_DATAAGENT_PREVIEW] + class azure.ai.projects.models.TelephonyOutboundRetryPolicy(_Model): + max_attempts: Optional[int] + type: str @overload def __init__( self, *, - fabric_dataagent_preview: FabricDataAgentToolParameters + max_attempts: Optional[int] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelCredentialRequest(_Model): - blob_uri: str + class azure.ai.projects.models.TelephonyOutboundRetryPolicyResponse(_Model): + max_attempts: int + type: str @overload def __init__( self, *, - blob_uri: str + max_attempts: int, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelDeployment(Deployment, discriminator='ModelDeployment'): - capabilities: dict[str, str] - connection_name: Optional[str] - model_name: str - model_publisher: str - model_version: str - name: str - sku: ModelDeploymentSku - type: Literal[DeploymentType.MODEL_DEPLOYMENT] + class azure.ai.projects.models.TelephonyOutboundRetryPolicyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FIXED_INTERVAL = "fixed_interval" + + + class azure.ai.projects.models.TelephonyProvider(str, Enum, metaclass=CaseInsensitiveEnumMeta): + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + TWILIO = "twilio" + + + class azure.ai.projects.models.TelephonyTransferDestination(_Model): + kind: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + kind: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelDeploymentSku(_Model): - capacity: int - family: str + class azure.ai.projects.models.TelephonyTransferDestinationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PSTN = "pstn" + SIP = "sip" + TEAMS = "teams" + + + class azure.ai.projects.models.TelephonyTransferTarget(_Model): + description: str + destination: TelephonyTransferDestination name: str - size: str - tier: str @overload def __init__( self, *, - capacity: int, - family: str, - name: str, - size: str, - tier: str + description: str, + destination: TelephonyTransferDestination, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelPendingUploadRequest(_Model): - connection_name: Optional[str] - pending_upload_id: Optional[str] - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + class azure.ai.projects.models.TelephonyTransferTargets(_Model): + transfer_targets: list[TelephonyTransferTarget] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - pending_upload_id: Optional[str] = ..., - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + transfer_targets: list[TelephonyTransferTarget] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelPendingUploadResponse(_Model): - blob_reference: BlobReference - pending_upload_id: str - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.TestingCriterionAzureAIEvaluator(TypedDict, total=False): + key "data_mapping": Dict[str, str] + key "evaluator_name": Required[str] + key "evaluator_version": str + key "initialization_parameters": Dict[str, Any] + key "name": Required[str] + key "type": Required[Literal["azure_ai_evaluator"]] + + + class azure.ai.projects.models.TextResponseFormat(_Model): + type: str @overload def __init__( self, *, - blob_reference: BlobReference, - pending_upload_id: str, - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE], - version: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelSamplingConfigParam(TypedDict, total=False): - key "max_completion_tokens": int - key "seed": int - key "temperature": float - key "top_p": float + class azure.ai.projects.models.TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + JSON_OBJECT = "json_object" + JSON_SCHEMA = "json_schema" + TEXT = "text" - class azure.ai.projects.models.ModelSamplingParams(_Model): - max_completion_tokens: Optional[int] - seed: Optional[int] - temperature: Optional[float] - top_p: Optional[float] + class azure.ai.projects.models.TextResponseFormatJsonObject(TextResponseFormat, 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.projects.models.TextResponseFormatJsonSchema(TextResponseFormat, discriminator='json_schema'): + description: Optional[str] + name: str + schema: dict[str, Any] + strict: Optional[bool] + type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] @overload def __init__( self, *, - max_completion_tokens: Optional[int] = ..., - seed: Optional[int] = ..., - temperature: Optional[float] = ..., - top_p: Optional[float] = ... + description: Optional[str] = ..., + name: str, + schema: dict[str, Any], + strict: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelSourceData(_Model): - job_id: Optional[str] - source_type: Optional[Union[str, FoundryModelSourceType]] + class azure.ai.projects.models.TextResponseFormatText(TextResponseFormat, discriminator='text'): + type: Literal[TextResponseFormatConfigurationType.TEXT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.TimerRoutineTrigger(RoutineTrigger, discriminator='timer'): + at: Optional[datetime] + type: Literal[RoutineTriggerType.TIMER] @overload def __init__( self, *, - job_id: Optional[str] = ..., - source_type: Optional[Union[str, FoundryModelSourceType]] = ... + at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelVersion(_Model): - artifact_profile: Optional[ArtifactProfile] - base_model: Optional[str] - blob_uri: str - description: Optional[str] - id: Optional[str] - lora_config: Optional[LoraConfig] - name: str - source: Optional[ModelSourceData] - tags: Optional[dict[str, str]] - version: str - warnings: Optional[list[FoundryModelWarning]] - weight_type: Optional[Union[str, FoundryModelWeightType]] + class azure.ai.projects.models.Tool(_Model): + type: str @overload def __init__( self, *, - base_model: Optional[str] = ..., - blob_uri: str, - description: Optional[str] = ..., - lora_config: Optional[LoraConfig] = ..., - source: Optional[ModelSourceData] = ..., - tags: Optional[dict[str, str]] = ..., - weight_type: Optional[Union[str, FoundryModelWeightType]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MonthlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Monthly'): - days_of_month: list[int] - type: Literal[RecurrenceType.MONTHLY] + class azure.ai.projects.models.ToolChoiceAllowed(ToolChoiceParam, discriminator='allowed_tools'): + mode: Literal["auto", "required"] + tools: list[dict[str, Any]] + type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] @overload def __init__( self, *, - days_of_month: list[int] + mode: Literal["auto", "required"], + tools: list[dict[str, Any]] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.NamespaceToolParam(Tool, discriminator='namespace'): - description: str - name: str - tools: list[Union[FunctionToolParam, CustomToolParam]] - type: Literal[ToolType.NAMESPACE] + class azure.ai.projects.models.ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator='code_interpreter'): + type: Literal[ToolChoiceParamType.CODE_INTERPRETER] @overload - def __init__( - self, - *, - description: str, - name: str, - tools: list[Union[FunctionToolParam, CustomToolParam]] - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.NoAuthenticationCredentials(BaseCredentials, discriminator='None'): - type: Literal[CredentialType.NONE] + class azure.ai.projects.models.ToolChoiceComputer(ToolChoiceParam, discriminator='computer'): + type: Literal[ToolChoiceParamType.COMPUTER] @overload def __init__(self) -> None: ... @@ -8138,25 +13661,18 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OneTimeTrigger(Trigger, discriminator='OneTime'): - time_zone: Optional[str] - trigger_at: datetime - type: Literal[TriggerType.ONE_TIME] + class azure.ai.projects.models.ToolChoiceComputerUse(ToolChoiceParam, discriminator='computer_use'): + type: Literal[ToolChoiceParamType.COMPUTER_USE] @overload - def __init__( - self, - *, - time_zone: Optional[str] = ..., - trigger_at: datetime - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAnonymousAuthDetails(OpenApiAuthDetails, discriminator='anonymous'): - type: Literal[OpenApiAuthType.ANONYMOUS] + class azure.ai.projects.models.ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator='computer_use_preview'): + type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] @overload def __init__(self) -> None: ... @@ -8165,854 +13681,816 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAuthDetails(_Model): - type: str + class azure.ai.projects.models.ToolChoiceCustom(ToolChoiceParam, discriminator='custom'): + name: str + type: Literal[ToolChoiceParamType.CUSTOM] @overload def __init__( self, *, - type: str + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ANONYMOUS = "anonymous" - MANAGED_IDENTITY = "managed_identity" - PROJECT_CONNECTION = "project_connection" + class azure.ai.projects.models.ToolChoiceFileSearch(ToolChoiceParam, discriminator='file_search'): + type: Literal[ToolChoiceParamType.FILE_SEARCH] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.OpenApiFunctionDefinition(_Model): - auth: OpenApiAuthDetails - default_params: Optional[list[str]] - description: Optional[str] - functions: Optional[list[OpenApiFunctionDefinitionFunction]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ToolChoiceFunction(ToolChoiceParam, discriminator='function'): name: str - spec: dict[str, Any] + type: Literal[ToolChoiceParamType.FUNCTION] @overload def __init__( self, *, - auth: OpenApiAuthDetails, - default_params: Optional[list[str]] = ..., - description: Optional[str] = ..., - name: str, - spec: dict[str, Any] + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiFunctionDefinitionFunction(_Model): - description: Optional[str] - name: str - parameters: dict[str, Any] + class azure.ai.projects.models.ToolChoiceImageGeneration(ToolChoiceParam, discriminator='image_generation'): + type: Literal[ToolChoiceParamType.IMAGE_GENERATION] @overload - def __init__( - self, - *, - description: Optional[str] = ..., - name: str, - parameters: dict[str, Any] - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiManagedAuthDetails(OpenApiAuthDetails, discriminator='managed_identity'): - security_scheme: OpenApiManagedSecurityScheme - type: Literal[OpenApiAuthType.MANAGED_IDENTITY] + class azure.ai.projects.models.ToolChoiceMCP(ToolChoiceParam, discriminator='mcp'): + name: Optional[str] + server_label: str + type: Literal[ToolChoiceParamType.MCP] @overload def __init__( self, *, - security_scheme: OpenApiManagedSecurityScheme + name: Optional[str] = ..., + server_label: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiManagedSecurityScheme(_Model): - audience: str + class azure.ai.projects.models.ToolChoiceOptions(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + NONE = "none" + REQUIRED = "required" + + + class azure.ai.projects.models.ToolChoiceParam(_Model): + type: str @overload def __init__( self, *, - audience: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiProjectConnectionAuthDetails(OpenApiAuthDetails, discriminator='project_connection'): - security_scheme: OpenApiProjectConnectionSecurityScheme - type: Literal[OpenApiAuthType.PROJECT_CONNECTION] + class azure.ai.projects.models.ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWED_TOOLS = "allowed_tools" + APPLY_PATCH = "apply_patch" + CODE_INTERPRETER = "code_interpreter" + COMPUTER = "computer" + COMPUTER_USE = "computer_use" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FILE_SEARCH = "file_search" + FUNCTION = "function" + IMAGE_GENERATION = "image_generation" + MCP = "mcp" + PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" + SHELL = "shell" + WEB_SEARCH_PREVIEW = "web_search_preview" + WEB_SEARCH_PREVIEW_2025_03_11 = "web_search_preview_2025_03_11" + + + class azure.ai.projects.models.ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator='web_search_preview'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] @overload - def __init__( - self, - *, - security_scheme: OpenApiProjectConnectionSecurityScheme - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiProjectConnectionSecurityScheme(_Model): - project_connection_id: str + class azure.ai.projects.models.ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator='web_search_preview_2025_03_11'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ToolConfig(_Model): + additional_search_text: Optional[str] + pin: Optional[bool] @overload def __init__( self, *, - project_connection_id: str + additional_search_text: Optional[str] = ..., + pin: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiTool(Tool, discriminator='openapi'): - openapi: OpenApiFunctionDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.OPENAPI] + class azure.ai.projects.models.ToolDescription(_Model): + description: Optional[str] + name: Optional[str] @overload def __init__( self, *, - openapi: OpenApiFunctionDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + description: Optional[str] = ..., + name: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiToolboxTool(ToolboxTool, discriminator='openapi'): - description: str - name: str - openapi: OpenApiFunctionDefinition - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.OPENAPI] + class azure.ai.projects.models.ToolDescriptionParam(TypedDict, total=False): + key "description": str + key "name": str + + + class azure.ai.projects.models.ToolProjectConnection(_Model): + project_connection_id: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - openapi: OpenApiFunctionDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + project_connection_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OperationState(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CANCELED = "Canceled" - FAILED = "Failed" - NOT_STARTED = "NotStarted" - RUNNING = "Running" - SUCCEEDED = "Succeeded" + class azure.ai.projects.models.ToolSearchExecutionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLIENT = "client" + SERVER = "server" - class azure.ai.projects.models.OptimizedAgentIdentifier(_Model): - agent_name: str - agent_version: Optional[str] + class azure.ai.projects.models.ToolSearchToolParam(Tool, discriminator='tool_search'): + description: Optional[str] + execution: Optional[Union[str, ToolSearchExecutionType]] + parameters: Optional[EmptyModelParam] + type: Literal[ToolType.TOOL_SEARCH] @overload def __init__( self, *, - agent_name: str, - agent_version: Optional[str] = ... + description: Optional[str] = ..., + execution: Optional[Union[str, ToolSearchExecutionType]] = ..., + parameters: Optional[EmptyModelParam] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OtlpTelemetryEndpoint(TelemetryEndpoint, discriminator='OTLP'): - auth: TelemetryEndpointAuth - data: Union[list[str, TelemetryDataKind]] - endpoint: str - kind: Literal[TelemetryEndpointKind.OTLP] - protocol: Union[str, TelemetryTransportProtocol] + class azure.ai.projects.models.ToolSearchToolboxTool(ToolboxTool, discriminator='toolbox_search'): + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.TOOLBOX_SEARCH] @overload def __init__( self, *, - auth: Optional[TelemetryEndpointAuth] = ..., - data: list[Union[str, TelemetryDataKind]], - endpoint: str, - protocol: Union[str, TelemetryTransportProtocol] + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PageOrder(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ASC = "asc" - DESC = "desc" + class azure.ai.projects.models.ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A_PREVIEW = "a2a_preview" + A2_A = "a2a" + 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 = "computer" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FABRIC_DATAAGENT_PREVIEW = "fabric_dataagent_preview" + FABRIC_IQ_PREVIEW = "fabric_iq_preview" + FILE_SEARCH = "file_search" + FUNCTION = "function" + IMAGE_GENERATION = "image_generation" + LOCAL_SHELL = "local_shell" + MCP = "mcp" + MEMORY_SEARCH_PREVIEW = "memory_search_preview" + NAMESPACE = "namespace" + OPENAPI = "openapi" + PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" + SHAREPOINT_GROUNDING_PREVIEW = "sharepoint_grounding_preview" + SHELL = "shell" + TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" + TOOL_SEARCH = "tool_search" + WEB_IQ_PREVIEW = "web_iq_preview" + WEB_SEARCH = "web_search" + WEB_SEARCH_PREVIEW = "web_search_preview" + WORK_IQ_PREVIEW = "work_iq_preview" - class azure.ai.projects.models.PendingUploadRequest(_Model): - connection_name: Optional[str] - pending_upload_id: Optional[str] - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + class azure.ai.projects.models.ToolUseFineTuningDataGenerationJobOptions(DataGenerationJobOptions, discriminator='tool_use'): + max_samples: int + model_options: DataGenerationModelOptions + train_split: float + type: Literal[DataGenerationJobType.TOOL_USE] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - pending_upload_id: Optional[str] = ..., - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PendingUploadResponse(_Model): - blob_reference: BlobReference - pending_upload_id: str - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.ToolboxObject(_Model): + default_version: str + id: str + name: str @overload def __init__( self, *, - blob_reference: BlobReference, - pending_upload_id: str, - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE], - version: Optional[str] = ... + default_version: str, + id: str, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PendingUploadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BLOB_REFERENCE = "BlobReference" - NONE = "None" - TEMPORARY_BLOB_REFERENCE = "TemporaryBlobReference" - - - class azure.ai.projects.models.ProceduralMemoryItem(MemoryItem, discriminator='procedural'): - content: str - kind: Literal[MemoryItemKind.PROCEDURAL] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.ToolboxPolicies(_Model): + rai_config: Optional[RaiConfig] @overload def __init__( self, *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + rai_config: Optional[RaiConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProgrammaticToolCallingParam(Tool, discriminator='programmatic_tool_calling'): - type: Literal[ToolType.PROGRAMMATIC_TOOL_CALLING] - - @overload - def __init__(self) -> None: ... - - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.PromotionInfo(_Model): - agent_name: str - agent_version: str - promoted_at: datetime + class azure.ai.projects.models.ToolboxSearchPreviewToolboxTool(ToolboxTool, discriminator='toolbox_search_preview'): + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] @overload def __init__( self, *, - agent_name: str, - agent_version: str, - promoted_at: datetime + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptAgentDefinition(AgentDefinition, discriminator='prompt'): - instructions: Optional[str] - kind: Literal[AgentKind.PROMPT] - model: str - rai_config: RaiConfig - reasoning: Optional[Reasoning] - structured_inputs: Optional[dict[str, StructuredInputDefinition]] - temperature: Optional[float] - text: Optional[PromptAgentDefinitionTextOptions] - tool_choice: Optional[Union[str, ToolChoiceParam]] - tools: Optional[list[Tool]] - top_p: Optional[float] + class azure.ai.projects.models.ToolboxShellContainerAutoEnvironment(ToolboxShellEnvironment, discriminator='container_auto'): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ToolboxShellNetworkPolicy] + skills: Optional[list[ContainerSkill]] + type: Literal["container_auto"] @overload def __init__( self, *, - instructions: Optional[str] = ..., - model: str, - rai_config: Optional[RaiConfig] = ..., - reasoning: Optional[Reasoning] = ..., - structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., - temperature: Optional[float] = ..., - text: Optional[PromptAgentDefinitionTextOptions] = ..., - tool_choice: Optional[Union[str, ToolChoiceParam]] = ..., - tools: Optional[list[Tool]] = ..., - top_p: Optional[float] = ... + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ToolboxShellNetworkPolicy] = ..., + skills: Optional[list[ContainerSkill]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptAgentDefinitionTextOptions(_Model): - format: Optional[TextResponseFormat] + class azure.ai.projects.models.ToolboxShellContainerReferenceEnvironment(ToolboxShellEnvironment, discriminator='container_reference'): + container_id: str + type: Literal["container_reference"] @overload def __init__( self, *, - format: Optional[TextResponseFormat] = ... + container_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='prompt'): - data_schema: dict[str, any] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - prompt_text: str - type: Literal[EvaluatorDefinitionType.PROMPT] + class azure.ai.projects.models.ToolboxShellEnvironment(_Model): + type: str @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - prompt_text: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptDataGenerationJobSource(DataGenerationJobSource, discriminator='prompt'): - description: str - prompt: str - type: Literal[DataGenerationJobSourceType.PROMPT] + class azure.ai.projects.models.ToolboxShellNetworkPolicy(_Model): + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - prompt: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='prompt'): - description: Optional[str] - prompt: str - type: Literal[EvaluatorGenerationJobSourceType.PROMPT] + class azure.ai.projects.models.ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator='disabled'): + type: Literal["disabled"] @overload - def __init__( - self, - *, - description: Optional[str] = ..., - prompt: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProtocolConfiguration(_Model): - a2a: Optional[A2AProtocolConfiguration] - activity: Optional[ActivityProtocolConfiguration] - invocations: Optional[InvocationsProtocolConfiguration] - invocations_ws: Optional[InvocationsWsProtocolConfiguration] - mcp: Optional[McpProtocolConfiguration] - responses: Optional[ResponsesProtocolConfiguration] + class azure.ai.projects.models.ToolboxSkill(_Model): + type: str @overload def __init__( self, *, - a2a: Optional[A2AProtocolConfiguration] = ..., - activity: Optional[ActivityProtocolConfiguration] = ..., - invocations: Optional[InvocationsProtocolConfiguration] = ..., - invocations_ws: Optional[InvocationsWsProtocolConfiguration] = ..., - mcp: Optional[McpProtocolConfiguration] = ..., - responses: Optional[ResponsesProtocolConfiguration] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProtocolVersionRecord(_Model): - protocol: Union[str, AgentEndpointProtocol] - version: str + class azure.ai.projects.models.ToolboxSkillReference(ToolboxSkill, discriminator='skill_reference'): + name: str + type: Literal["skill_reference"] + version: Optional[str] @overload def __init__( self, *, - protocol: Union[str, AgentEndpointProtocol], - version: str + name: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - APPROVED = "approved" - NOT_PUBLISHED = "not_published" - NO_APPROVAL_NEEDED = "no_approval_needed" - PENDING = "pending" - REJECTED = "rejected" - - - class azure.ai.projects.models.RaiConfig(_Model): - rai_policy_name: str + class azure.ai.projects.models.ToolboxTool(_Model): + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: str @overload def __init__( self, *, - rai_policy_name: str + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AUTO = "auto" - DEFAULT_2024_11_15 = "default-2024-11-15" + class azure.ai.projects.models.ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A_PREVIEW = "a2a_preview" + A2_A = "a2a" + AZURE_AI_SEARCH = "azure_ai_search" + BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" + CODE_INTERPRETER = "code_interpreter" + FABRIC_IQ_PREVIEW = "fabric_iq_preview" + FILE_SEARCH = "file_search" + MCP = "mcp" + OPENAPI = "openapi" + REMINDER_PREVIEW = "reminder_preview" + SHELL = "shell" + TOOLBOX_SEARCH = "toolbox_search" + TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" + WEB_IQ_PREVIEW = "web_iq_preview" + WEB_SEARCH = "web_search" + WORK_IQ_PREVIEW = "work_iq_preview" - class azure.ai.projects.models.RankingOptions(_Model): - hybrid_search: Optional[HybridSearchOptions] - ranker: Optional[Union[str, RankerVersionType]] - score_threshold: Optional[float] + class azure.ai.projects.models.ToolboxVersionObject(_Model): + created_at: datetime + description: Optional[str] + id: str + metadata: dict[str, str] + name: str + policies: Optional[ToolboxPolicies] + skills: Optional[list[ToolboxSkill]] + tools: list[ToolboxTool] + version: str @overload def __init__( self, *, - hybrid_search: Optional[HybridSearchOptions] = ..., - ranker: Optional[Union[str, RankerVersionType]] = ..., - score_threshold: Optional[float] = ... + created_at: datetime, + description: Optional[str] = ..., + id: str, + metadata: dict[str, str], + name: str, + policies: Optional[ToolboxPolicies] = ..., + skills: Optional[list[ToolboxSkill]] = ..., + tools: list[ToolboxTool], + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Reasoning(_Model): - context: Optional[Literal["auto", "current_turn", "all_turns"]] - effort: Optional[Union[str, ReasoningEffort]] - generate_summary: Optional[Literal["auto", "concise", "detailed"]] - mode: Optional[Union[str, ReasoningModeEnum]] - summary: Optional[Literal["auto", "concise", "detailed"]] + class azure.ai.projects.models.TracesDataGenerationJobOptions(DataGenerationJobOptions, discriminator='traces'): + max_samples: int + model_options: DataGenerationModelOptions + redact_private_content: Optional[bool] + train_split: float + type: Literal[DataGenerationJobType.TRACES] @overload def __init__( self, *, - context: Optional[Literal[auto, current_turn, all_turns]] = ..., - effort: Optional[Union[str, ReasoningEffort]] = ..., - generate_summary: Optional[Literal[auto, concise, detailed]] = ..., - mode: Optional[Union[str, ReasoningModeEnum]] = ..., - summary: Optional[Literal[auto, concise, detailed]] = ... + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + redact_private_content: Optional[bool] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MAX = "max" - MEDIUM = "medium" - MINIMAL = "minimal" - NONE = "none" - XHIGH = "xhigh" - - - class azure.ai.projects.models.ReasoningModeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): - PRO = "pro" - STANDARD = "standard" - - - class azure.ai.projects.models.RecurrenceSchedule(_Model): - type: str + class azure.ai.projects.models.TracesDataGenerationJobSource(DataGenerationJobSource, discriminator='traces'): + agent_id: Optional[str] + agent_name: Optional[str] + agent_version: Optional[str] + description: str + end_time: Optional[datetime] + start_time: datetime + type: Literal[DataGenerationJobSourceType.TRACES] @overload def __init__( self, *, - type: str + agent_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + agent_version: Optional[str] = ..., + description: Optional[str] = ..., + end_time: Optional[datetime] = ..., + start_time: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RecurrenceTrigger(Trigger, discriminator='Recurrence'): + class azure.ai.projects.models.TracesEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='traces'): + agent_id: Optional[str] + agent_name: Optional[str] + agent_version: Optional[str] + description: Optional[str] end_time: Optional[datetime] - interval: int - schedule: RecurrenceSchedule - start_time: Optional[datetime] - time_zone: Optional[str] - type: Literal[TriggerType.RECURRENCE] + start_time: datetime + type: Literal[EvaluatorGenerationJobSourceType.TRACES] @overload def __init__( self, *, + agent_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + agent_version: Optional[str] = ..., + description: Optional[str] = ..., end_time: Optional[datetime] = ..., - interval: int, - schedule: RecurrenceSchedule, - start_time: Optional[datetime] = ..., - time_zone: Optional[str] = ... + start_time: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RecurrenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DAILY = "Daily" - HOURLY = "Hourly" - MONTHLY = "Monthly" - WEEKLY = "Weekly" + class azure.ai.projects.models.TracesPreviewEvalRunDataSource(TypedDict, total=False): + key "agent_id": str + key "agent_name": str + key "end_time": datetime + key "ingestion_delay_seconds": int + key "lookback_hours": int + key "max_traces": int + key "trace_ids": List[str] + key "type": Required[Literal["azure_ai_traces_preview"]] - class azure.ai.projects.models.RedTeam(_Model): - application_scenario: Optional[str] - attack_strategies: Optional[list[Union[str, AttackStrategy]]] - display_name: Optional[str] - name: str - num_turns: Optional[int] - properties: Optional[dict[str, str]] - risk_categories: Optional[list[Union[str, RiskCategory]]] - simulation_only: Optional[bool] - status: Optional[str] - tags: Optional[dict[str, str]] - target: RedTeamTargetConfig + class azure.ai.projects.models.TranscriptTextUsageDuration(CreateTranscriptionResponseJsonUsage, discriminator='duration'): + seconds: timedelta + type: Literal[CreateTranscriptionResponseJsonUsageType.DURATION] @overload def __init__( self, *, - application_scenario: Optional[str] = ..., - attack_strategies: Optional[list[Union[str, AttackStrategy]]] = ..., - display_name: Optional[str] = ..., - num_turns: Optional[int] = ..., - properties: Optional[dict[str, str]] = ..., - risk_categories: Optional[list[Union[str, RiskCategory]]] = ..., - simulation_only: Optional[bool] = ..., - tags: Optional[dict[str, str]] = ..., - target: RedTeamTargetConfig + seconds: timedelta ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RedTeamEvalRunDataSource(TypedDict, total=False): - key "item_generation_params": Required[Any] - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_red_team"]] - - - class azure.ai.projects.models.RedTeamTargetConfig(_Model): - type: str + class azure.ai.projects.models.TranscriptTextUsageTokens(CreateTranscriptionResponseJsonUsage, discriminator='tokens'): + input_token_details: Optional[TranscriptTextUsageTokensInputTokenDetails] + input_tokens: int + output_tokens: int + total_tokens: int + type: Literal[CreateTranscriptionResponseJsonUsageType.TOKENS] @overload def __init__( self, *, - type: str + input_token_details: Optional[TranscriptTextUsageTokensInputTokenDetails] = ..., + input_tokens: int, + output_tokens: int, + total_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ReminderPreviewToolboxTool(ToolboxTool, discriminator='reminder_preview'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.REMINDER_PREVIEW] + class azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails(_Model): + audio_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + audio_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponseRetrievalItemGenerationParams(TypedDict, total=False): - key "data_mapping": Required[Dict[str, str]] - key "max_num_turns": int - key "source": Required[Union[SourceFileContent, SourceFileID]] - key "type": Required[Literal["response_retrieval"]] - - - class azure.ai.projects.models.ResponseUsageInputTokensDetails(_Model): - cache_write_tokens: int - cached_tokens: int + class azure.ai.projects.models.TranscriptionLanguage(_Model): + code: str @overload def __init__( self, *, - cache_write_tokens: int, - cached_tokens: int + code: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponseUsageOutputTokensDetails(_Model): - reasoning_tokens: int + class azure.ai.projects.models.TreatmentEffectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHANGED = "Changed" + DEGRADED = "Degraded" + IMPROVED = "Improved" + INCONCLUSIVE = "Inconclusive" + TOO_FEW_SAMPLES = "TooFewSamples" + + + class azure.ai.projects.models.Trigger(_Model): + type: str @overload def __init__( self, *, - reasoning_tokens: int + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponsesProtocolConfiguration(_Model): - - - class azure.ai.projects.models.RiskCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE_VULNERABILITY = "CodeVulnerability" - HATE_UNFAIRNESS = "HateUnfairness" - PROHIBITED_ACTIONS = "ProhibitedActions" - PROTECTED_MATERIAL = "ProtectedMaterial" - SELF_HARM = "SelfHarm" - SENSITIVE_DATA_LEAKAGE = "SensitiveDataLeakage" - SEXUAL = "Sexual" - TASK_ADHERENCE = "TaskAdherence" - UNGROUNDED_ATTRIBUTES = "UngroundedAttributes" - VIOLENCE = "Violence" + class azure.ai.projects.models.TriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CRON = "Cron" + ONE_TIME = "OneTime" + RECURRENCE = "Recurrence" - class azure.ai.projects.models.Routine(_Model): - action: Optional[RoutineAction] - created_at: Optional[datetime] - description: Optional[str] - enabled: bool - name: Optional[str] - triggers: Optional[dict[str, RoutineTrigger]] - updated_at: Optional[datetime] + class azure.ai.projects.models.TwilioTelephonyBinding(TelephonyBinding, discriminator='twilio'): + connection: str + id: str + incoming_call_url: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - action: Optional[RoutineAction] = ..., - created_at: Optional[datetime] = ..., - description: Optional[str] = ..., - enabled: bool, - name: Optional[str] = ..., - triggers: Optional[dict[str, RoutineTrigger]] = ..., - updated_at: Optional[datetime] = ... + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineAction(_Model): - type: str + class azure.ai.projects.models.TwilioTelephonyBindingListItem(TelephonyBindingListItem, discriminator='twilio'): + connection: str + etag: str + id: str + incoming_call_url: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - type: str + connection: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" - INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" - + class azure.ai.projects.models.UpdateMemoriesLROPoller(LROPoller[MemoryStoreUpdateCompletedResult]): + property superseded_by: Optional[str] # Read-only + property update_id: str # Read-only - class azure.ai.projects.models.RoutineAttemptSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVENT_FIRE = "event_fire" - MANUAL_DISPATCH = "manual_dispatch" - QUEUED_DISPATCH = "queued_dispatch" - SCHEDULE_DELIVERY = "schedule_delivery" - TIMER_DELIVERY = "timer_delivery" + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[MemoryStoreUpdateCompletedResult], + continuation_token: str, + **kwargs: Any + ) -> UpdateMemoriesLROPoller: ... - class azure.ai.projects.models.RoutineAuthorization(_Model): - identity: Optional[Union[str, RoutineDispatchIdentity]] + class azure.ai.projects.models.UpdateModelVersionRequest(_Model): + description: Optional[str] + tags: Optional[dict[str, str]] @overload def __init__( self, *, - identity: Optional[Union[str, RoutineDispatchIdentity]] = ... + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineDispatchIdentity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - CREATOR = "creator" - - - class azure.ai.projects.models.RoutineDispatchPayload(_Model): - type: str + class azure.ai.projects.models.UpdateTelephonyBindingRequest(_Model): + connection: Optional[str] + label: Optional[str] + phone_number: Optional[str] + status: Optional[Union[str, TelephonyBindingStatus]] @overload def __init__( self, *, - type: str + connection: Optional[str] = ..., + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineDispatchPayloadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" - INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" - - - class azure.ai.projects.models.RoutineRun(_Model): - action_correlation_id: Optional[str] - action_type: Optional[Union[str, RoutineActionType]] - agent_endpoint_id: Optional[str] - agent_id: Optional[str] - attempt_source: Optional[Union[str, RoutineAttemptSource]] - conversation_id: Optional[str] - dispatch_id: Optional[str] - ended_at: Optional[datetime] - error_message: Optional[str] - error_status_code: Optional[int] - error_type: Optional[str] - id: str - phase: Optional[Union[str, RoutineRunPhase]] - response_id: Optional[str] - scheduled_fire_at: Optional[datetime] - session_id: Optional[str] - started_at: Optional[datetime] - status: Optional[RoutineRunStatus] - task_id: Optional[str] - trigger_event_payload: Optional[dict[str, Any]] - trigger_name: Optional[str] - trigger_type: Optional[Union[str, RoutineTriggerType]] - triggered_at: Optional[datetime] + class azure.ai.projects.models.UpdateToolboxRequest(_Model): + default_version: str @overload def __init__( self, *, - action_correlation_id: Optional[str] = ..., - action_type: Optional[Union[str, RoutineActionType]] = ..., - agent_endpoint_id: Optional[str] = ..., - agent_id: Optional[str] = ..., - attempt_source: Optional[Union[str, RoutineAttemptSource]] = ..., - conversation_id: Optional[str] = ..., - dispatch_id: Optional[str] = ..., - ended_at: Optional[datetime] = ..., - error_message: Optional[str] = ..., - error_status_code: Optional[int] = ..., - error_type: Optional[str] = ..., - phase: Optional[Union[str, RoutineRunPhase]] = ..., - response_id: Optional[str] = ..., - scheduled_fire_at: Optional[datetime] = ..., - session_id: Optional[str] = ..., - started_at: Optional[datetime] = ..., - status: Optional[RoutineRunStatus] = ..., - task_id: Optional[str] = ..., - trigger_event_payload: Optional[dict[str, Any]] = ..., - trigger_name: Optional[str] = ..., - trigger_type: Optional[Union[str, RoutineTriggerType]] = ..., - triggered_at: Optional[datetime] = ... + default_version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineRunPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): - COMPLETED = "completed" - DISPATCHING = "dispatching" - FAILED = "failed" - QUEUED = "queued" + class azure.ai.projects.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: ... - class azure.ai.projects.models.RoutineTrigger(_Model): + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.VersionIndicator(_Model): type: str @overload @@ -9026,1170 +14504,1564 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineTriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CUSTOM = "custom" - GITHUB_ISSUE = "github_issue" - SCHEDULE = "schedule" - TIMER = "timer" + class azure.ai.projects.models.VersionIndicatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + VERSION_REF = "version_ref" - class azure.ai.projects.models.RubricBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='rubric'): - data_schema: dict[str, any] - dimensions: list[Dimension] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - pass_threshold: Optional[float] - type: Literal[EvaluatorDefinitionType.RUBRIC] + class azure.ai.projects.models.VersionRefIndicator(VersionIndicator, discriminator='version_ref'): + agent_version: str + type: Literal[VersionIndicatorType.VERSION_REF] @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - dimensions: list[Dimension], - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - pass_threshold: Optional[float] = ... + agent_version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarning(_Model): - code: Union[str, RubricGenerationInputQualityWarningCode] - message: str - severity: Union[str, RubricGenerationInputQualityWarningSeverity] - source: Union[str, RubricGenerationInputQualityWarningSource] - source_index: Optional[int] + class azure.ai.projects.models.VersionSelectionRule(_Model): + agent_version: str + type: str @overload def __init__( self, *, - code: Union[str, RubricGenerationInputQualityWarningCode], - message: str, - severity: Union[str, RubricGenerationInputQualityWarningSeverity], - source: Union[str, RubricGenerationInputQualityWarningSource], - source_index: Optional[int] = ... + agent_version: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EMPTY_AGENT_INSTRUCTIONS = "empty_agent_instructions" - EMPTY_DATASET_CONTENT = "empty_dataset_content" - EMPTY_PROMPT = "empty_prompt" - INSUFFICIENT_TOTAL_INPUT = "insufficient_total_input" - LOW_TRACE_COUNT = "low_trace_count" - SHORT_AGENT_INSTRUCTIONS = "short_agent_instructions" - SHORT_DATASET_CONTENT = "short_dataset_content" - SHORT_PROMPT = "short_prompt" + class azure.ai.projects.models.VersionSelector(_Model): + version_selection_rules: list[VersionSelectionRule] + @overload + def __init__( + self, + *, + version_selection_rules: list[VersionSelectionRule] + ) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - WARNING = "warning" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarningSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - AGGREGATE = "aggregate" - DATASET = "dataset" - PROMPT = "prompt" + class azure.ai.projects.models.VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FIXED_RATIO = "FixedRatio" - class azure.ai.projects.models.SASCredentials(BaseCredentials, discriminator='SAS'): - sas_token: Optional[str] - type: Literal[CredentialType.SAS] + class azure.ai.projects.models.VoiceAgentAnimationConfig(_Model): + model_name: Optional[str] + outputs: Optional[list[Union[str, VoiceAgentAnimationOutputType]]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + model_name: Optional[str] = ..., + outputs: Optional[list[Union[str, VoiceAgentAnimationOutputType]]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SampleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION_RESULT_SAMPLE = "EvaluationResultSample" + class azure.ai.projects.models.VoiceAgentAnimationOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BLENDSHAPES = "blendshapes" + VISEME_ID = "viseme_id" - class azure.ai.projects.models.Schedule(_Model): - description: Optional[str] - display_name: Optional[str] - enabled: bool - properties: Optional[dict[str, str]] - provisioning_status: Optional[Union[str, ScheduleProvisioningStatus]] - schedule_id: str - system_data: dict[str, str] - tags: Optional[dict[str, str]] - task: ScheduleTask - trigger: Trigger + class azure.ai.projects.models.VoiceAgentAudioConfig(_Model): + input: Optional[VoiceAgentAudioInputConfig] + output: Optional[VoiceAgentAudioOutputConfig] @overload def __init__( self, *, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - enabled: bool, - properties: Optional[dict[str, str]] = ..., - tags: Optional[dict[str, str]] = ..., - task: ScheduleTask, - trigger: Trigger + input: Optional[VoiceAgentAudioInputConfig] = ..., + output: Optional[VoiceAgentAudioOutputConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleProvisioningStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CREATING = "Creating" - DELETING = "Deleting" - FAILED = "Failed" - SUCCEEDED = "Succeeded" - UPDATING = "Updating" - - - class azure.ai.projects.models.ScheduleRoutineTrigger(RoutineTrigger, discriminator='schedule'): - cron_expression: str - time_zone: str - type: Literal[RoutineTriggerType.SCHEDULE] + class azure.ai.projects.models.VoiceAgentAudioInputConfig(_Model): + echo_cancellation: Optional[VoiceAgentEchoCancellation] + format: Optional[RealtimeAudioFormats] + noise_reduction: Optional[VoiceAgentNoiseReduction] + transcription: Optional[VoiceAgentInputTranscription] + turn_detection: Optional[VoiceAgentTurnDetectionConfig] @overload def __init__( self, *, - cron_expression: str, - time_zone: str + echo_cancellation: Optional[VoiceAgentEchoCancellation] = ..., + format: Optional[RealtimeAudioFormats] = ..., + noise_reduction: Optional[VoiceAgentNoiseReduction] = ..., + transcription: Optional[VoiceAgentInputTranscription] = ..., + turn_detection: Optional[VoiceAgentTurnDetectionConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleRun(_Model): - error: Optional[str] - properties: dict[str, str] - run_id: str - schedule_id: str - success: bool - trigger_time: Optional[datetime] + class azure.ai.projects.models.VoiceAgentAudioOutputConfig(_Model): + custom_lexicon_url: Optional[str] + custom_text_normalization_url: Optional[str] + custom_voice_endpoint_id: Optional[str] + format: Optional[RealtimeAudioFormats] + output_audio_timestamp_types: Optional[list[Union[str, VoiceAgentAudioTimestampType]]] + personal_voice_model: Optional[str] + pitch: Optional[str] + prefer_locales: Optional[list[str]] + speed: Optional[float] + style: Optional[str] + voice: Optional[str] + voice_locale: Optional[str] + voice_temperature: Optional[float] + voice_type: Optional[Union[str, VoiceType]] + volume: Optional[str] @overload def __init__( self, *, - schedule_id: str, - trigger_time: Optional[datetime] = ... + custom_lexicon_url: Optional[str] = ..., + custom_text_normalization_url: Optional[str] = ..., + custom_voice_endpoint_id: Optional[str] = ..., + format: Optional[RealtimeAudioFormats] = ..., + output_audio_timestamp_types: Optional[list[Union[str, VoiceAgentAudioTimestampType]]] = ..., + personal_voice_model: Optional[str] = ..., + pitch: Optional[str] = ..., + prefer_locales: Optional[list[str]] = ..., + speed: Optional[float] = ..., + style: Optional[str] = ..., + voice: Optional[str] = ..., + voice_locale: Optional[str] = ..., + voice_temperature: Optional[float] = ..., + voice_type: Optional[Union[str, VoiceType]] = ..., + volume: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleTask(_Model): - configuration: Optional[dict[str, str]] - type: str + class azure.ai.projects.models.VoiceAgentAudioTimestampType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WORD = "word" + + + class azure.ai.projects.models.VoiceAgentAvatarConfig(_Model): + character: str + customized: Optional[bool] + model: Optional[str] + output_audit_audio: Optional[bool] + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] + scene: Optional[VoiceAgentAvatarScene] + style: Optional[str] + type: Union[str, VoiceAgentAvatarType] + video: Optional[VoiceAgentAvatarVideoParams] @overload def __init__( self, *, - configuration: Optional[dict[str, str]] = ..., - type: str + character: str, + customized: Optional[bool] = ..., + model: Optional[str] = ..., + output_audit_audio: Optional[bool] = ..., + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] = ..., + scene: Optional[VoiceAgentAvatarScene] = ..., + style: Optional[str] = ..., + type: Union[str, VoiceAgentAvatarType], + video: Optional[VoiceAgentAvatarVideoParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleTaskType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION = "Evaluation" - INSIGHT = "Insight" + class azure.ai.projects.models.VoiceAgentAvatarIceServer(_Model): + credential: Optional[str] + urls: list[str] + username: Optional[str] + @overload + def __init__( + self, + *, + credential: Optional[str] = ..., + urls: list[str], + username: Optional[str] = ... + ) -> None: ... - class azure.ai.projects.models.SearchContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - IMAGE = "image" - TEXT = "text" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SearchContextSize(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MEDIUM = "medium" + class azure.ai.projects.models.VoiceAgentAvatarOutputProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WEBRTC = "webrtc" + WEBSOCKET = "websocket" - class azure.ai.projects.models.SessionConfiguration(_Model): - idle_timeout_seconds: Optional[timedelta] + class azure.ai.projects.models.VoiceAgentAvatarScene(_Model): + amplitude: Optional[float] + position_x: Optional[float] + position_y: Optional[float] + rotation_x: Optional[float] + rotation_y: Optional[float] + rotation_z: Optional[float] + zoom: Optional[float] @overload def __init__( self, *, - idle_timeout_seconds: Optional[timedelta] = ... + amplitude: Optional[float] = ..., + position_x: Optional[float] = ..., + position_y: Optional[float] = ..., + rotation_x: Optional[float] = ..., + rotation_y: Optional[float] = ..., + rotation_z: Optional[float] = ..., + zoom: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionDirectoryEntry(_Model): - is_directory: bool - modified_time: datetime - name: str - size: int + class azure.ai.projects.models.VoiceAgentAvatarType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PHOTO_AVATAR = "photo_avatar" + VIDEO_AVATAR = "video_avatar" + + + class azure.ai.projects.models.VoiceAgentAvatarVideoBackground(_Model): + color: Optional[str] + image_url: Optional[str] @overload def __init__( self, *, - is_directory: bool, - modified_time: datetime, - name: str, - size: int + color: Optional[str] = ..., + image_url: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionFileWriteResult(_Model): - bytes_written: int - path: str + class azure.ai.projects.models.VoiceAgentAvatarVideoCrop(_Model): + bottom_right: list[int] + top_left: list[int] @overload def __init__( self, *, - bytes_written: int, - path: str + bottom_right: list[int], + top_left: list[int] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionLogEvent(_Model): - data: str - event: Union[str, SessionLogEventType] + class azure.ai.projects.models.VoiceAgentAvatarVideoParams(_Model): + background: Optional[VoiceAgentAvatarVideoBackground] + bitrate: Optional[int] + crop: Optional[VoiceAgentAvatarVideoCrop] + gop_size: Optional[int] + resolution: Optional[VoiceAgentAvatarVideoResolution] @overload def __init__( self, *, - data: str, - event: Union[str, SessionLogEventType] + background: Optional[VoiceAgentAvatarVideoBackground] = ..., + bitrate: Optional[int] = ..., + crop: Optional[VoiceAgentAvatarVideoCrop] = ..., + gop_size: Optional[int] = ..., + resolution: Optional[VoiceAgentAvatarVideoResolution] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionLogEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LOG = "log" - - - class azure.ai.projects.models.SharepointGroundingToolParameters(_Model): - project_connections: Optional[list[ToolProjectConnection]] + class azure.ai.projects.models.VoiceAgentAvatarVideoResolution(_Model): + height: int + width: int @overload def __init__( self, *, - project_connections: Optional[list[ToolProjectConnection]] = ... + height: int, + width: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SharepointPreviewTool(Tool, discriminator='sharepoint_grounding_preview'): - sharepoint_grounding_preview: SharepointGroundingToolParameters - type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] + class azure.ai.projects.models.VoiceAgentAzureSemanticVadEnTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad_en'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN] @overload def __init__( self, *, - sharepoint_grounding_preview: SharepointGroundingToolParameters + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ShellToolboxTool(ToolboxTool, discriminator='shell'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - description: str - environment: ToolboxShellEnvironment - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.SHELL] + class azure.ai.projects.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad_multilingual'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + languages: Optional[list[str]] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - description: Optional[str] = ..., - environment: ToolboxShellEnvironment, - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + languages: Optional[list[str]] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.SimpleQnADataGenerationJobOptions(DataGenerationJobOptions, discriminator='simple_qna'): - max_samples: int - model_options: DataGenerationModelOptions - question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] - train_split: float - type: Literal[DataGenerationJobType.SIMPLE_QNA] + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.VoiceAgentAzureSemanticVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + languages: Optional[list[str]] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] = ..., - train_split: Optional[float] = ... + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + languages: Optional[list[str]] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SimpleQnAFineTuningQuestionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LONG_ANSWER = "long_answer" - SHORT_ANSWER = "short_answer" - - - class azure.ai.projects.models.SimulationSeedDataGenerationJobOptions(DataGenerationJobOptions, discriminator='simulation_seed'): - max_samples: int - model_options: DataGenerationModelOptions - train_split: float - type: Literal[DataGenerationJobType.SIMULATION_SEED] + class azure.ai.projects.models.VoiceAgentClientEventRtcCallSdpCreate(RealtimeClientEvent, discriminator='rtc.call.sdp.create'): + event_id: Optional[str] + sdp_offer: str + session: Optional[VoiceAgentSessionUpdateConfig] + type: Literal[RealtimeClientEventType.RTC_CALL_SDP_CREATE] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ... + event_id: Optional[str] = ..., + sdp_offer: str, + session: Optional[VoiceAgentSessionUpdateConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillDetails(_Model): - created_at: datetime - default_version: str - description: str - id: str - latest_version: str - name: str + class azure.ai.projects.models.VoiceAgentClientEventSessionAvatarConnect(RealtimeClientEvent, discriminator='session.avatar.connect'): + client_sdp: str + event_id: Optional[str] + type: Literal[RealtimeClientEventType.SESSION_AVATAR_CONNECT] @overload def __init__( self, *, - created_at: datetime, - default_version: str, - description: str, - id: str, - latest_version: str, - name: str + client_sdp: str, + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillInlineContent(_Model): - allowed_tools: Optional[list[str]] - compatibility: Optional[str] - description: str - instructions: str - license: Optional[str] - metadata: Optional[dict[str, str]] + class azure.ai.projects.models.VoiceAgentClientEventSessionUpdate(_Model): + event_id: Optional[str] + session: VoiceAgentSessionUpdateConfig + type: Literal[RealtimeClientEventType.SESSION_UPDATE] @overload def __init__( self, *, - allowed_tools: Optional[list[str]] = ..., - compatibility: Optional[str] = ..., - description: str, - instructions: str, - license: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ... + event_id: Optional[str] = ..., + session: VoiceAgentSessionUpdateConfig, + type: Literal[RealtimeClientEventType.SESSION_UPDATE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillReferenceParam(ContainerSkill, discriminator='skill_reference'): - skill_id: str - type: Literal[ContainerSkillType.SKILL_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.VoiceAgentDefinition(AgentDefinition, discriminator='voice'): + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentAvatarConfig] + conversation_engine: Optional[VoiceConversationEngine] + greeting: Optional[VoiceAgentGreetingConfig] + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + kind: Literal[AgentKind.VOICE] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + model: Optional[str] + model_type: Optional[Union[str, VoiceModelType]] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + rai_config: RaiConfig + store: Optional[bool] + structured_inputs: Optional[dict[str, StructuredInputDefinition]] + subagent_config: Optional[VoiceAgentSubagentConfig] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] @overload def __init__( self, *, - skill_id: str, - version: Optional[str] = ... + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentAvatarConfig] = ..., + conversation_engine: Optional[VoiceConversationEngine] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + model: Optional[str] = ..., + model_type: Optional[Union[str, VoiceModelType]] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + rai_config: Optional[RaiConfig] = ..., + store: Optional[bool] = ..., + structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., + subagent_config: Optional[VoiceAgentSubagentConfig] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillVersion(_Model): - created_at: datetime - description: str - id: str - name: str - skill_id: str - version: str + class azure.ai.projects.models.VoiceAgentEchoCancellation(_Model): + channels: Optional[int] + reference_source: Optional[Union[str, VoiceAgentEchoCancellationReferenceSource]] + type: Literal["server_echo_cancellation"] @overload def __init__( self, *, - created_at: datetime, - description: str, - id: str, - name: str, - skill_id: str, - version: str + channels: Optional[int] = ..., + reference_source: Optional[Union[str, VoiceAgentEchoCancellationReferenceSource]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SpecificApplyPatchParam(ToolChoiceParam, discriminator='apply_patch'): - type: Literal[ToolChoiceParamType.APPLY_PATCH] + class azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLIENT = "client" + SERVER = "server" + + + class azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection(_Model): + model: Union[str, VoiceAgentEndOfUtteranceDetectionModel] + threshold_level: Optional[Union[str, VoiceAgentEndOfUtteranceThresholdLevel]] + timeout_ms: Optional[timedelta] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + model: Union[str, VoiceAgentEndOfUtteranceDetectionModel], + threshold_level: Optional[Union[str, VoiceAgentEndOfUtteranceThresholdLevel]] = ..., + timeout_ms: Optional[timedelta] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SpecificFunctionShellParam(ToolChoiceParam, discriminator='shell'): - type: Literal[ToolChoiceParamType.SHELL] + class azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SEMANTIC_DETECTION_V1 = "semantic_detection_v1" + SEMANTIC_DETECTION_V1_EN = "semantic_detection_v1_en" + SEMANTIC_DETECTION_V1_MULTILINGUAL = "semantic_detection_v1_multilingual" + SMART_END_OF_TURN_DETECTION = "smart_end_of_turn_detection" - @overload - def __init__(self) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DEFAULT = "default" + HIGH = "high" + LOW = "low" + MEDIUM = "medium" - class azure.ai.projects.models.SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator='programmatic_tool_calling'): - type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] + class azure.ai.projects.models.VoiceAgentFunctionTool(VoiceAgentTool, discriminator='function'): + description: Optional[str] + name: str + parameters: Optional[RealtimeFunctionToolParameters] + type: Literal["function"] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + parameters: Optional[RealtimeFunctionToolParameters] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.StructuredInputDefinition(_Model): - default_value: Optional[Any] - description: Optional[str] - required: Optional[bool] - schema: Optional[dict[str, Any]] + class azure.ai.projects.models.VoiceAgentGreetingConfig(_Model): + type: str @overload def __init__( self, *, - default_value: Optional[Any] = ..., - description: Optional[str] = ..., - required: Optional[bool] = ..., - schema: Optional[dict[str, Any]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.StructuredOutputDefinition(_Model): - description: str - name: str - schema: dict[str, Any] - strict: bool + class azure.ai.projects.models.VoiceAgentInputTranscription(_Model): + custom_speech: Optional[dict[str, str]] + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] + keywords: Optional[list[str]] + language: Optional[str] + languages: Optional[list[str]] + model: Union[str, VoiceAgentInputTranscriptionModel] + phrase_list: Optional[list[str]] + prompt: Optional[str] @overload def __init__( self, *, - description: str, - name: str, - schema: dict[str, Any], - strict: bool + custom_speech: Optional[dict[str, str]] = ..., + delay: Optional[Literal[minimal, low, medium, high, xhigh]] = ..., + keywords: Optional[list[str]] = ..., + language: Optional[str] = ..., + languages: Optional[list[str]] = ..., + model: Union[str, VoiceAgentInputTranscriptionModel], + phrase_list: Optional[list[str]] = ..., + prompt: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TargetCompletionEvalRunDataSource(TypedDict, total=False): - key "input_messages": Required[InputMessagesItemReference] - key "source": Required[Union[SourceFileContent, SourceFileID]] - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_target_completions"]] + class azure.ai.projects.models.VoiceAgentInputTranscriptionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SPEECH = "azure-speech" + GPT4_O_MINI_TRANSCRIBE = "gpt-4o-mini-transcribe" + GPT4_O_TRANSCRIBE = "gpt-4o-transcribe" + GPT4_O_TRANSCRIBE_DIARIZE = "gpt-4o-transcribe-diarize" + GPT_LIVE_TRANSCRIBE = "gpt-live-transcribe" + GPT_REALTIME_WHISPER = "gpt-realtime-whisper" + GPT_TRANSCRIBE = "gpt-transcribe" + MAI_TRANSCRIBE = "mai-transcribe" + WHISPER1 = "whisper-1" - class azure.ai.projects.models.TaxonomyCategory(_Model): - description: Optional[str] - id: str - name: str - properties: Optional[dict[str, str]] - risk_category: Union[str, RiskCategory] - sub_categories: list[TaxonomySubCategory] + class azure.ai.projects.models.VoiceAgentInterimResponseConfig(_Model): + latency_threshold_ms: Optional[timedelta] + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - id: str, - name: str, - properties: Optional[dict[str, str]] = ..., - risk_category: Union[str, RiskCategory], - sub_categories: list[TaxonomySubCategory] + latency_threshold_ms: Optional[timedelta] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TaxonomySubCategory(_Model): - description: Optional[str] - enabled: bool - id: str - name: str - properties: Optional[dict[str, str]] + class azure.ai.projects.models.VoiceAgentInterimResponseTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LATENCY = "latency" + TOOL = "tool" + + + class azure.ai.projects.models.VoiceAgentLlmGeneratedGreetingConfig(VoiceAgentGreetingConfig, discriminator='llm_generated'): + prompt: str + tool_choice: Optional[VoiceAgentToolChoice] + type: Literal["llm_generated"] @overload def __init__( self, *, - description: Optional[str] = ..., - enabled: bool, - id: str, - name: str, - properties: Optional[dict[str, str]] = ... + prompt: str, + tool_choice: Optional[VoiceAgentToolChoice] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryConfig(_Model): - endpoints: list[TelemetryEndpoint] + class azure.ai.projects.models.VoiceAgentLlmInterimResponseConfig(VoiceAgentInterimResponseConfig, discriminator='llm_interim_response'): + instructions: Optional[str] + latency_threshold_ms: timedelta + max_completion_tokens: Optional[int] + model: Optional[str] + triggers: Union[list[str, VoiceAgentInterimResponseTrigger]] + type: Literal["llm_interim_response"] @overload def __init__( self, *, - endpoints: list[TelemetryEndpoint] + instructions: Optional[str] = ..., + latency_threshold_ms: Optional[timedelta] = ..., + max_completion_tokens: Optional[int] = ..., + model: Optional[str] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryDataKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTAINER_OTEL = "ContainerOtel" - CONTAINER_STDOUT_STDERR = "ContainerStdoutStderr" - METRICS = "Metrics" - - - class azure.ai.projects.models.TelemetryEndpoint(_Model): - auth: Optional[TelemetryEndpointAuth] - data: list[Union[str, TelemetryDataKind]] - kind: str + class azure.ai.projects.models.VoiceAgentMcpTool(VoiceAgentTool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + allowed_tools: Optional[Union[list[str], MCPToolFilter]] + authorization: Optional[str] + defer_loading: Optional[bool] + headers: Optional[dict[str, str]] + project_connection_id: Optional[str] + require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] + server_description: Optional[str] + server_label: str + server_url: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal["mcp"] @overload def __init__( self, *, - auth: Optional[TelemetryEndpointAuth] = ..., - data: list[Union[str, TelemetryDataKind]], - kind: str + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., + authorization: Optional[str] = ..., + defer_loading: Optional[bool] = ..., + headers: Optional[dict[str, str]] = ..., + project_connection_id: Optional[str] = ..., + require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] = ..., + server_description: Optional[str] = ..., + server_label: str, + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryEndpointAuth(_Model): - type: str + class azure.ai.projects.models.VoiceAgentNoiseReduction(_Model): + type: Union[str, VoiceAgentNoiseReductionType] @overload def __init__( self, *, - type: str + type: Union[str, VoiceAgentNoiseReductionType] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryEndpointAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HEADER = "header" - - - class azure.ai.projects.models.TelemetryEndpointKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - OTLP = "OTLP" + class azure.ai.projects.models.VoiceAgentNoiseReductionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_DEEP_NOISE_SUPPRESSION = "azure_deep_noise_suppression" + FAR_FIELD = "far_field" + NEAR_FIELD = "near_field" - class azure.ai.projects.models.TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GRPC = "Grpc" - HTTP = "Http" + class azure.ai.projects.models.VoiceAgentRealtimeResponse(VoiceAgentRealtimeResponseBase): + audio: Optional[VoiceResponseAudio] + conversation_id: str + id: str + max_output_tokens: Union[int, str] + metadata: Metadata + object: str + output: Optional[list[RealtimeConversationItem]] + output_modalities: Union[list[str, str]] + status: Union[str, str, str, str, str] + status_details: RealtimeResponseStatusDetails + usage: RealtimeResponseUsage + @overload + def __init__( + self, + *, + audio: Optional[VoiceResponseAudio] = ..., + conversation_id: Optional[str] = ..., + id: Optional[str] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + object: Optional[Literal[response]] = ..., + output: Optional[list[RealtimeConversationItem]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... + ) -> None: ... - class azure.ai.projects.models.TestingCriterionAzureAIEvaluator(TypedDict, total=False): - key "data_mapping": Dict[str, str] - key "evaluator_name": Required[str] - key "evaluator_version": str - key "initialization_parameters": Dict[str, Any] - key "name": Required[str] - key "type": Required[Literal["azure_ai_evaluator"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormat(_Model): - type: str + class azure.ai.projects.models.VoiceAgentRealtimeResponseBase(_Model): + conversation_id: Optional[str] + id: Optional[str] + max_output_tokens: Optional[Union[int, Literal["inf"]]] + metadata: Optional[Metadata] + object: Optional[Literal["response"]] + output_modalities: Optional[list[Literal["text", "audio"]]] + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] + status_details: Optional[RealtimeResponseStatusDetails] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, - type: str + conversation_id: Optional[str] = ..., + id: Optional[str] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + object: Optional[Literal[response]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - JSON_OBJECT = "json_object" - JSON_SCHEMA = "json_schema" - TEXT = "text" - - - class azure.ai.projects.models.TextResponseFormatJsonObject(TextResponseFormat, discriminator='json_object'): - type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] + class azure.ai.projects.models.VoiceAgentResponseCreateParams(_Model): + audio: Optional[PickPropertiesVoiceAgentAudioConfig] + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] + input: Optional[list[RealtimeConversationItem]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[Union[int, Literal["inf"]]] + metadata: Optional[Metadata] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + pre_generated_assistant_message: Optional[RealtimeConversationItem] + reasoning: Optional[RealtimeReasoning] + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceFunction, ToolChoiceMCP]] + tools: Optional[list[Union[RealtimeFunctionTool, MCPTool]]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio: Optional[PickPropertiesVoiceAgentAudioConfig] = ..., + conversation: Optional[Union[Literal[auto], Literal[none], str]] = ..., + input: Optional[list[RealtimeConversationItem]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + pre_generated_assistant_message: Optional[RealtimeConversationItem] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceFunction, ToolChoiceMCP]] = ..., + tools: Optional[list[Union[RealtimeFunctionTool, MCPTool]]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatJsonSchema(TextResponseFormat, discriminator='json_schema'): - description: Optional[str] - name: str - schema: dict[str, Any] - strict: Optional[bool] - type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] + class azure.ai.projects.models.VoiceAgentRtcCallErrorDetails(_Model): + code: Optional[str] + message: str + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - schema: dict[str, Any], - strict: Optional[bool] = ... + code: Optional[str] = ..., + message: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatText(TextResponseFormat, discriminator='text'): - type: Literal[TextResponseFormatConfigurationType.TEXT] + class azure.ai.projects.models.VoiceAgentSemanticVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='semantic_vad'): + auto_truncate: bool + create_response: Optional[bool] + eagerness: Optional[Literal["low", "medium", "high", "auto"]] + interrupt_response: Optional[bool] + type: Literal[VoiceAgentTurnDetectionType.SEMANTIC_VAD] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + eagerness: Optional[Literal[low, medium, high, auto]] = ..., + interrupt_response: Optional[bool] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TimerRoutineTrigger(RoutineTrigger, discriminator='timer'): - at: Optional[datetime] - type: Literal[RoutineTriggerType.TIMER] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDelta(RealtimeServerEvent, discriminator='response.animation_blendshapes.delta'): + content_index: int + event_id: str + frame_index: int + frames: list[list[float]] + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA] @overload def __init__( self, *, - at: Optional[datetime] = ... + content_index: int, + event_id: str, + frame_index: int, + frames: list[list[float]], + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Tool(_Model): - type: str + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDone(RealtimeServerEvent, discriminator='response.animation_blendshapes.done'): + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE] @overload def __init__( self, *, - type: str + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceAllowed(ToolChoiceParam, discriminator='allowed_tools'): - mode: Literal["auto", "required"] - tools: list[dict[str, Any]] - type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDelta(RealtimeServerEvent, discriminator='response.animation_viseme.delta'): + audio_offset_ms: timedelta + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA] + viseme_id: int @overload def __init__( self, *, - mode: Literal["auto", "required"], - tools: list[dict[str, Any]] + audio_offset_ms: timedelta, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + viseme_id: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator='code_interpreter'): - type: Literal[ToolChoiceParamType.CODE_INTERPRETER] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDone(RealtimeServerEvent, discriminator='response.animation_viseme.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputer(ToolChoiceParam, discriminator='computer'): - type: Literal[ToolChoiceParamType.COMPUTER] + class azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDelta(RealtimeServerEvent, discriminator='response.audio_timestamp.delta'): + audio_duration_ms: timedelta + audio_offset_ms: timedelta + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + text: str + timestamp_type: Literal["word"] + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_duration_ms: timedelta, + audio_offset_ms: timedelta, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + text: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputerUse(ToolChoiceParam, discriminator='computer_use'): - type: Literal[ToolChoiceParamType.COMPUTER_USE] + class azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDone(RealtimeServerEvent, discriminator='response.audio_timestamp.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator='computer_use_preview'): - type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] + class azure.ai.projects.models.VoiceAgentServerEventResponseVideoDelta(RealtimeServerEvent, discriminator='response.video.delta'): + codec: str + delta: str + event_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_VIDEO_DELTA] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + codec: str, + delta: str, + event_id: str, + output_index: int + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceCustom(ToolChoiceParam, discriminator='custom'): - name: str - type: Literal[ToolChoiceParamType.CUSTOM] + class azure.ai.projects.models.VoiceAgentServerEventRtcCallError(RealtimeServerEvent, discriminator='rtc.call.error'): + error: VoiceAgentRtcCallErrorDetails + event_id: Optional[str] + operation: Optional[str] + rtc_call_id: Optional[str] + type: Literal[RealtimeServerEventType.RTC_CALL_ERROR] @overload def __init__( self, *, - name: str + error: VoiceAgentRtcCallErrorDetails, + event_id: Optional[str] = ..., + operation: Optional[str] = ..., + rtc_call_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceFileSearch(ToolChoiceParam, discriminator='file_search'): - type: Literal[ToolChoiceParamType.FILE_SEARCH] + class azure.ai.projects.models.VoiceAgentServerEventRtcCallSdpCreated(RealtimeServerEvent, discriminator='rtc.call.sdp.created'): + event_id: str + rtc_call_id: str + sdp_answer: str + type: Literal[RealtimeServerEventType.RTC_CALL_SDP_CREATED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + rtc_call_id: str, + sdp_answer: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceFunction(ToolChoiceParam, discriminator='function'): - name: str - type: Literal[ToolChoiceParamType.FUNCTION] + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarConnecting(RealtimeServerEvent, discriminator='session.avatar.connecting'): + event_id: str + server_sdp: str + type: Literal[RealtimeServerEventType.SESSION_AVATAR_CONNECTING] @overload def __init__( self, *, - name: str + event_id: str, + server_sdp: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceImageGeneration(ToolChoiceParam, discriminator='image_generation'): - type: Literal[ToolChoiceParamType.IMAGE_GENERATION] + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToIdle(RealtimeServerEvent, discriminator='session.avatar.switch_to_idle'): + event_id: str + turn_id: Optional[str] + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + turn_id: Optional[str] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceMCP(ToolChoiceParam, discriminator='mcp'): - name: Optional[str] - server_label: str - type: Literal[ToolChoiceParamType.MCP] + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking(RealtimeServerEvent, discriminator='session.avatar.switch_to_speaking'): + event_id: str + turn_id: Optional[str] + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING] @overload def __init__( self, *, - name: Optional[str] = ..., - server_label: str + event_id: str, + turn_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceParam(_Model): - type: str + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentAborted(RealtimeServerEvent, discriminator='session.subagent.aborted'): + call_id: str + consultation_id: str + event_id: str + reason: Union[str, VoiceAgentSubagentAbortReason] + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_ABORTED] @overload def __init__( self, *, - type: str + call_id: str, + consultation_id: str, + event_id: str, + reason: Union[str, VoiceAgentSubagentAbortReason], + subagent_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ALLOWED_TOOLS = "allowed_tools" - APPLY_PATCH = "apply_patch" - CODE_INTERPRETER = "code_interpreter" - COMPUTER = "computer" - COMPUTER_USE = "computer_use" - COMPUTER_USE_PREVIEW = "computer_use_preview" - CUSTOM = "custom" - FILE_SEARCH = "file_search" - FUNCTION = "function" - IMAGE_GENERATION = "image_generation" - MCP = "mcp" - PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" - SHELL = "shell" - WEB_SEARCH_PREVIEW = "web_search_preview" - WEB_SEARCH_PREVIEW_2025_03_11 = "web_search_preview_2025_03_11" - - - class azure.ai.projects.models.ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator='web_search_preview'): - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentCompleted(RealtimeServerEvent, discriminator='session.subagent.completed'): + call_id: str + consultation_id: str + event_id: str + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + call_id: str, + consultation_id: str, + event_id: str, + subagent_name: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator='web_search_preview_2025_03_11'): - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentStarted(RealtimeServerEvent, discriminator='session.subagent.started'): + call_id: str + consultation_id: str + event_id: str + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_STARTED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + call_id: str, + consultation_id: str, + event_id: str, + subagent_name: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolConfig(_Model): - additional_search_text: Optional[str] - pin: Optional[bool] + class azure.ai.projects.models.VoiceAgentServerEventWarning(RealtimeServerEvent, discriminator='warning'): + event_id: str + type: Literal[RealtimeServerEventType.WARNING] + warning: VoiceAgentServerEventWarningDetails @overload def __init__( self, *, - additional_search_text: Optional[str] = ..., - pin: Optional[bool] = ... + event_id: str, + warning: VoiceAgentServerEventWarningDetails ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolDescription(_Model): - description: Optional[str] - name: Optional[str] + class azure.ai.projects.models.VoiceAgentServerEventWarningDetails(_Model): + code: Optional[str] + message: str + param: Optional[str] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ... + code: Optional[str] = ..., + message: str, + param: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolDescriptionParam(TypedDict, total=False): - key "description": str - key "name": str - - - class azure.ai.projects.models.ToolProjectConnection(_Model): - project_connection_id: str + class azure.ai.projects.models.VoiceAgentServerVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='server_vad'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[int] + interrupt_response: Optional[bool] + prefix_padding_ms: Optional[int] + silence_duration_ms: Optional[int] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.SERVER_VAD] @overload def __init__( self, *, - project_connection_id: str + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[int] = ..., + interrupt_response: Optional[bool] = ..., + prefix_padding_ms: Optional[int] = ..., + silence_duration_ms: Optional[int] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolSearchExecutionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CLIENT = "client" - SERVER = "server" - - - class azure.ai.projects.models.ToolSearchToolParam(Tool, discriminator='tool_search'): - description: Optional[str] - execution: Optional[Union[str, ToolSearchExecutionType]] - parameters: Optional[EmptyModelParam] - type: Literal[ToolType.TOOL_SEARCH] + class azure.ai.projects.models.VoiceAgentSessionAvatarConfig(VoiceAgentAvatarConfig): + character: str + customized: bool + ice_servers: Optional[list[VoiceAgentAvatarIceServer]] + model: str + output_audit_audio: bool + output_protocol: Union[str, VoiceAgentAvatarOutputProtocol] + scene: VoiceAgentAvatarScene + style: str + type: Union[str, VoiceAgentAvatarType] + video: VoiceAgentAvatarVideoParams @overload def __init__( self, *, - description: Optional[str] = ..., - execution: Optional[Union[str, ToolSearchExecutionType]] = ..., - parameters: Optional[EmptyModelParam] = ... + character: str, + customized: Optional[bool] = ..., + ice_servers: Optional[list[VoiceAgentAvatarIceServer]] = ..., + model: Optional[str] = ..., + output_audit_audio: Optional[bool] = ..., + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] = ..., + scene: Optional[VoiceAgentAvatarScene] = ..., + style: Optional[str] = ..., + type: Union[str, VoiceAgentAvatarType], + video: Optional[VoiceAgentAvatarVideoParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolSearchToolboxTool(ToolboxTool, discriminator='toolbox_search'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.TOOLBOX_SEARCH] + class azure.ai.projects.models.VoiceAgentSessionIncludeOption(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FILE_SEARCH_CALL_RESULTS = "file_search_call.results" + INPUT_AUDIO_TRANSCRIPTION_LOGPROBS = "item.input_audio_transcription.logprobs" + INPUT_AUDIO_TRANSCRIPTION_PHRASES = "item.input_audio_transcription.phrases" + + + class azure.ai.projects.models.VoiceAgentSessionResponseConfig(_Model): + animation: Optional[VoiceAgentAnimationConfig] + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentSessionAvatarConfig] + expires_at: Optional[datetime] + greeting: Optional[VoiceAgentGreetingConfig] + id: str + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + metadata: Optional[dict[str, str]] + model: str + object: Literal["session"] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + reasoning: Optional[RealtimeReasoning] + temperature: Optional[float] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] + type: Literal["realtime"] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + animation: Optional[VoiceAgentAnimationConfig] = ..., + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentSessionAvatarConfig] = ..., + expires_at: Optional[datetime] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., + id: str, + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + metadata: Optional[dict[str, str]] = ..., + model: str, + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + temperature: Optional[float] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A_PREVIEW = "a2a_preview" - A2_A = "a2a" - 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 = "computer" - COMPUTER_USE_PREVIEW = "computer_use_preview" - CUSTOM = "custom" - FABRIC_DATAAGENT_PREVIEW = "fabric_dataagent_preview" - FABRIC_IQ_PREVIEW = "fabric_iq_preview" - FILE_SEARCH = "file_search" - FUNCTION = "function" - IMAGE_GENERATION = "image_generation" - LOCAL_SHELL = "local_shell" - MCP = "mcp" - MEMORY_SEARCH_PREVIEW = "memory_search_preview" - NAMESPACE = "namespace" - OPENAPI = "openapi" - PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" - SHAREPOINT_GROUNDING_PREVIEW = "sharepoint_grounding_preview" - SHELL = "shell" - TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" - TOOL_SEARCH = "tool_search" - WEB_IQ_PREVIEW = "web_iq_preview" - WEB_SEARCH = "web_search" - WEB_SEARCH_PREVIEW = "web_search_preview" - WORK_IQ_PREVIEW = "work_iq_preview" - - - class azure.ai.projects.models.ToolUseFineTuningDataGenerationJobOptions(DataGenerationJobOptions, discriminator='tool_use'): - max_samples: int - model_options: DataGenerationModelOptions - train_split: float - type: Literal[DataGenerationJobType.TOOL_USE] + class azure.ai.projects.models.VoiceAgentSessionUpdateConfig(_Model): + animation: Optional[VoiceAgentAnimationConfig] + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentSessionAvatarConfig] + greeting: Optional[VoiceAgentGreetingConfig] + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + metadata: Optional[dict[str, str]] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + reasoning: Optional[RealtimeReasoning] + temperature: Optional[float] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] + type: Literal["realtime"] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ... + animation: Optional[VoiceAgentAnimationConfig] = ..., + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentSessionAvatarConfig] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + metadata: Optional[dict[str, str]] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + temperature: Optional[float] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxObject(_Model): - default_version: str - id: str - name: str + class azure.ai.projects.models.VoiceAgentStaticInterimResponseConfig(VoiceAgentInterimResponseConfig, discriminator='static_interim_response'): + latency_threshold_ms: timedelta + texts: Optional[list[str]] + triggers: Union[list[str, VoiceAgentInterimResponseTrigger]] + type: Literal["static_interim_response"] @overload def __init__( self, *, - default_version: str, - id: str, - name: str + latency_threshold_ms: Optional[timedelta] = ..., + texts: Optional[list[str]] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxPolicies(_Model): - rai_config: Optional[RaiConfig] + class azure.ai.projects.models.VoiceAgentSubagent(_Model): + agent_capabilities: str + agent_name: str + agent_version: Optional[str] + invoke_timeout_seconds: Optional[timedelta] + response_policy: Optional[VoiceAgentSubagentResponsePolicy] @overload def __init__( self, *, - rai_config: Optional[RaiConfig] = ... + agent_capabilities: str, + agent_name: str, + agent_version: Optional[str] = ..., + invoke_timeout_seconds: Optional[timedelta] = ..., + response_policy: Optional[VoiceAgentSubagentResponsePolicy] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSearchPreviewToolboxTool(ToolboxTool, discriminator='toolbox_search_preview'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] + class azure.ai.projects.models.VoiceAgentSubagentAbortReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + STOPPED_BY_USER = "stopped_by_user" + SUPERSEDED = "superseded" + TIMEOUT = "timeout" + UNKNOWN_TARGET = "unknown_target" + + + class azure.ai.projects.models.VoiceAgentSubagentConfig(_Model): + subagents: list[VoiceAgentSubagent] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + subagents: list[VoiceAgentSubagent] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellContainerAutoEnvironment(ToolboxShellEnvironment, discriminator='container_auto'): - file_ids: Optional[list[str]] - memory_limit: Optional[Union[str, ContainerMemoryLimit]] - network_policy: Optional[ToolboxShellNetworkPolicy] - skills: Optional[list[ContainerSkill]] - type: Literal["container_auto"] + class azure.ai.projects.models.VoiceAgentSubagentResponsePolicy(_Model): + ack_instructions: Optional[str] + enable_delta_progress: Optional[bool] + gap_filling_instructions: Optional[str] + gap_filling_interval: Optional[timedelta] + immediate_ack: Optional[bool] + progress_instructions: Optional[str] + progress_update_interval: Optional[timedelta] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ToolboxShellNetworkPolicy] = ..., - skills: Optional[list[ContainerSkill]] = ... + ack_instructions: Optional[str] = ..., + enable_delta_progress: Optional[bool] = ..., + gap_filling_instructions: Optional[str] = ..., + gap_filling_interval: Optional[timedelta] = ..., + immediate_ack: Optional[bool] = ..., + progress_instructions: Optional[str] = ..., + progress_update_interval: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellContainerReferenceEnvironment(ToolboxShellEnvironment, discriminator='container_reference'): - container_id: str - type: Literal["container_reference"] + class azure.ai.projects.models.VoiceAgentSystemTool(VoiceAgentTool, discriminator='system'): + description: Optional[str] + name: Union[str, VoiceAgentSystemToolName] + type: Literal["system"] @overload def __init__( self, *, - container_id: str + description: Optional[str] = ..., + name: Union[str, VoiceAgentSystemToolName] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellEnvironment(_Model): - type: str + class azure.ai.projects.models.VoiceAgentSystemToolName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + END_CONVERSATION = "end_conversation" + + + class azure.ai.projects.models.VoiceAgentTemplateGreetingConfig(VoiceAgentGreetingConfig, discriminator='template'): + text: str + type: Literal["template"] @overload def __init__( self, *, - type: str + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellNetworkPolicy(_Model): + class azure.ai.projects.models.VoiceAgentTool(_Model): type: str @overload @@ -10203,60 +16075,88 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator='disabled'): - type: Literal["disabled"] + class azure.ai.projects.models.VoiceAgentToolResponseScheduling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INTERRUPT = "interrupt" + SILENT = "silent" + SKIP_IF_BUSY = "skip_if_busy" + WHEN_IDLE = "when_idle" + + + class azure.ai.projects.models.VoiceAgentToolboxTool(VoiceAgentTool, discriminator='toolbox'): + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] + toolbox_name: str + toolbox_version: str + type: Literal["toolbox"] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] = ..., + toolbox_name: str, + toolbox_version: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSkill(_Model): - type: str + class azure.ai.projects.models.VoiceAgentTranscriptionPhrase(_Model): + confidence: Optional[float] + duration_milliseconds: timedelta + locale: Optional[str] + offset_milliseconds: timedelta + text: str + words: Optional[list[VoiceAgentTranscriptionWord]] @overload def __init__( self, *, - type: str + confidence: Optional[float] = ..., + duration_milliseconds: timedelta, + locale: Optional[str] = ..., + offset_milliseconds: timedelta, + text: str, + words: Optional[list[VoiceAgentTranscriptionWord]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSkillReference(ToolboxSkill, discriminator='skill_reference'): - name: str - type: Literal["skill_reference"] - version: Optional[str] + class azure.ai.projects.models.VoiceAgentTranscriptionWord(_Model): + duration_milliseconds: timedelta + offset_milliseconds: timedelta + text: str @overload def __init__( self, *, - name: str, - version: Optional[str] = ... + duration_milliseconds: timedelta, + offset_milliseconds: timedelta, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxTool(_Model): - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] + class azure.ai.projects.models.VoiceAgentTransport(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WEBRTC = "webrtc" + WEBSOCKET = "websocket" + + + class azure.ai.projects.models.VoiceAgentTurnDetectionConfig(_Model): + auto_truncate: Optional[bool] type: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., + auto_truncate: Optional[bool] = ..., type: str ) -> None: ... @@ -10264,294 +16164,319 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A_PREVIEW = "a2a_preview" - A2_A = "a2a" - AZURE_AI_SEARCH = "azure_ai_search" - BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" - CODE_INTERPRETER = "code_interpreter" - FABRIC_IQ_PREVIEW = "fabric_iq_preview" - FILE_SEARCH = "file_search" - MCP = "mcp" - OPENAPI = "openapi" - REMINDER_PREVIEW = "reminder_preview" - SHELL = "shell" - TOOLBOX_SEARCH = "toolbox_search" - TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" - WEB_IQ_PREVIEW = "web_iq_preview" - WEB_SEARCH = "web_search" - WORK_IQ_PREVIEW = "work_iq_preview" + class azure.ai.projects.models.VoiceAgentTurnDetectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SEMANTIC_VAD = "azure_semantic_vad" + AZURE_SEMANTIC_VAD_EN = "azure_semantic_vad_en" + AZURE_SEMANTIC_VAD_MULTILINGUAL = "azure_semantic_vad_multilingual" + SEMANTIC_VAD = "semantic_vad" + SERVER_VAD = "server_vad" - class azure.ai.projects.models.ToolboxVersionObject(_Model): + class azure.ai.projects.models.VoiceAgentWebSocketSubprotocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + REALTIME = "realtime" + + + class azure.ai.projects.models.VoiceAudioCodec(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PCM16 = "pcm16" + PCMA = "pcma" + PCMU = "pcmu" + + + class azure.ai.projects.models.VoiceAudioContainerFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WAV = "wav" + + + class azure.ai.projects.models.VoiceAudioRole(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + USER = "user" + + + class azure.ai.projects.models.VoiceConversation(_Model): + completed_at: Optional[datetime] created_at: datetime - description: Optional[str] id: str - metadata: dict[str, str] - name: str - policies: Optional[ToolboxPolicies] - skills: Optional[list[ToolboxSkill]] - tools: list[ToolboxTool] - version: str + last_error: Optional[ApiError] + metadata: Optional[dict[str, str]] + object: Literal["conversation"] + status: Union[str, VoiceConversationStatus] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, + completed_at: Optional[datetime] = ..., created_at: datetime, - description: Optional[str] = ..., id: str, - metadata: dict[str, str], - name: str, - policies: Optional[ToolboxPolicies] = ..., - skills: Optional[list[ToolboxSkill]] = ..., - tools: list[ToolboxTool], - version: str + last_error: Optional[ApiError] = ..., + metadata: Optional[dict[str, str]] = ..., + status: Union[str, VoiceConversationStatus], + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesDataGenerationJobOptions(DataGenerationJobOptions, discriminator='traces'): - max_samples: int - model_options: DataGenerationModelOptions - redact_private_content: Optional[bool] - train_split: float - type: Literal[DataGenerationJobType.TRACES] + class azure.ai.projects.models.VoiceConversationEngine(_Model): + type: str @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - redact_private_content: Optional[bool] = ..., - train_split: Optional[float] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesDataGenerationJobSource(DataGenerationJobSource, discriminator='traces'): - agent_id: Optional[str] - agent_name: Optional[str] - agent_version: Optional[str] - description: str - end_time: Optional[datetime] - start_time: datetime - type: Literal[DataGenerationJobSourceType.TRACES] + class azure.ai.projects.models.VoiceConversationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + IN_PROGRESS = "in_progress" + + + class azure.ai.projects.models.VoiceGeneratedItemAudioResponse(_Model): + blob_uri: Optional[str] + channels: Optional[int] + codec: Optional[Union[str, VoiceAudioCodec]] + conversation_id: str + duration_ms: Optional[timedelta] + format: Optional[Union[str, VoiceAudioContainerFormat]] + item_id: str + role: Optional[Union[str, VoiceAudioRole]] + sample_rate: Optional[int] + start_offset_ms: Optional[timedelta] @overload def __init__( self, *, - agent_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - agent_version: Optional[str] = ..., - description: Optional[str] = ..., - end_time: Optional[datetime] = ..., - start_time: datetime + blob_uri: Optional[str] = ..., + channels: Optional[int] = ..., + codec: Optional[Union[str, VoiceAudioCodec]] = ..., + conversation_id: str, + duration_ms: Optional[timedelta] = ..., + format: Optional[Union[str, VoiceAudioContainerFormat]] = ..., + item_id: str, + role: Optional[Union[str, VoiceAudioRole]] = ..., + sample_rate: Optional[int] = ..., + start_offset_ms: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='traces'): - agent_id: Optional[str] - agent_name: Optional[str] - agent_version: Optional[str] - description: Optional[str] - end_time: Optional[datetime] - start_time: datetime - type: Literal[EvaluatorGenerationJobSourceType.TRACES] + class azure.ai.projects.models.VoiceHostedAgentConversationEngine(VoiceConversationEngine, discriminator='hosted_agent'): + name: str + type: Literal["hosted_agent"] + version: Optional[str] @overload def __init__( self, *, - agent_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - agent_version: Optional[str] = ..., - description: Optional[str] = ..., - end_time: Optional[datetime] = ..., - start_time: datetime + name: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesPreviewEvalRunDataSource(TypedDict, total=False): - key "agent_id": str - key "agent_name": str - key "end_time": datetime - key "ingestion_delay_seconds": int - key "lookback_hours": int - key "max_traces": int - key "trace_ids": List[str] - key "type": Required[Literal["azure_ai_traces_preview"]] - - - class azure.ai.projects.models.TreatmentEffectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CHANGED = "Changed" - DEGRADED = "Degraded" - IMPROVED = "Improved" - INCONCLUSIVE = "Inconclusive" - TOO_FEW_SAMPLES = "TooFewSamples" - - - class azure.ai.projects.models.Trigger(_Model): - type: str + class azure.ai.projects.models.VoiceItemAudioResponse(_Model): + blob_uri: Optional[str] + channels: Optional[int] + codec: Optional[Union[str, VoiceAudioCodec]] + conversation_id: str + duration_ms: Optional[timedelta] + format: Optional[Union[str, VoiceAudioContainerFormat]] + item_id: str + role: Optional[Union[str, VoiceAudioRole]] + sample_rate: Optional[int] + start_offset_ms: Optional[timedelta] @overload def __init__( self, *, - type: str + blob_uri: Optional[str] = ..., + channels: Optional[int] = ..., + codec: Optional[Union[str, VoiceAudioCodec]] = ..., + conversation_id: str, + duration_ms: Optional[timedelta] = ..., + format: Optional[Union[str, VoiceAudioContainerFormat]] = ..., + item_id: str, + role: Optional[Union[str, VoiceAudioRole]] = ..., + sample_rate: Optional[int] = ..., + start_offset_ms: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CRON = "Cron" - ONE_TIME = "OneTime" - RECURRENCE = "Recurrence" - - - class azure.ai.projects.models.UpdateMemoriesLROPoller(LROPoller[MemoryStoreUpdateCompletedResult]): - property superseded_by: Optional[str] # Read-only - property update_id: str # Read-only - - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[MemoryStoreUpdateCompletedResult], - continuation_token: str, - **kwargs: Any - ) -> UpdateMemoriesLROPoller: ... - - - class azure.ai.projects.models.UpdateModelVersionRequest(_Model): - description: Optional[str] - tags: Optional[dict[str, str]] + class azure.ai.projects.models.VoiceModelType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANAGED = "managed" + SELF_DEPLOYED = "self_deployed" - @overload - def __init__( - self, - *, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... - ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.VoiceOutputModality(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANIMATION = "animation" + AUDIO = "audio" + AVATAR = "avatar" + TEXT = "text" - class azure.ai.projects.models.UpdateToolboxRequest(_Model): - default_version: str + class azure.ai.projects.models.VoiceRecordingChannelLayout(_Model): + left: Literal["user"] + right: Literal["agent"] - @overload def __init__( self, - *, - default_version: str + *args: Any, + **kwargs: Any ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - class azure.ai.projects.models.UserProfileMemoryItem(MemoryItem, discriminator='user_profile'): - content: str - kind: Literal[MemoryItemKind.USER_PROFILE] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.VoiceRecordingResponse(_Model): + blob_uri: Optional[str] + channel_layout: VoiceRecordingChannelLayout + channels: int + conversation_id: str + duration_ms: timedelta + format: Union[str, VoiceAudioContainerFormat] + sample_rate: int @overload def __init__( self, *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + blob_uri: Optional[str] = ..., + channel_layout: VoiceRecordingChannelLayout, + channels: int, + conversation_id: str, + duration_ms: timedelta, + format: Union[str, VoiceAudioContainerFormat], + sample_rate: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionIndicator(_Model): - type: str + class azure.ai.projects.models.VoiceResponse(VoiceResponseBase): + audio: Optional[VoiceResponseAudio] + completed_at: Optional[datetime] + conversation_id: str + created_at: Optional[datetime] + id: str + max_output_tokens: Union[int, str] + metadata: Optional[dict[str, str]] + object: str + output: Optional[list[RealtimeConversationItem]] + output_modalities: Union[list[str, str]] + status: Union[str, str, str, str, str] + status_details: RealtimeResponseStatusDetails + temperature: Optional[float] + usage: RealtimeResponseUsage @overload def __init__( self, *, - type: str + audio: Optional[VoiceResponseAudio] = ..., + completed_at: Optional[datetime] = ..., + conversation_id: str, + created_at: Optional[datetime] = ..., + id: str, + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[dict[str, str]] = ..., + object: Optional[Literal[response]] = ..., + output: Optional[list[RealtimeConversationItem]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + temperature: Optional[float] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionIndicatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - VERSION_REF = "version_ref" - - - class azure.ai.projects.models.VersionRefIndicator(VersionIndicator, discriminator='version_ref'): - agent_version: str - type: Literal[VersionIndicatorType.VERSION_REF] - + class azure.ai.projects.models.VoiceResponseAudio(_Model): + output: Optional[VoiceResponseAudioOutput] + @overload def __init__( self, *, - agent_version: str + output: Optional[VoiceResponseAudioOutput] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelectionRule(_Model): - agent_version: str - type: str + class azure.ai.projects.models.VoiceResponseAudioOutput(_Model): + format: Optional[RealtimeAudioFormats] + voice: Optional[str] + voice_locale: Optional[str] + voice_type: Optional[Union[str, VoiceType]] @overload def __init__( self, *, - agent_version: str, - type: str + format: Optional[RealtimeAudioFormats] = ..., + voice: Optional[str] = ..., + voice_locale: Optional[str] = ..., + voice_type: Optional[Union[str, VoiceType]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelector(_Model): - version_selection_rules: list[VersionSelectionRule] + class azure.ai.projects.models.VoiceResponseBase(_Model): + conversation_id: Optional[str] + id: Optional[str] + max_output_tokens: Optional[Union[int, Literal["inf"]]] + object: Optional[Literal["response"]] + output_modalities: Optional[list[Literal["text", "audio"]]] + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] + status_details: Optional[RealtimeResponseStatusDetails] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, - version_selection_rules: list[VersionSelectionRule] + conversation_id: Optional[str] = ..., + id: Optional[str] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + object: Optional[Literal[response]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - FIXED_RATIO = "FixedRatio" + class azure.ai.projects.models.VoiceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AVATAR_VOICE_SYNC = "avatar-voice-sync" + AZURE_CUSTOM = "azure-custom" + AZURE_PERSONAL = "azure-personal" + AZURE_REALTIME_NATIVE = "azure-realtime-native" + AZURE_STANDARD = "azure-standard" + OPENAI = "openai" class azure.ai.projects.models.WebIQPreviewTool(Tool, discriminator='web_iq_preview'): @@ -10723,78 +16648,438 @@ namespace azure.ai.projects.models ) -> None: ... @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.WeeklyRecurrenceSchedule(RecurrenceSchedule, discriminator='Weekly'): - days_of_week: list[Union[str, DayOfWeek]] - type: Literal[RecurrenceType.WEEKLY] + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.WeeklyRecurrenceSchedule(RecurrenceSchedule, discriminator='Weekly'): + days_of_week: list[Union[str, DayOfWeek]] + type: Literal[RecurrenceType.WEEKLY] + + @overload + def __init__( + self, + *, + days_of_week: list[Union[str, DayOfWeek]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.WorkIQPreviewTool(Tool, discriminator='work_iq_preview'): + project_connection_id: str + type: Literal[ToolType.WORK_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.WorkIQPreviewToolboxTool(ToolboxTool, discriminator='work_iq_preview'): + description: str + name: str + project_connection_id: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.WORK_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str, + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.WorkflowAgentDefinition(AgentDefinition, discriminator='workflow'): + kind: Literal[AgentKind.WORKFLOW] + rai_config: RaiConfig + workflow: Optional[str] + + @overload + def __init__( + self, + *, + rai_config: Optional[RaiConfig] = ..., + workflow: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + +namespace azure.ai.projects.operations + + class azure.ai.projects.operations.AgentEndpointConversationsOperations(GeneratedAgentEndpointConversationsOperations): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + def delete_agent_conversation( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace + def get_agent_conversation( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> VoiceConversation: ... + + @distributed_trace + def get_agent_conversation_audio( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> VoiceRecordingResponse: ... + + @distributed_trace + def get_agent_conversation_audio_content( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> Iterator[bytes]: ... + + @distributed_trace + def get_agent_conversation_item( + self, + agent_name: str, + conversation_id: str, + item_id: str, + **kwargs: Any + ) -> RealtimeConversationItem: ... + + @distributed_trace + def get_agent_conversation_item_audio( + self, + agent_name: str, + conversation_id: str, + item_id: str, + **kwargs: Any + ) -> VoiceItemAudioResponse: ... + + @distributed_trace + def get_agent_conversation_item_audio_content( + self, + agent_name: str, + conversation_id: str, + item_id: str, + **kwargs: Any + ) -> Iterator[bytes]: ... + + @distributed_trace + def get_agent_conversation_item_generated_audio( + self, + agent_name: str, + conversation_id: str, + item_id: str, + **kwargs: Any + ) -> VoiceGeneratedItemAudioResponse: ... + + @distributed_trace + def get_agent_conversation_item_generated_audio_content( + self, + agent_name: str, + conversation_id: str, + item_id: str, + **kwargs: Any + ) -> Iterator[bytes]: ... + + @distributed_trace + def get_agent_conversation_response( + self, + agent_name: str, + conversation_id: str, + response_id: str, + **kwargs: Any + ) -> VoiceResponse: ... + + @distributed_trace + def list_agent_conversation_items( + self, + agent_name: str, + conversation_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[RealtimeConversationItem]: ... + + @distributed_trace + def list_agent_conversation_response_items( + self, + agent_name: str, + conversation_id: str, + response_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[RealtimeConversationItem]: ... + + @distributed_trace + def list_agent_conversation_responses( + self, + agent_name: str, + conversation_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[VoiceResponse]: ... + + @distributed_trace + def list_agent_conversations( + self, + agent_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[VoiceConversation]: ... + + + class azure.ai.projects.operations.AgentTelephonyOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + def begin_import_telephony_campaign_recipients( + self, + agent_name: str, + campaign_id: str, + body: ImportTelephonyCampaignRecipientsRequest, + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @overload + def begin_import_telephony_campaign_recipients( + self, + agent_name: str, + campaign_id: str, + body: JSON, + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @overload + def begin_import_telephony_campaign_recipients( + self, + agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @overload + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: PublishTelephonyCampaignRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @overload + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @overload + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @distributed_trace + def begin_validate_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> LROPoller[TelephonyOperationResource]: ... + + @distributed_trace + def cancel_telephony_call_job( + self, + agent_name: str, + call_job_id: str, + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyCallJob: ... + + @distributed_trace + def cancel_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... + + @overload + def create_telephony_call_job( + self, + agent_name: str, + body: CreateTelephonyCallJobRequest, + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> TelephonyCallJob: ... @overload - def __init__( + def create_telephony_call_job( self, + agent_name: str, + body: JSON, *, - days_of_week: list[Union[str, DayOfWeek]] - ) -> None: ... + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> TelephonyCallJob: ... @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.WorkIQPreviewTool(Tool, discriminator='work_iq_preview'): - project_connection_id: str - type: Literal[ToolType.WORK_IQ_PREVIEW] + def create_telephony_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> TelephonyCallJob: ... @overload - def __init__( + def create_telephony_campaign( self, + agent_name: str, + body: CreateTelephonyCampaignRequest, *, - project_connection_id: str - ) -> None: ... + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCampaign: ... @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - - class azure.ai.projects.models.WorkIQPreviewToolboxTool(ToolboxTool, discriminator='work_iq_preview'): - description: str - name: str - project_connection_id: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.WORK_IQ_PREVIEW] + def create_telephony_campaign( + self, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCampaign: ... @overload - def __init__( + def create_telephony_campaign( self, + agent_name: str, + body: IO[bytes], *, - description: Optional[str] = ..., - name: Optional[str] = ..., - project_connection_id: str, - tool_configs: Optional[dict[str, ToolConfig]] = ... - ) -> None: ... + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCampaign: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + @distributed_trace + def get_telephony_call_job( + self, + agent_name: str, + call_job_id: str, + **kwargs: Any + ) -> TelephonyCallJob: ... + @distributed_trace + def get_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... - class azure.ai.projects.models.WorkflowAgentDefinition(AgentDefinition, discriminator='workflow'): - kind: Literal[AgentKind.WORKFLOW] - rai_config: RaiConfig - workflow: Optional[str] + @distributed_trace + def get_telephony_campaign_recipient_import( + self, + agent_name: str, + campaign_id: str, + import_id: str, + **kwargs: Any + ) -> TelephonyCampaignRecipientImport: ... - @overload - def __init__( + @distributed_trace + def get_telephony_operation( self, - *, - rai_config: Optional[RaiConfig] = ..., - workflow: Optional[str] = ... - ) -> None: ... + agent_name: str, + operation_id: str, + **kwargs: Any + ) -> TelephonyOperation: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + @distributed_trace + def pause_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... + @distributed_trace + def resume_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + **kwargs: Any + ) -> TelephonyCampaign: ... -namespace azure.ai.projects.operations class azure.ai.projects.operations.AgentsOperations(GeneratedAgentsOperations): @@ -10835,6 +17120,36 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> AgentSessionResource: ... + @overload + def create_telephony_binding( + self, + agent_name: str, + body: CreateTelephonyBindingRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def create_telephony_binding( + self, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def create_telephony_binding( + self, + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... + @overload def create_version( self, @@ -10943,6 +17258,17 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> None: ... + @distributed_trace + def delete_telephony_binding( + self, + agent_name: str, + binding_id: str, + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> None: ... + @distributed_trace def delete_version( self, @@ -10986,6 +17312,21 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> None: ... + @distributed_trace + def end_telephony_call( + self, + agent_name: str, + call_id: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @distributed_trace + def generate_agent( + self, + body: GenerateVoiceAgentRequest, + **kwargs: Any + ) -> AgentDetails: ... + @distributed_trace def get( self, @@ -11064,6 +17405,29 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> SessionLogEvent: ... + @distributed_trace + def get_telephony_binding( + self, + agent_name: str, + binding_id: str, + **kwargs: Any + ) -> TelephonyBinding: ... + + @distributed_trace + def get_telephony_call( + self, + agent_name: str, + call_id: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @distributed_trace + def get_telephony_transfer_targets( + self, + agent_name: str, + **kwargs: Any + ) -> TelephonyTransferTargets: ... + @distributed_trace def get_version( self, @@ -11107,6 +17471,34 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> ItemPaged[AgentSessionResource]: ... + @distributed_trace + def list_telephony_bindings( + self, + agent_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ..., + **kwargs: Any + ) -> ItemPaged[TelephonyBindingListItem]: ... + + @distributed_trace + def list_telephony_calls( + self, + agent_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + started_after: Optional[datetime] = ..., + started_before: Optional[datetime] = ..., + status: Optional[Union[str, TelephonyCallStatus]] = ..., + **kwargs: Any + ) -> ItemPaged[TelephonyCallSummary]: ... + @distributed_trace def list_versions( self, @@ -11164,6 +17556,42 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> Microsoft365PublishResult: ... + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + transfer_targets: List[TelephonyTransferTarget], + **kwargs: Any + ) -> TelephonyTransferTargets: ... + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyTransferTargets: ... + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyTransferTargets: ... + @distributed_trace def stop_session( self, @@ -11172,6 +17600,39 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> None: ... + @overload + def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + *, + content_type: str = "application/json", + target: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + @overload def update_details( self, @@ -11203,6 +17664,45 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> AgentDetails: ... + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: UpdateTelephonyBindingRequest, + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... + @overload def upload_session_file( self, @@ -13366,6 +19866,29 @@ namespace azure.ai.projects.operations ) -> ToolboxObject: ... + class azure.ai.projects.operations.VoiceAgentWebSocketOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + def connect_voice_agent( + self, + agent_name: str, + *, + agent_version_override: Optional[str] = ..., + foundry_features_query: Optional[Literal[_AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW]] = ..., + store: Optional[bool] = ..., + structured_input: Optional[str] = ..., + transport: Optional[Union[str, VoiceAgentTransport]] = ..., + websocket_subprotocol: Optional[Union[str, VoiceAgentWebSocketSubprotocol]] = ..., + **kwargs: Any + ) -> None: ... + + namespace azure.ai.projects.telemetry def azure.ai.projects.telemetry.trace_function(span_name: Optional[str] = None) -> Callable: ... diff --git a/sdk/ai/azure-ai-projects/api.metadata.yml b/sdk/ai/azure-ai-projects/api.metadata.yml index ea465463f31b..59500e0cdda0 100644 --- a/sdk/ai/azure-ai-projects/api.metadata.yml +++ b/sdk/ai/azure-ai-projects/api.metadata.yml @@ -1,4 +1,4 @@ -apiMdSha256: 5d405fa9c99c19e09c66ec01f262504083883917fbd849199f1a58de4a21c81e -packageVersion: 2.6.0 +apiMdSha256: 6800ab7a923e43603098be740db58aa7722b5ce824b52a34dd16cbf5f4c13801 +packageVersion: 2.7.0b1 parserVersion: 0.3.31 -pythonVersion: 3.12.10 +pythonVersion: 3.12.14 diff --git a/sdk/ai/azure-ai-projects/apiview-properties.json b/sdk/ai/azure-ai-projects/apiview-properties.json index 12ce353dd066..010b2e52b06b 100644 --- a/sdk/ai/azure-ai-projects/apiview-properties.json +++ b/sdk/ai/azure-ai-projects/apiview-properties.json @@ -132,6 +132,12 @@ "azure.ai.projects.models.CosmosDBIndex": "Azure.AI.Projects.CosmosDBIndex", "azure.ai.projects.models.CreateAsyncResponse": "Azure.AI.Projects.createAsync.Response.anonymous", "azure.ai.projects.models.CreateSkillVersionFromFilesBody": "Azure.AI.Projects.CreateSkillVersionFromFilesBody", + "azure.ai.projects.models.CreateTelephonyBindingRequest": "Azure.AI.Projects.CreateTelephonyBindingRequest", + "azure.ai.projects.models.CreateTeamsPhoneExtensionTelephonyBindingRequest": "Azure.AI.Projects.CreateTeamsPhoneExtensionTelephonyBindingRequest", + "azure.ai.projects.models.CreateTelephonyCallJobRequest": "Azure.AI.Projects.CreateTelephonyCallJobRequest", + "azure.ai.projects.models.CreateTelephonyCampaignRequest": "Azure.AI.Projects.CreateTelephonyCampaignRequest", + "azure.ai.projects.models.CreateTranscriptionResponseJsonUsage": "OpenAI.CreateTranscriptionResponseJsonUsage", + "azure.ai.projects.models.CreateTwilioTelephonyBindingRequest": "Azure.AI.Projects.CreateTwilioTelephonyBindingRequest", "azure.ai.projects.models.Trigger": "Azure.AI.Projects.Trigger", "azure.ai.projects.models.CronTrigger": "Azure.AI.Projects.CronTrigger", "azure.ai.projects.models.CustomCredential": "Azure.AI.Projects.CustomCredential", @@ -211,6 +217,7 @@ "azure.ai.projects.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam": "OpenAI.FunctionShellToolParamEnvironmentLocalEnvironmentParam", "azure.ai.projects.models.FunctionTool": "OpenAI.FunctionTool", "azure.ai.projects.models.FunctionToolParam": "OpenAI.FunctionToolParam", + "azure.ai.projects.models.GenerateVoiceAgentRequest": "Azure.AI.Projects.GenerateVoiceAgentRequest", "azure.ai.projects.models.GitHubIssueRoutineTrigger": "Azure.AI.Projects.GitHubIssueRoutineTrigger", "azure.ai.projects.models.TelemetryEndpointAuth": "Azure.AI.Projects.TelemetryEndpointAuth", "azure.ai.projects.models.HeaderTelemetryEndpointAuth": "Azure.AI.Projects.HeaderTelemetryEndpointAuth", @@ -220,6 +227,7 @@ "azure.ai.projects.models.HybridSearchOptions": "OpenAI.HybridSearchOptions", "azure.ai.projects.models.ImageGenTool": "OpenAI.ImageGenTool", "azure.ai.projects.models.ImageGenToolInputImageMask": "OpenAI.ImageGenToolInputImageMask", + "azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest": "Azure.AI.Projects.ImportTelephonyCampaignRecipientsRequest", "azure.ai.projects.models.InlineSkillParam": "OpenAI.InlineSkillParam", "azure.ai.projects.models.InlineSkillSourceParam": "OpenAI.InlineSkillSourceParam", "azure.ai.projects.models.Insight": "Azure.AI.Projects.Insight", @@ -238,9 +246,13 @@ "azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction": "Azure.AI.Projects.InvokeAgentResponsesApiRoutineAction", "azure.ai.projects.models.LocalShellToolParam": "OpenAI.LocalShellToolParam", "azure.ai.projects.models.LocalSkillParam": "OpenAI.LocalSkillParam", + "azure.ai.projects.models.LogProbProperties": "OpenAI.LogProbProperties", "azure.ai.projects.models.LoraConfig": "Azure.AI.Projects.LoraConfig", "azure.ai.projects.models.ManagedAgentIdentityBlueprintReference": "Azure.AI.Projects.ManagedAgentIdentityBlueprintReference", "azure.ai.projects.models.ManagedAzureAISearchIndex": "Azure.AI.Projects.ManagedAzureAISearchIndex", + "azure.ai.projects.models.MCPListToolsTool": "OpenAI.MCPListToolsTool", + "azure.ai.projects.models.MCPListToolsToolAnnotations": "OpenAI.MCPListToolsToolAnnotations", + "azure.ai.projects.models.MCPListToolsToolInputSchema": "OpenAI.MCPListToolsToolInputSchema", "azure.ai.projects.models.McpProtocolConfiguration": "Azure.AI.Projects.McpProtocolConfiguration", "azure.ai.projects.models.MCPTool": "OpenAI.MCPTool", "azure.ai.projects.models.MCPToolboxTool": "Azure.AI.Projects.MCPToolboxTool", @@ -259,6 +271,7 @@ "azure.ai.projects.models.MemoryStoreSearchResult": "Azure.AI.Projects.MemoryStoreSearchResponse", "azure.ai.projects.models.MemoryStoreUpdateCompletedResult": "Azure.AI.Projects.MemoryStoreUpdateCompletedResult", "azure.ai.projects.models.MemoryStoreUpdateResult": "Azure.AI.Projects.MemoryStoreUpdateResponse", + "azure.ai.projects.models.Metadata": "OpenAI.Metadata", "azure.ai.projects.models.Microsoft365PermissionScopes": "Azure.AI.Projects.Microsoft365PermissionScopes", "azure.ai.projects.models.Microsoft365PublishDefaults": "Azure.AI.Projects.Microsoft365PublishDefaults", "azure.ai.projects.models.Microsoft365PublishResult": "Azure.AI.Projects.Microsoft365PublishResponse", @@ -290,6 +303,7 @@ "azure.ai.projects.models.OtlpTelemetryEndpoint": "Azure.AI.Projects.OtlpTelemetryEndpoint", "azure.ai.projects.models.PendingUploadRequest": "Azure.AI.Projects.PendingUploadRequest", "azure.ai.projects.models.PendingUploadResponse": "Azure.AI.Projects.PendingUploadResponse", + "azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig": "TypeSpec.PickProperties", "azure.ai.projects.models.ProceduralMemoryItem": "Azure.AI.Projects.ProceduralMemoryItem", "azure.ai.projects.models.ProgrammaticToolCallingParam": "OpenAI.ProgrammaticToolCallingParam", "azure.ai.projects.models.PromotionInfo": "Azure.AI.Projects.PromotionInfo", @@ -300,8 +314,103 @@ "azure.ai.projects.models.PromptEvaluatorGenerationJobSource": "Azure.AI.Projects.PromptEvaluatorGenerationJobSource", "azure.ai.projects.models.ProtocolConfiguration": "Azure.AI.Projects.ProtocolConfiguration", "azure.ai.projects.models.ProtocolVersionRecord": "Azure.AI.Projects.ProtocolVersionRecord", + "azure.ai.projects.models.TelephonyTransferDestination": "Azure.AI.Projects.TelephonyTransferDestination", + "azure.ai.projects.models.PSTNTelephonyTransferDestination": "Azure.AI.Projects.PSTNTelephonyTransferDestination", + "azure.ai.projects.models.PublishTelephonyCampaignRequest": "Azure.AI.Projects.PublishTelephonyCampaignRequest", "azure.ai.projects.models.RaiConfig": "Azure.AI.Projects.RaiConfig", + "azure.ai.projects.models.RaiInvocationModeration": "Azure.AI.Projects.RaiInvocationModeration", + "azure.ai.projects.models.RaiSseTextSelector": "Azure.AI.Projects.RaiSseTextSelector", "azure.ai.projects.models.RankingOptions": "OpenAI.RankingOptions", + "azure.ai.projects.models.RealtimeAudioFormats": "OpenAI.RealtimeAudioFormats", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcm": "OpenAI.RealtimeAudioFormatsAudioPcm", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcma": "OpenAI.RealtimeAudioFormatsAudioPcma", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcmu": "OpenAI.RealtimeAudioFormatsAudioPcmu", + "azure.ai.projects.models.RealtimeClientEvent": "OpenAI.RealtimeClientEvent", + "azure.ai.projects.models.RealtimeClientEventConversationItemCreate": "OpenAI.RealtimeClientEventConversationItemCreate", + "azure.ai.projects.models.RealtimeClientEventConversationItemDelete": "OpenAI.RealtimeClientEventConversationItemDelete", + "azure.ai.projects.models.RealtimeClientEventConversationItemRetrieve": "OpenAI.RealtimeClientEventConversationItemRetrieve", + "azure.ai.projects.models.RealtimeClientEventConversationItemTruncate": "OpenAI.RealtimeClientEventConversationItemTruncate", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferAppend": "OpenAI.RealtimeClientEventInputAudioBufferAppend", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferClear": "OpenAI.RealtimeClientEventInputAudioBufferClear", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferCommit": "OpenAI.RealtimeClientEventInputAudioBufferCommit", + "azure.ai.projects.models.RealtimeClientEventOutputAudioBufferClear": "OpenAI.RealtimeClientEventOutputAudioBufferClear", + "azure.ai.projects.models.RealtimeClientEventResponseCancel": "OpenAI.RealtimeClientEventResponseCancel", + "azure.ai.projects.models.RealtimeClientEventResponseCreate": "OpenAI.RealtimeClientEventResponseCreate", + "azure.ai.projects.models.RealtimeConversationItem": "OpenAI.RealtimeConversationItem", + "azure.ai.projects.models.RealtimeConversationItemFunctionCall": "OpenAI.RealtimeConversationItemFunctionCall", + "azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput": "OpenAI.RealtimeConversationItemFunctionCallOutput", + "azure.ai.projects.models.RealtimeConversationItemMessage": "OpenAI.RealtimeConversationItemMessage", + "azure.ai.projects.models.RealtimeConversationItemMessageAssistant": "OpenAI.RealtimeConversationItemMessageAssistant", + "azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent": "OpenAI.RealtimeConversationItemMessageAssistantContent", + "azure.ai.projects.models.RealtimeConversationItemMessageSystem": "OpenAI.RealtimeConversationItemMessageSystem", + "azure.ai.projects.models.RealtimeConversationItemMessageSystemContent": "OpenAI.RealtimeConversationItemMessageSystemContent", + "azure.ai.projects.models.RealtimeConversationItemMessageUser": "OpenAI.RealtimeConversationItemMessageUser", + "azure.ai.projects.models.RealtimeConversationItemMessageUserContent": "OpenAI.RealtimeConversationItemMessageUserContent", + "azure.ai.projects.models.RealtimeFunctionTool": "OpenAI.RealtimeFunctionTool", + "azure.ai.projects.models.RealtimeFunctionToolParameters": "OpenAI.RealtimeFunctionToolParameters", + "azure.ai.projects.models.RealtimeMCPApprovalRequest": "OpenAI.RealtimeMCPApprovalRequest", + "azure.ai.projects.models.RealtimeMCPApprovalResponse": "OpenAI.RealtimeMCPApprovalResponse", + "azure.ai.projects.models.RealtimeMCPError": "OpenAI.RealtimeMCPError", + "azure.ai.projects.models.RealtimeMCPHTTPError": "OpenAI.RealtimeMCPHTTPError", + "azure.ai.projects.models.RealtimeMCPListTools": "OpenAI.RealtimeMCPListTools", + "azure.ai.projects.models.RealtimeMCPProtocolError": "OpenAI.RealtimeMCPProtocolError", + "azure.ai.projects.models.RealtimeMCPToolCall": "OpenAI.RealtimeMCPToolCall", + "azure.ai.projects.models.RealtimeMCPToolExecutionError": "OpenAI.RealtimeMCPToolExecutionError", + "azure.ai.projects.models.RealtimeReasoning": "OpenAI.RealtimeReasoning", + "azure.ai.projects.models.RealtimeResponseStatusDetails": "OpenAI.RealtimeResponseStatusDetails", + "azure.ai.projects.models.RealtimeResponseStatusDetailsError": "OpenAI.RealtimeResponseStatusDetailsError", + "azure.ai.projects.models.RealtimeResponseUsage": "OpenAI.RealtimeResponseUsage", + "azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails": "OpenAI.RealtimeResponseUsageInputTokenDetails", + "azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails": "OpenAI.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails", + "azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails": "OpenAI.RealtimeResponseUsageOutputTokenDetails", + "azure.ai.projects.models.RealtimeServerEvent": "OpenAI.RealtimeServerEvent", + "azure.ai.projects.models.RealtimeServerEventConversationItemAdded": "OpenAI.RealtimeServerEventConversationItemAdded", + "azure.ai.projects.models.RealtimeServerEventConversationItemCreated": "OpenAI.RealtimeServerEventConversationItemCreated", + "azure.ai.projects.models.RealtimeServerEventConversationItemDeleted": "OpenAI.RealtimeServerEventConversationItemDeleted", + "azure.ai.projects.models.RealtimeServerEventConversationItemDone": "OpenAI.RealtimeServerEventConversationItemDone", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionDelta", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailed", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionSegment", + "azure.ai.projects.models.RealtimeServerEventConversationItemRetrieved": "OpenAI.RealtimeServerEventConversationItemRetrieved", + "azure.ai.projects.models.RealtimeServerEventConversationItemTruncated": "OpenAI.RealtimeServerEventConversationItemTruncated", + "azure.ai.projects.models.RealtimeServerEventError": "OpenAI.RealtimeServerEventError", + "azure.ai.projects.models.RealtimeServerEventErrorError": "OpenAI.RealtimeServerEventErrorError", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferCleared": "OpenAI.RealtimeServerEventInputAudioBufferCleared", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferCommitted": "OpenAI.RealtimeServerEventInputAudioBufferCommitted", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStarted": "OpenAI.RealtimeServerEventInputAudioBufferSpeechStarted", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStopped": "OpenAI.RealtimeServerEventInputAudioBufferSpeechStopped", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferTimeoutTriggered": "OpenAI.RealtimeServerEventInputAudioBufferTimeoutTriggered", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsCompleted": "OpenAI.RealtimeServerEventMCPListToolsCompleted", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsFailed": "OpenAI.RealtimeServerEventMCPListToolsFailed", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsInProgress": "OpenAI.RealtimeServerEventMCPListToolsInProgress", + "azure.ai.projects.models.RealtimeServerEventOutputAudioBufferCleared": "OpenAI.RealtimeServerEventOutputAudioBufferCleared", + "azure.ai.projects.models.RealtimeServerEventRateLimitsUpdated": "OpenAI.RealtimeServerEventRateLimitsUpdated", + "azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits": "OpenAI.RealtimeServerEventRateLimitsUpdatedRateLimits", + "azure.ai.projects.models.RealtimeServerEventResponseAudioDelta": "OpenAI.RealtimeServerEventResponseAudioDelta", + "azure.ai.projects.models.RealtimeServerEventResponseAudioDone": "OpenAI.RealtimeServerEventResponseAudioDone", + "azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDelta": "OpenAI.RealtimeServerEventResponseAudioTranscriptDelta", + "azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDone": "OpenAI.RealtimeServerEventResponseAudioTranscriptDone", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartAdded": "OpenAI.RealtimeServerEventResponseContentPartAdded", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart": "OpenAI.RealtimeServerEventResponseContentPartAddedPart", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartDone": "OpenAI.RealtimeServerEventResponseContentPartDone", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart": "OpenAI.RealtimeServerEventResponseContentPartDonePart", + "azure.ai.projects.models.RealtimeServerEventResponseCreated": "OpenAI.RealtimeServerEventResponseCreated", + "azure.ai.projects.models.RealtimeServerEventResponseDone": "OpenAI.RealtimeServerEventResponseDone", + "azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDelta": "OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDelta", + "azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDone": "OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDone", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDelta": "OpenAI.RealtimeServerEventResponseMCPCallArgumentsDelta", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDone": "OpenAI.RealtimeServerEventResponseMCPCallArgumentsDone", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallCompleted": "OpenAI.RealtimeServerEventResponseMCPCallCompleted", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallFailed": "OpenAI.RealtimeServerEventResponseMCPCallFailed", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallInProgress": "OpenAI.RealtimeServerEventResponseMCPCallInProgress", + "azure.ai.projects.models.RealtimeServerEventResponseOutputItemAdded": "OpenAI.RealtimeServerEventResponseOutputItemAdded", + "azure.ai.projects.models.RealtimeServerEventResponseOutputItemDone": "OpenAI.RealtimeServerEventResponseOutputItemDone", + "azure.ai.projects.models.RealtimeServerEventResponseTextDelta": "OpenAI.RealtimeServerEventResponseTextDelta", + "azure.ai.projects.models.RealtimeServerEventResponseTextDone": "OpenAI.RealtimeServerEventResponseTextDone", + "azure.ai.projects.models.RealtimeServerEventSessionCreated": "OpenAI.RealtimeServerEventSessionCreated", + "azure.ai.projects.models.RealtimeServerEventSessionUpdated": "OpenAI.RealtimeServerEventSessionUpdated", "azure.ai.projects.models.Reasoning": "OpenAI.Reasoning", "azure.ai.projects.models.RecurrenceTrigger": "Azure.AI.Projects.RecurrenceTrigger", "azure.ai.projects.models.RedTeam": "Azure.AI.Projects.RedTeam", @@ -327,6 +436,7 @@ "azure.ai.projects.models.ShellToolboxTool": "Azure.AI.Projects.ShellToolboxTool", "azure.ai.projects.models.SimpleQnADataGenerationJobOptions": "Azure.AI.Projects.SimpleQnADataGenerationJobOptions", "azure.ai.projects.models.SimulationSeedDataGenerationJobOptions": "Azure.AI.Projects.SimulationSeedDataGenerationJobOptions", + "azure.ai.projects.models.SipTelephonyTransferDestination": "Azure.AI.Projects.SipTelephonyTransferDestination", "azure.ai.projects.models.SkillDetails": "Azure.AI.Projects.Skill", "azure.ai.projects.models.SkillInlineContent": "Azure.AI.Projects.SkillInlineContent", "azure.ai.projects.models.SkillReferenceParam": "OpenAI.SkillReferenceParam", @@ -339,7 +449,36 @@ "azure.ai.projects.models.StructuredOutputDefinition": "Azure.AI.Projects.StructuredOutputDefinition", "azure.ai.projects.models.TaxonomyCategory": "Azure.AI.Projects.TaxonomyCategory", "azure.ai.projects.models.TaxonomySubCategory": "Azure.AI.Projects.TaxonomySubCategory", + "azure.ai.projects.models.TelephonyBinding": "Azure.AI.Projects.TelephonyBinding", + "azure.ai.projects.models.TeamsPhoneExtensionTelephonyBinding": "Azure.AI.Projects.TeamsPhoneExtensionTelephonyBinding", + "azure.ai.projects.models.TelephonyBindingListItem": "Azure.AI.Projects.TelephonyBindingListItem", + "azure.ai.projects.models.TeamsPhoneExtensionTelephonyBindingListItem": "Azure.AI.Projects.TeamsPhoneExtensionTelephonyBindingListItem", + "azure.ai.projects.models.TeamsTelephonyTransferDestination": "Azure.AI.Projects.TeamsTelephonyTransferDestination", "azure.ai.projects.models.TelemetryConfig": "Azure.AI.Projects.TelemetryConfig", + "azure.ai.projects.models.TelephonyCallJob": "Azure.AI.Projects.TelephonyCallJob", + "azure.ai.projects.models.TelephonyCallJobCancellation": "Azure.AI.Projects.TelephonyCallJobCancellation", + "azure.ai.projects.models.TelephonyCallJobSchedule": "Azure.AI.Projects.TelephonyCallJobSchedule", + "azure.ai.projects.models.TelephonyCallLifecycleEvent": "Azure.AI.Projects.TelephonyCallLifecycleEvent", + "azure.ai.projects.models.TelephonyCallRecord": "Azure.AI.Projects.TelephonyCallRecord", + "azure.ai.projects.models.TelephonyCallSummary": "Azure.AI.Projects.TelephonyCallSummary", + "azure.ai.projects.models.TelephonyCallTiming": "Azure.AI.Projects.TelephonyCallTiming", + "azure.ai.projects.models.TelephonyCallTrace": "Azure.AI.Projects.TelephonyCallTrace", + "azure.ai.projects.models.TelephonyCampaign": "Azure.AI.Projects.TelephonyCampaign", + "azure.ai.projects.models.TelephonyCampaignCallJobCounts": "Azure.AI.Projects.TelephonyCampaignCallJobCounts", + "azure.ai.projects.models.TelephonyCampaignRecipientImport": "Azure.AI.Projects.TelephonyCampaignRecipientImport", + "azure.ai.projects.models.TelephonyCampaignRecipientImportSource": "Azure.AI.Projects.TelephonyCampaignRecipientImportSource", + "azure.ai.projects.models.TelephonyCampaignRecipientMapping": "Azure.AI.Projects.TelephonyCampaignRecipientMapping", + "azure.ai.projects.models.TelephonyCampaignRecipientMappingRequest": "Azure.AI.Projects.TelephonyCampaignRecipientMappingRequest", + "azure.ai.projects.models.TelephonyCampaignSchedule": "Azure.AI.Projects.TelephonyCampaignSchedule", + "azure.ai.projects.models.TelephonyOperation": "Azure.AI.Projects.TelephonyOperation", + "azure.ai.projects.models.TelephonyOperationResource": "Azure.AI.Projects.TelephonyOperationResource", + "azure.ai.projects.models.TelephonyOutboundDestination": "Azure.AI.Projects.TelephonyOutboundDestination", + "azure.ai.projects.models.TelephonyOutboundRetryPolicy": "Azure.AI.Projects.TelephonyOutboundRetryPolicy", + "azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicy": "Azure.AI.Projects.TelephonyOutboundFixedIntervalRetryPolicy", + "azure.ai.projects.models.TelephonyOutboundRetryPolicyResponse": "Azure.AI.Projects.TelephonyOutboundRetryPolicyResponse", + "azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicyResponse": "Azure.AI.Projects.TelephonyOutboundFixedIntervalRetryPolicyResponse", + "azure.ai.projects.models.TelephonyTransferTarget": "Azure.AI.Projects.TelephonyTransferTarget", + "azure.ai.projects.models.TelephonyTransferTargets": "Azure.AI.Projects.TelephonyTransferTargets", "azure.ai.projects.models.TextResponseFormat": "OpenAI.TextResponseFormatConfiguration", "azure.ai.projects.models.TextResponseFormatJsonObject": "OpenAI.TextResponseFormatConfigurationResponseFormatJsonObject", "azure.ai.projects.models.TextResponseFormatJsonSchema": "OpenAI.TextResponseFormatJsonSchema", @@ -377,12 +516,95 @@ "azure.ai.projects.models.TracesDataGenerationJobOptions": "Azure.AI.Projects.TracesDataGenerationJobOptions", "azure.ai.projects.models.TracesDataGenerationJobSource": "Azure.AI.Projects.TracesDataGenerationJobSource", "azure.ai.projects.models.TracesEvaluatorGenerationJobSource": "Azure.AI.Projects.TracesEvaluatorGenerationJobSource", + "azure.ai.projects.models.TranscriptionLanguage": "OpenAI.TranscriptionLanguage", + "azure.ai.projects.models.TranscriptTextUsageDuration": "OpenAI.TranscriptTextUsageDuration", + "azure.ai.projects.models.TranscriptTextUsageTokens": "OpenAI.TranscriptTextUsageTokens", + "azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails": "OpenAI.TranscriptTextUsageTokensInputTokenDetails", + "azure.ai.projects.models.TwilioTelephonyBinding": "Azure.AI.Projects.TwilioTelephonyBinding", + "azure.ai.projects.models.TwilioTelephonyBindingListItem": "Azure.AI.Projects.TwilioTelephonyBindingListItem", "azure.ai.projects.models.UpdateModelVersionRequest": "Azure.AI.Projects.UpdateModelVersionRequest", + "azure.ai.projects.models.UpdateTelephonyBindingRequest": "Azure.AI.Projects.UpdateTelephonyBindingRequest", "azure.ai.projects.models.UpdateToolboxRequest": "Azure.AI.Projects.UpdateToolboxRequest", "azure.ai.projects.models.UserProfileMemoryItem": "Azure.AI.Projects.UserProfileMemoryItem", "azure.ai.projects.models.VersionIndicator": "Azure.AI.Projects.VersionIndicator", "azure.ai.projects.models.VersionRefIndicator": "Azure.AI.Projects.VersionRefIndicator", "azure.ai.projects.models.VersionSelector": "Azure.AI.Projects.VersionSelector", + "azure.ai.projects.models.VoiceAgentAnimationConfig": "Azure.AI.Projects.VoiceAgentAnimationConfig", + "azure.ai.projects.models.VoiceAgentAudioConfig": "Azure.AI.Projects.VoiceAgentAudioConfig", + "azure.ai.projects.models.VoiceAgentAudioInputConfig": "Azure.AI.Projects.VoiceAgentAudioInputConfig", + "azure.ai.projects.models.VoiceAgentAudioOutputConfig": "Azure.AI.Projects.VoiceAgentAudioOutputConfig", + "azure.ai.projects.models.VoiceAgentAvatarConfig": "Azure.AI.Projects.VoiceAgentAvatarConfig", + "azure.ai.projects.models.VoiceAgentAvatarIceServer": "Azure.AI.Projects.VoiceAgentAvatarIceServer", + "azure.ai.projects.models.VoiceAgentAvatarScene": "Azure.AI.Projects.VoiceAgentAvatarScene", + "azure.ai.projects.models.VoiceAgentAvatarVideoBackground": "Azure.AI.Projects.VoiceAgentAvatarVideoBackground", + "azure.ai.projects.models.VoiceAgentAvatarVideoCrop": "Azure.AI.Projects.VoiceAgentAvatarVideoCrop", + "azure.ai.projects.models.VoiceAgentAvatarVideoParams": "Azure.AI.Projects.VoiceAgentAvatarVideoParams", + "azure.ai.projects.models.VoiceAgentAvatarVideoResolution": "Azure.AI.Projects.VoiceAgentAvatarVideoResolution", + "azure.ai.projects.models.VoiceAgentTurnDetectionConfig": "Azure.AI.Projects.VoiceAgentTurnDetectionConfig", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadEnTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadEnTurnDetection", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadMultilingualTurnDetection", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadTurnDetection", + "azure.ai.projects.models.VoiceAgentClientEventRtcCallSdpCreate": "Azure.AI.Projects.VoiceAgentClientEventRtcCallSdpCreate", + "azure.ai.projects.models.VoiceAgentClientEventSessionAvatarConnect": "Azure.AI.Projects.VoiceAgentClientEventSessionAvatarConnect", + "azure.ai.projects.models.VoiceAgentClientEventSessionUpdate": "Azure.AI.Projects.VoiceAgentClientEventSessionUpdate", + "azure.ai.projects.models.VoiceAgentDefinition": "Azure.AI.Projects.VoiceAgentDefinition", + "azure.ai.projects.models.VoiceAgentEchoCancellation": "Azure.AI.Projects.VoiceAgentEchoCancellation", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection": "Azure.AI.Projects.VoiceAgentEndOfUtteranceDetection", + "azure.ai.projects.models.VoiceAgentTool": "Azure.AI.Projects.VoiceAgentTool", + "azure.ai.projects.models.VoiceAgentFunctionTool": "Azure.AI.Projects.VoiceAgentFunctionTool", + "azure.ai.projects.models.VoiceAgentGreetingConfig": "Azure.AI.Projects.VoiceAgentGreetingConfig", + "azure.ai.projects.models.VoiceAgentInputTranscription": "Azure.AI.Projects.VoiceAgentInputTranscription", + "azure.ai.projects.models.VoiceAgentInterimResponseConfig": "Azure.AI.Projects.VoiceAgentInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentLlmGeneratedGreetingConfig": "Azure.AI.Projects.VoiceAgentLlmGeneratedGreetingConfig", + "azure.ai.projects.models.VoiceAgentLlmInterimResponseConfig": "Azure.AI.Projects.VoiceAgentLlmInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentMcpTool": "Azure.AI.Projects.VoiceAgentMcpTool", + "azure.ai.projects.models.VoiceAgentNoiseReduction": "Azure.AI.Projects.VoiceAgentNoiseReduction", + "azure.ai.projects.models.VoiceAgentRealtimeResponseBase": "Azure.AI.Projects.VoiceAgentRealtimeResponseBase", + "azure.ai.projects.models.VoiceAgentRealtimeResponse": "Azure.AI.Projects.VoiceAgentRealtimeResponse", + "azure.ai.projects.models.VoiceAgentResponseCreateParams": "Azure.AI.Projects.VoiceAgentResponseCreateParams", + "azure.ai.projects.models.VoiceAgentRtcCallErrorDetails": "Azure.AI.Projects.VoiceAgentRtcCallErrorDetails", + "azure.ai.projects.models.VoiceAgentSemanticVadTurnDetection": "Azure.AI.Projects.VoiceAgentSemanticVadTurnDetection", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseVideoDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseVideoDelta", + "azure.ai.projects.models.VoiceAgentServerEventRtcCallError": "Azure.AI.Projects.VoiceAgentServerEventRtcCallError", + "azure.ai.projects.models.VoiceAgentServerEventRtcCallSdpCreated": "Azure.AI.Projects.VoiceAgentServerEventRtcCallSdpCreated", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarConnecting": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarConnecting", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToIdle": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToIdle", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToSpeaking", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentAborted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentAborted", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentCompleted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentCompleted", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentStarted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentStarted", + "azure.ai.projects.models.VoiceAgentServerEventWarning": "Azure.AI.Projects.VoiceAgentServerEventWarning", + "azure.ai.projects.models.VoiceAgentServerEventWarningDetails": "Azure.AI.Projects.VoiceAgentServerEventWarningDetails", + "azure.ai.projects.models.VoiceAgentServerVadTurnDetection": "Azure.AI.Projects.VoiceAgentServerVadTurnDetection", + "azure.ai.projects.models.VoiceAgentSessionAvatarConfig": "Azure.AI.Projects.VoiceAgentSessionAvatarConfig", + "azure.ai.projects.models.VoiceAgentSessionResponseConfig": "Azure.AI.Projects.VoiceAgentSessionResponseConfig", + "azure.ai.projects.models.VoiceAgentSessionUpdateConfig": "Azure.AI.Projects.VoiceAgentSessionUpdateConfig", + "azure.ai.projects.models.VoiceAgentStaticInterimResponseConfig": "Azure.AI.Projects.VoiceAgentStaticInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentSubagent": "Azure.AI.Projects.VoiceAgentSubagent", + "azure.ai.projects.models.VoiceAgentSubagentConfig": "Azure.AI.Projects.VoiceAgentSubagentConfig", + "azure.ai.projects.models.VoiceAgentSubagentResponsePolicy": "Azure.AI.Projects.VoiceAgentSubagentResponsePolicy", + "azure.ai.projects.models.VoiceAgentSystemTool": "Azure.AI.Projects.VoiceAgentSystemTool", + "azure.ai.projects.models.VoiceAgentTemplateGreetingConfig": "Azure.AI.Projects.VoiceAgentTemplateGreetingConfig", + "azure.ai.projects.models.VoiceAgentToolboxTool": "Azure.AI.Projects.VoiceAgentToolboxTool", + "azure.ai.projects.models.VoiceAgentTranscriptionPhrase": "Azure.AI.Projects.VoiceAgentTranscriptionPhrase", + "azure.ai.projects.models.VoiceAgentTranscriptionWord": "Azure.AI.Projects.VoiceAgentTranscriptionWord", + "azure.ai.projects.models.VoiceConversation": "Azure.AI.Projects.VoiceConversation", + "azure.ai.projects.models.VoiceConversationEngine": "Azure.AI.Projects.VoiceConversationEngine", + "azure.ai.projects.models.VoiceGeneratedItemAudioResponse": "Azure.AI.Projects.VoiceGeneratedItemAudioResponse", + "azure.ai.projects.models.VoiceHostedAgentConversationEngine": "Azure.AI.Projects.VoiceHostedAgentConversationEngine", + "azure.ai.projects.models.VoiceItemAudioResponse": "Azure.AI.Projects.VoiceItemAudioResponse", + "azure.ai.projects.models.VoiceRecordingChannelLayout": "Azure.AI.Projects.VoiceRecordingChannelLayout", + "azure.ai.projects.models.VoiceRecordingResponse": "Azure.AI.Projects.VoiceRecordingResponse", + "azure.ai.projects.models.VoiceResponseBase": "Azure.AI.Projects.VoiceResponseBase", + "azure.ai.projects.models.VoiceResponse": "Azure.AI.Projects.VoiceResponse", + "azure.ai.projects.models.VoiceResponseAudio": "Azure.AI.Projects.VoiceResponseAudio", + "azure.ai.projects.models.VoiceResponseAudioOutput": "Azure.AI.Projects.VoiceResponseAudioOutput", "azure.ai.projects.models.WebIQPreviewTool": "Azure.AI.Projects.WebIQPreviewTool", "azure.ai.projects.models.WebIQPreviewToolboxTool": "Azure.AI.Projects.WebIQPreviewToolboxTool", "azure.ai.projects.models.WebSearchApproximateLocation": "OpenAI.WebSearchApproximateLocation", @@ -471,6 +693,8 @@ "azure.ai.projects.models.AgentState": "Azure.AI.Projects.AgentState", "azure.ai.projects.models.AgentStateSource": "Azure.AI.Projects.AgentStateSource", "azure.ai.projects.models.AgentKind": "Azure.AI.Projects.AgentKind", + "azure.ai.projects.models.RaiInvocationContentType": "Azure.AI.Projects.RaiInvocationContentType", + "azure.ai.projects.models.RaiInvocationMode": "Azure.AI.Projects.RaiInvocationMode", "azure.ai.projects.models.AgentEndpointProtocol": "Azure.AI.Projects.AgentEndpointProtocol", "azure.ai.projects.models.CodeDependencyResolution": "Azure.AI.Projects.CodeDependencyResolution", "azure.ai.projects.models.TelemetryEndpointKind": "Azure.AI.Projects.TelemetryEndpointKind", @@ -481,6 +705,23 @@ "azure.ai.projects.models.ReasoningEffort": "OpenAI.ReasoningEffort", "azure.ai.projects.models.ToolChoiceParamType": "OpenAI.ToolChoiceParamType", "azure.ai.projects.models.TextResponseFormatConfigurationType": "OpenAI.TextResponseFormatConfigurationType", + "azure.ai.projects.models.VoiceModelType": "Azure.AI.Projects.VoiceModelType", + "azure.ai.projects.models.RealtimeAudioFormatsType": "OpenAI.RealtimeAudioFormatsType", + "azure.ai.projects.models.VoiceAgentNoiseReductionType": "Azure.AI.Projects.VoiceAgentNoiseReductionType", + "azure.ai.projects.models.VoiceAgentTurnDetectionType": "Azure.AI.Projects.VoiceAgentTurnDetectionType", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel": "Azure.AI.Projects.VoiceAgentEndOfUtteranceDetectionModel", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel": "Azure.AI.Projects.VoiceAgentEndOfUtteranceThresholdLevel", + "azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource": "Azure.AI.Projects.VoiceAgentEchoCancellationReferenceSource", + "azure.ai.projects.models.VoiceAgentInputTranscriptionModel": "Azure.AI.Projects.VoiceAgentInputTranscriptionModel", + "azure.ai.projects.models.VoiceType": "Azure.AI.Projects.VoiceType", + "azure.ai.projects.models.VoiceAgentAudioTimestampType": "Azure.AI.Projects.VoiceAgentAudioTimestampType", + "azure.ai.projects.models.VoiceOutputModality": "Azure.AI.Projects.VoiceOutputModality", + "azure.ai.projects.models.VoiceAgentSessionIncludeOption": "Azure.AI.Projects.VoiceAgentSessionIncludeOption", + "azure.ai.projects.models.VoiceAgentInterimResponseTrigger": "Azure.AI.Projects.VoiceAgentInterimResponseTrigger", + "azure.ai.projects.models.VoiceAgentAvatarType": "Azure.AI.Projects.VoiceAgentAvatarType", + "azure.ai.projects.models.VoiceAgentAvatarOutputProtocol": "Azure.AI.Projects.VoiceAgentAvatarOutputProtocol", + "azure.ai.projects.models.VoiceAgentToolResponseScheduling": "Azure.AI.Projects.VoiceAgentToolResponseScheduling", + "azure.ai.projects.models.VoiceAgentSystemToolName": "Azure.AI.Projects.VoiceAgentSystemToolName", "azure.ai.projects.models.AgentVersionStatus": "Azure.AI.Projects.AgentVersionStatus", "azure.ai.projects.models.AgentIdentityStatus": "Azure.AI.Projects.AgentIdentityStatus", "azure.ai.projects.models.AgentBlueprintReferenceType": "Azure.AI.Projects.AgentBlueprintReferenceType", @@ -493,6 +734,18 @@ "azure.ai.projects.models.AgentSessionStatus": "Azure.AI.Projects.AgentSessionStatus", "azure.ai.projects.models.SessionLogEventType": "Azure.AI.Projects.SessionLogEventType", "azure.ai.projects.models.Microsoft365PublishScope": "Azure.AI.Projects.Microsoft365PublishScope", + "azure.ai.projects.models.TelephonyProvider": "Azure.AI.Projects.TelephonyProvider", + "azure.ai.projects.models.TelephonyBindingStatus": "Azure.AI.Projects.TelephonyBindingStatus", + "azure.ai.projects.models.TelephonyCallStatus": "Azure.AI.Projects.TelephonyCallStatus", + "azure.ai.projects.models.TelephonyCallPhase": "Azure.AI.Projects.TelephonyCallPhase", + "azure.ai.projects.models.TelephonyCallDurationBasis": "Azure.AI.Projects.TelephonyCallDurationBasis", + "azure.ai.projects.models.TelephonyCallTimestampSource": "Azure.AI.Projects.TelephonyCallTimestampSource", + "azure.ai.projects.models.TelephonyCallTraceStatus": "Azure.AI.Projects.TelephonyCallTraceStatus", + "azure.ai.projects.models.TelephonyCallTraceMode": "Azure.AI.Projects.TelephonyCallTraceMode", + "azure.ai.projects.models.TelephonyCallLifecycleEventName": "Azure.AI.Projects.TelephonyCallLifecycleEventName", + "azure.ai.projects.models.TelephonyCallLifecycleEventSource": "Azure.AI.Projects.TelephonyCallLifecycleEventSource", + "azure.ai.projects.models.TelephonyCallLifecycleEventOutcome": "Azure.AI.Projects.TelephonyCallLifecycleEventOutcome", + "azure.ai.projects.models.TelephonyTransferDestinationKind": "Azure.AI.Projects.TelephonyTransferDestinationKind", "azure.ai.projects.models.EvaluationRuleActionType": "Azure.AI.Projects.EvaluationRuleActionType", "azure.ai.projects.models.EvaluationRuleEventType": "Azure.AI.Projects.EvaluationRuleEventType", "azure.ai.projects.models.ConnectionType": "Azure.AI.Projects.ConnectionType", @@ -500,10 +753,39 @@ "azure.ai.projects.models.DatasetType": "Azure.AI.Projects.DatasetType", "azure.ai.projects.models.DeploymentType": "Azure.AI.Projects.DeploymentType", "azure.ai.projects.models.IndexType": "Azure.AI.Projects.IndexType", + "azure.ai.projects.models.VoiceAgentWebSocketSubprotocol": "Azure.AI.Projects.VoiceAgentWebSocketSubprotocol", + "azure.ai.projects.models._AgentDefinitionOptInKeys": "Azure.AI.Projects.AgentDefinitionOptInKeys", + "azure.ai.projects.models.VoiceAgentTransport": "Azure.AI.Projects.VoiceAgentTransport", + "azure.ai.projects.models.VoiceConversationStatus": "Azure.AI.Projects.VoiceConversationStatus", + "azure.ai.projects.models.RealtimeConversationItemType": "OpenAI.RealtimeConversationItemType", + "azure.ai.projects.models.RealtimeMcpErrorType": "OpenAI.RealtimeMcpErrorType", + "azure.ai.projects.models.RealtimeConversationItemMessageType": "OpenAI.RealtimeConversationItemMessageType", + "azure.ai.projects.models.VoiceAudioRole": "Azure.AI.Projects.VoiceAudioRole", + "azure.ai.projects.models.VoiceAudioContainerFormat": "Azure.AI.Projects.VoiceAudioContainerFormat", + "azure.ai.projects.models.VoiceAudioCodec": "Azure.AI.Projects.VoiceAudioCodec", + "azure.ai.projects.models.TelephonyOutboundDestinationType": "Azure.AI.Projects.TelephonyOutboundDestinationType", + "azure.ai.projects.models.TelephonyCallJobStatus": "Azure.AI.Projects.TelephonyCallJobStatus", + "azure.ai.projects.models.TelephonyOutboundRetryPolicyType": "Azure.AI.Projects.TelephonyOutboundRetryPolicyType", + "azure.ai.projects.models.TelephonyCampaignScheduleType": "Azure.AI.Projects.TelephonyCampaignScheduleType", + "azure.ai.projects.models.TelephonyCampaignConfigurationStatus": "Azure.AI.Projects.TelephonyCampaignConfigurationStatus", + "azure.ai.projects.models.TelephonyCampaignExecutionStatus": "Azure.AI.Projects.TelephonyCampaignExecutionStatus", + "azure.ai.projects.models.TelephonyCampaignRecipientImportFormat": "Azure.AI.Projects.TelephonyCampaignRecipientImportFormat", + "azure.ai.projects.models.TelephonyCampaignDuplicateHandling": "Azure.AI.Projects.TelephonyCampaignDuplicateHandling", + "azure.ai.projects.models.TelephonyCampaignRecipientImportStatus": "Azure.AI.Projects.TelephonyCampaignRecipientImportStatus", + "azure.ai.projects.models.TelephonyOperationStatus": "Azure.AI.Projects.TelephonyOperationStatus", "azure.ai.projects.models.ToolboxToolType": "Azure.AI.Projects.ToolboxToolType", "azure.ai.projects.models.MemoryStoreUpdateStatus": "Azure.AI.Projects.MemoryStoreUpdateStatus", + "azure.ai.projects.models.VoiceAgentAnimationOutputType": "Azure.AI.Projects.VoiceAgentAnimationOutputType", + "azure.ai.projects.models.RealtimeReasoningEffort": "OpenAI.RealtimeReasoningEffort", + "azure.ai.projects.models.RealtimeClientEventType": "OpenAI.RealtimeClientEventType", + "azure.ai.projects.models.ToolChoiceOptions": "OpenAI.ToolChoiceOptions", + "azure.ai.projects.models.RealtimeServerEventType": "OpenAI.RealtimeServerEventType", + "azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType": "OpenAI.CreateTranscriptionResponseJsonUsageType", + "azure.ai.projects.models.VoiceAgentSubagentAbortReason": "Azure.AI.Projects.VoiceAgentSubagentAbortReason", "azure.ai.projects.operations.AgentsOperations.get": "Azure.AI.Projects.Agents.getAgent", "azure.ai.projects.aio.operations.AgentsOperations.get": "Azure.AI.Projects.Agents.getAgent", + "azure.ai.projects.operations.AgentsOperations.generate_agent": "Azure.AI.Projects.Agents.generateAgent", + "azure.ai.projects.aio.operations.AgentsOperations.generate_agent": "Azure.AI.Projects.Agents.generateAgent", "azure.ai.projects.operations.AgentsOperations.delete": "Azure.AI.Projects.Agents.deleteAgent", "azure.ai.projects.aio.operations.AgentsOperations.delete": "Azure.AI.Projects.Agents.deleteAgent", "azure.ai.projects.operations.AgentsOperations.list": "Azure.AI.Projects.Agents.listAgents", @@ -544,6 +826,28 @@ "azure.ai.projects.aio.operations.AgentsOperations.get_microsoft365_package": "Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage", "azure.ai.projects.operations.AgentsOperations.get_microsoft365_publish_defaults": "Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults", "azure.ai.projects.aio.operations.AgentsOperations.get_microsoft365_publish_defaults": "Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults", + "azure.ai.projects.operations.AgentsOperations.create_telephony_binding": "Azure.AI.Projects.AgentTelephony.createTelephonyBinding", + "azure.ai.projects.aio.operations.AgentsOperations.create_telephony_binding": "Azure.AI.Projects.AgentTelephony.createTelephonyBinding", + "azure.ai.projects.operations.AgentsOperations.list_telephony_bindings": "Azure.AI.Projects.AgentTelephony.listTelephonyBindings", + "azure.ai.projects.aio.operations.AgentsOperations.list_telephony_bindings": "Azure.AI.Projects.AgentTelephony.listTelephonyBindings", + "azure.ai.projects.operations.AgentsOperations.get_telephony_binding": "Azure.AI.Projects.AgentTelephony.getTelephonyBinding", + "azure.ai.projects.aio.operations.AgentsOperations.get_telephony_binding": "Azure.AI.Projects.AgentTelephony.getTelephonyBinding", + "azure.ai.projects.operations.AgentsOperations.update_telephony_binding": "Azure.AI.Projects.AgentTelephony.updateTelephonyBinding", + "azure.ai.projects.aio.operations.AgentsOperations.update_telephony_binding": "Azure.AI.Projects.AgentTelephony.updateTelephonyBinding", + "azure.ai.projects.operations.AgentsOperations.delete_telephony_binding": "Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding", + "azure.ai.projects.aio.operations.AgentsOperations.delete_telephony_binding": "Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding", + "azure.ai.projects.operations.AgentsOperations.list_telephony_calls": "Azure.AI.Projects.AgentTelephony.listTelephonyCalls", + "azure.ai.projects.aio.operations.AgentsOperations.list_telephony_calls": "Azure.AI.Projects.AgentTelephony.listTelephonyCalls", + "azure.ai.projects.operations.AgentsOperations.get_telephony_call": "Azure.AI.Projects.AgentTelephony.getTelephonyCall", + "azure.ai.projects.aio.operations.AgentsOperations.get_telephony_call": "Azure.AI.Projects.AgentTelephony.getTelephonyCall", + "azure.ai.projects.operations.AgentsOperations.transfer_telephony_call": "Azure.AI.Projects.AgentTelephony.transferTelephonyCall", + "azure.ai.projects.aio.operations.AgentsOperations.transfer_telephony_call": "Azure.AI.Projects.AgentTelephony.transferTelephonyCall", + "azure.ai.projects.operations.AgentsOperations.end_telephony_call": "Azure.AI.Projects.AgentTelephony.endTelephonyCall", + "azure.ai.projects.aio.operations.AgentsOperations.end_telephony_call": "Azure.AI.Projects.AgentTelephony.endTelephonyCall", + "azure.ai.projects.operations.AgentsOperations.get_telephony_transfer_targets": "Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets", + "azure.ai.projects.aio.operations.AgentsOperations.get_telephony_transfer_targets": "Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets", + "azure.ai.projects.operations.AgentsOperations.replace_telephony_transfer_targets": "Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets", + "azure.ai.projects.aio.operations.AgentsOperations.replace_telephony_transfer_targets": "Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets", "azure.ai.projects.operations.AgentsOperations.upload_session_file": "Azure.AI.Projects.AgentSessionFiles.uploadSessionFile", "azure.ai.projects.aio.operations.AgentsOperations.upload_session_file": "Azure.AI.Projects.AgentSessionFiles.uploadSessionFile", "azure.ai.projects.operations.AgentsOperations.download_session_file": "Azure.AI.Projects.AgentSessionFiles.downloadSessionFile", @@ -590,6 +894,62 @@ "azure.ai.projects.aio.operations.IndexesOperations.delete": "Azure.AI.Projects.Indexes.deleteVersion", "azure.ai.projects.operations.IndexesOperations.create_or_update": "Azure.AI.Projects.Indexes.createOrUpdateVersion", "azure.ai.projects.aio.operations.IndexesOperations.create_or_update": "Azure.AI.Projects.Indexes.createOrUpdateVersion", + "azure.ai.projects.operations.VoiceAgentWebSocketOperations.connect_voice_agent": "Azure.AI.Projects.VoiceAgentWebSocket.connectVoiceAgent", + "azure.ai.projects.aio.operations.VoiceAgentWebSocketOperations.connect_voice_agent": "Azure.AI.Projects.VoiceAgentWebSocket.connectVoiceAgent", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.list_agent_conversations": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversations", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.list_agent_conversations": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversations", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversation", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversation", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.delete_agent_conversation": "Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.delete_agent_conversation": "Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.list_agent_conversation_responses": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.list_agent_conversation_responses": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_response": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_response": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.list_agent_conversation_response_items": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.list_agent_conversation_response_items": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.list_agent_conversation_items": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.list_agent_conversation_items": "Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_item": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_item": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemAudio", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemAudio", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemAudioContent", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemAudioContent", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_generated_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemGeneratedAudio", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_generated_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemGeneratedAudio", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_generated_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemGeneratedAudioContent", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_item_generated_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItemGeneratedAudioContent", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_audio": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio", + "azure.ai.projects.operations.AgentEndpointConversationsOperations.get_agent_conversation_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent", + "azure.ai.projects.aio.operations.AgentEndpointConversationsOperations.get_agent_conversation_audio_content": "Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent", + "azure.ai.projects.operations.AgentTelephonyOperations.create_telephony_call_job": "Azure.AI.Projects.AgentTelephony.createTelephonyCallJob", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.create_telephony_call_job": "Azure.AI.Projects.AgentTelephony.createTelephonyCallJob", + "azure.ai.projects.operations.AgentTelephonyOperations.get_telephony_call_job": "Azure.AI.Projects.AgentTelephony.getTelephonyCallJob", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.get_telephony_call_job": "Azure.AI.Projects.AgentTelephony.getTelephonyCallJob", + "azure.ai.projects.operations.AgentTelephonyOperations.cancel_telephony_call_job": "Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.cancel_telephony_call_job": "Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob", + "azure.ai.projects.operations.AgentTelephonyOperations.create_telephony_campaign": "Azure.AI.Projects.AgentTelephony.createTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.create_telephony_campaign": "Azure.AI.Projects.AgentTelephony.createTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.get_telephony_campaign": "Azure.AI.Projects.AgentTelephony.getTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.get_telephony_campaign": "Azure.AI.Projects.AgentTelephony.getTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.begin_import_telephony_campaign_recipients": "Azure.AI.Projects.AgentTelephony.importTelephonyCampaignRecipients", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.begin_import_telephony_campaign_recipients": "Azure.AI.Projects.AgentTelephony.importTelephonyCampaignRecipients", + "azure.ai.projects.operations.AgentTelephonyOperations.get_telephony_campaign_recipient_import": "Azure.AI.Projects.AgentTelephony.getTelephonyCampaignRecipientImport", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.get_telephony_campaign_recipient_import": "Azure.AI.Projects.AgentTelephony.getTelephonyCampaignRecipientImport", + "azure.ai.projects.operations.AgentTelephonyOperations.begin_validate_telephony_campaign": "Azure.AI.Projects.AgentTelephony.validateTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.begin_validate_telephony_campaign": "Azure.AI.Projects.AgentTelephony.validateTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.begin_publish_telephony_campaign": "Azure.AI.Projects.AgentTelephony.publishTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.begin_publish_telephony_campaign": "Azure.AI.Projects.AgentTelephony.publishTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.pause_telephony_campaign": "Azure.AI.Projects.AgentTelephony.pauseTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.pause_telephony_campaign": "Azure.AI.Projects.AgentTelephony.pauseTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.resume_telephony_campaign": "Azure.AI.Projects.AgentTelephony.resumeTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.resume_telephony_campaign": "Azure.AI.Projects.AgentTelephony.resumeTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.cancel_telephony_campaign": "Azure.AI.Projects.AgentTelephony.cancelTelephonyCampaign", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.cancel_telephony_campaign": "Azure.AI.Projects.AgentTelephony.cancelTelephonyCampaign", + "azure.ai.projects.operations.AgentTelephonyOperations.get_telephony_operation": "Azure.AI.Projects.AgentTelephony.getTelephonyOperation", + "azure.ai.projects.aio.operations.AgentTelephonyOperations.get_telephony_operation": "Azure.AI.Projects.AgentTelephony.getTelephonyOperation", "azure.ai.projects.operations.ToolboxesOperations.create_version": "Azure.AI.Projects.Toolboxes.createToolboxVersion", "azure.ai.projects.aio.operations.ToolboxesOperations.create_version": "Azure.AI.Projects.Toolboxes.createToolboxVersion", "azure.ai.projects.operations.ToolboxesOperations.get": "Azure.AI.Projects.Toolboxes.getToolbox", @@ -607,5 +967,5 @@ "azure.ai.projects.operations.ToolboxesOperations.delete_version": "Azure.AI.Projects.Toolboxes.deleteToolboxVersion", "azure.ai.projects.aio.operations.ToolboxesOperations.delete_version": "Azure.AI.Projects.Toolboxes.deleteToolboxVersion" }, - "CrossLanguageVersion": "4a45c56db1c7" + "CrossLanguageVersion": "d6ddc3e85c2a" } \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/assets.json b/sdk/ai/azure-ai-projects/assets.json index caef94c4b521..7ea3407bf008 100644 --- a/sdk/ai/azure-ai-projects/assets.json +++ b/sdk/ai/azure-ai-projects/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/ai/azure-ai-projects", - "Tag": "python/ai/azure-ai-projects_80e35fe70b" + "Tag": "python/ai/azure-ai-projects_d1480b3c35" } diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_client.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_client.py index 7052e3b647c9..433a5a41ddd8 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_client.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_client.py @@ -17,6 +17,8 @@ from ._configuration import AIProjectClientConfiguration from ._utils.serialization import Deserializer, Serializer from .operations import ( + AgentEndpointConversationsOperations, + AgentTelephonyOperations, AgentsOperations, BetaOperations, ConnectionsOperations, @@ -53,6 +55,11 @@ class AIProjectClient: # pylint: disable=too-many-instance-attributes,docstring :vartype deployments: azure.ai.projects.operations.DeploymentsOperations :ivar indexes: IndexesOperations operations :vartype indexes: azure.ai.projects.operations.IndexesOperations + :ivar agent_endpoint_conversations: AgentEndpointConversationsOperations operations + :vartype agent_endpoint_conversations: + azure.ai.projects.operations.AgentEndpointConversationsOperations + :ivar agent_telephony: AgentTelephonyOperations operations + :vartype agent_telephony: azure.ai.projects.operations.AgentTelephonyOperations :ivar toolboxes: ToolboxesOperations operations :vartype toolboxes: azure.ai.projects.operations.ToolboxesOperations :param endpoint: Foundry Project endpoint in the form @@ -113,6 +120,10 @@ def __init__( self.datasets = DatasetsOperations(self._client, self._config, self._serialize, self._deserialize) self.deployments = DeploymentsOperations(self._client, self._config, self._serialize, self._deserialize) self.indexes = IndexesOperations(self._client, self._config, self._serialize, self._deserialize) + self.agent_endpoint_conversations = AgentEndpointConversationsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.agent_telephony = AgentTelephonyOperations(self._client, self._config, self._serialize, self._deserialize) self.toolboxes = ToolboxesOperations(self._client, self._config, self._serialize, self._deserialize) def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py index 747660cf3f4f..742e58e3bc3c 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py @@ -19,7 +19,17 @@ from azure.identity import get_bearer_token_provider from ._client import AIProjectClient as AIProjectClientGenerated from .operations import TelemetryOperations +from .operations._patch import _OperationMethodHeaderProxy +from .models._enums import _AgentDefinitionOptInKeys from .models._patch import _BETA_OPERATION_FEATURE_HEADERS, _FOUNDRY_FEATURES_HEADER_NAME, _has_header_case_insensitive +from ._realtime import ( + Realtime, + RealtimeConnection, + RealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) _OPENAI_TRANSPORT_LOGGER_NAME = "azure.ai.projects.openai_transport" logger = logging.getLogger(__name__) @@ -238,7 +248,37 @@ def __init__( super().__init__(endpoint=endpoint, credential=credential, allow_preview=allow_preview, **kwargs) + if allow_preview: + setattr( + self, + "agent_telephony", + _OperationMethodHeaderProxy( + self.agent_telephony, + _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value, + ), + ) + self.telemetry = TelemetryOperations(self) # type: ignore + self._realtime: Optional[Realtime] = None + # NOTE: voice-agent conversation reads (`agent_endpoint_conversations`) have round-tripped + # between living directly on `self` (top-level) and being nested under `self.beta` across + # several upstream TypeSpec regenerations. It is currently back to being a top-level, + # stable client attribute again -- its VoiceAgents=V1Preview opt-in header injection is + # handled per-method (gated behind `allow_preview`) in + # `operations/_patch_agent_endpoint_conversations.py`, not by + # `_BETA_OPERATION_FEATURE_HEADERS`/`BetaOperations.__init__` (which only applies to + # `.beta`'s sub-clients). + + @property + def realtime(self) -> Realtime: + """Realtime streaming entry point for voice agents. + + :return: The realtime namespace, exposing ``connect(...)``. + :rtype: ~azure.ai.projects.Realtime + """ + if self._realtime is None: + self._realtime = Realtime(self) + return self._realtime def _get_openai_api_key(self, kwargs: dict): """Resolve the API key for the OpenAI client. @@ -268,7 +308,9 @@ def _get_openai_http_client(self, kwargs: dict): logging_kwargs = getattr(self, "_kwargs", {}) logging_enabled = bool(logging_kwargs.get("logging_enable", False)) - return DefaultHttpxClient(transport=_OpenAILoggingTransport(logging_enabled=logging_enabled)) + return DefaultHttpxClient( + transport=_OpenAILoggingTransport(logging_enabled=logging_enabled) + ) # type: ignore[arg-type] @distributed_trace def get_openai_client( @@ -501,6 +543,12 @@ def _log_request_body(self, request: httpx2.Request) -> None: __all__: List[str] = [ "AIProjectClient", + "Realtime", + "RealtimeConnection", + "RealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.pyi b/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.pyi index 48e25bc97418..b4bb8823374f 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.pyi +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_patch.pyi @@ -34,6 +34,14 @@ from openai.types.eval_create_response import EvalCreateResponse from openai.types.shared_params.metadata import Metadata from ._client import AIProjectClient as AIProjectClientGenerated from .operations import TelemetryOperations +from ._realtime import ( + Realtime, + RealtimeConnection, + RealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) from .models import ( AzureAIBenchmarkPreviewEvalRunDataSource, AzureAIDataSourceConfig, @@ -46,7 +54,7 @@ from .models import ( ) class _AzureEvalRuns(Runs): - def create( + def create( # type: ignore[reportIncompatibleMethodOverride] self, eval_id: str, *, @@ -70,7 +78,7 @@ class _AzureEvalRuns(Runs): ) -> RunCreateResponse: ... class _AzureEvals(Evals): - def create( + def create( # type: ignore[reportIncompatibleMethodOverride] self, *, data_source_config: Union[ @@ -102,6 +110,8 @@ class OpenAI(OpenAIClient): class AIProjectClient(AIProjectClientGenerated): telemetry: TelemetryOperations + @property + def realtime(self) -> Realtime: ... def get_openai_client( self, agent_name: Optional[str] = None, **kwargs: Any # pylint: disable=unused-argument ) -> OpenAI: ... @@ -126,6 +136,14 @@ def _resolve_openai_default_headers(agent_name: Optional[str], kwargs: dict) -> def _build_openai_user_agent(custom_user_agent: Optional[str], openai_default_user_agent: str) -> str: ... def _log_streaming_response_notice(logging_enabled: bool) -> bool: ... -__all__: List[str] = ["AIProjectClient"] +__all__: List[str] = [ + "AIProjectClient", + "Realtime", + "RealtimeConnection", + "RealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] def patch_sdk() -> None: ... diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py new file mode 100644 index 000000000000..ad7b8c335369 --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py @@ -0,0 +1,871 @@ +# pylint: disable=networking-import-outside-azure-core-transport +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- +"""Hand-written sync realtime (WebSocket) streaming client for voice agents. + +This is the synchronous counterpart of :mod:`azure.ai.projects.aio._realtime`. See that +module's docstring for the full design rationale; the two modules are kept structurally +identical (sync method names drop the ``async``/``await`` keywords) so fixes/features land in +both at once. + +``websockets`` is required for this feature and is *not* a hard dependency of the package; it +is imported lazily so importing the SDK never fails when it is absent. +""" + +from __future__ import annotations + +import base64 +import json +from urllib.parse import urlencode, urlparse +from typing import ( + Any, + Dict, + Iterator, + List, + Mapping, + Optional, + Tuple, + Type, + TYPE_CHECKING, + Union, + cast, +) + +from azure.core.pipeline.policies import UserAgentPolicy + +from . import models as _models +from .models._enums import _AgentDefinitionOptInKeys +from .models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _has_header_case_insensitive +from ._utils.model_base import Model as _Model, SdkJSONEncoder +from ._version import VERSION + +# Scoped to just the voice-agent preview opt-in; callers connecting to other preview agent +# kinds through this same route can pass a broader value explicitly via ``foundry_features``. +_VOICE_AGENT_FEATURE_HEADER: str = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + +# Identifies the SDK to the service on the WebSocket handshake, which otherwise falls back to +# the underlying `websockets` library's generic default (the generated HTTP surface gets this +# for free from the pipeline's own UserAgentPolicy; this hand-written client builds its own +# request instead, so it needs to opt in explicitly the same way). +_USER_AGENT: str = UserAgentPolicy(sdk_moniker=f"ai-projects/{VERSION}").user_agent + +if TYPE_CHECKING: + from websockets.sync.client import ClientConnection + from azure.core.credentials import TokenCredential + + from ._client import AIProjectClient + + +__all__ = [ + "Realtime", + "RealtimeConnection", + "RealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] + +# Union of the client event models sendable over the connection, plus a raw mapping escape +# hatch for forward compatibility with event types not yet represented in the generated models. +ClientEvent = Union[ + _models.RealtimeClientEventConversationItemCreate, + _models.RealtimeClientEventConversationItemDelete, + _models.RealtimeClientEventConversationItemRetrieve, + _models.RealtimeClientEventConversationItemTruncate, + _models.RealtimeClientEventInputAudioBufferAppend, + _models.RealtimeClientEventInputAudioBufferClear, + _models.RealtimeClientEventInputAudioBufferCommit, + _models.RealtimeClientEventOutputAudioBufferClear, + _models.RealtimeClientEventResponseCancel, + _models.RealtimeClientEventResponseCreate, + _models.VoiceAgentClientEventRtcCallSdpCreate, + _models.VoiceAgentClientEventSessionAvatarConnect, + _models.VoiceAgentClientEventSessionUpdate, + str, + Mapping[str, Any], +] + +# The conversation item variants accepted by ``conversation.item.create``. +ConversationItem = Union[ + _models.RealtimeConversationItemMessageSystem, + _models.RealtimeConversationItemMessageUser, + _models.RealtimeConversationItemMessageAssistant, + _models.RealtimeConversationItemFunctionCall, + _models.RealtimeConversationItemFunctionCallOutput, + _models.RealtimeMCPApprovalResponse, + Mapping[str, Any], +] + +# Every server event ``type`` string mapped to its generated model, used to deserialize +# inbound frames into strongly-typed objects. Event types not represented by a dedicated +# generated model in this package (for example ``conversation.created``) are intentionally +# left out here and fall back to a plain ``dict``, as do any newly-added service events. +_SERVER_EVENT_TYPES: Dict[str, Type[_Model]] = { + "conversation.item.added": _models.RealtimeServerEventConversationItemAdded, + "conversation.item.created": _models.RealtimeServerEventConversationItemCreated, + "conversation.item.deleted": _models.RealtimeServerEventConversationItemDeleted, + "conversation.item.done": _models.RealtimeServerEventConversationItemDone, + "conversation.item.input_audio_transcription.completed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted + ), + "conversation.item.input_audio_transcription.delta": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta + ), + "conversation.item.input_audio_transcription.failed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed + ), + "conversation.item.input_audio_transcription.segment": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment + ), + "conversation.item.retrieved": _models.RealtimeServerEventConversationItemRetrieved, + "conversation.item.truncated": _models.RealtimeServerEventConversationItemTruncated, + # Shared OpenAI-style Realtime error event (not voice-agent specific in this package). + "error": _models.RealtimeServerEventError, + "input_audio_buffer.cleared": _models.RealtimeServerEventInputAudioBufferCleared, + "input_audio_buffer.committed": _models.RealtimeServerEventInputAudioBufferCommitted, + "input_audio_buffer.speech_started": _models.RealtimeServerEventInputAudioBufferSpeechStarted, + "input_audio_buffer.speech_stopped": _models.RealtimeServerEventInputAudioBufferSpeechStopped, + "input_audio_buffer.timeout_triggered": (_models.RealtimeServerEventInputAudioBufferTimeoutTriggered), + "mcp_list_tools.completed": _models.RealtimeServerEventMCPListToolsCompleted, + "mcp_list_tools.failed": _models.RealtimeServerEventMCPListToolsFailed, + "mcp_list_tools.in_progress": _models.RealtimeServerEventMCPListToolsInProgress, + "output_audio_buffer.cleared": _models.RealtimeServerEventOutputAudioBufferCleared, + "rate_limits.updated": _models.RealtimeServerEventRateLimitsUpdated, + "response.animation_blendshapes.delta": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDelta), + "response.animation_blendshapes.done": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDone), + "response.animation_viseme.delta": _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + "response.animation_viseme.done": _models.VoiceAgentServerEventResponseAnimationVisemeDone, + "response.audio_timestamp.delta": _models.VoiceAgentServerEventResponseAudioTimestampDelta, + "response.audio_timestamp.done": _models.VoiceAgentServerEventResponseAudioTimestampDone, + "response.content_part.added": _models.RealtimeServerEventResponseContentPartAdded, + "response.content_part.done": _models.RealtimeServerEventResponseContentPartDone, + "response.created": _models.RealtimeServerEventResponseCreated, + "response.done": _models.RealtimeServerEventResponseDone, + "response.function_call_arguments.delta": (_models.RealtimeServerEventResponseFunctionCallArgumentsDelta), + "response.function_call_arguments.done": (_models.RealtimeServerEventResponseFunctionCallArgumentsDone), + "response.mcp_call.completed": _models.RealtimeServerEventResponseMCPCallCompleted, + "response.mcp_call.failed": _models.RealtimeServerEventResponseMCPCallFailed, + "response.mcp_call.in_progress": _models.RealtimeServerEventResponseMCPCallInProgress, + "response.mcp_call_arguments.delta": _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + "response.mcp_call_arguments.done": _models.RealtimeServerEventResponseMCPCallArgumentsDone, + "response.output_audio.delta": _models.RealtimeServerEventResponseAudioDelta, + "response.output_audio.done": _models.RealtimeServerEventResponseAudioDone, + "response.output_audio_transcript.delta": (_models.RealtimeServerEventResponseAudioTranscriptDelta), + "response.output_audio_transcript.done": (_models.RealtimeServerEventResponseAudioTranscriptDone), + "response.output_item.added": _models.RealtimeServerEventResponseOutputItemAdded, + "response.output_item.done": _models.RealtimeServerEventResponseOutputItemDone, + "response.output_text.delta": _models.RealtimeServerEventResponseTextDelta, + "response.output_text.done": _models.RealtimeServerEventResponseTextDone, + "response.video.delta": _models.VoiceAgentServerEventResponseVideoDelta, + "rtc.call.error": _models.VoiceAgentServerEventRtcCallError, + "rtc.call.sdp.created": _models.VoiceAgentServerEventRtcCallSdpCreated, + "session.avatar.connecting": _models.VoiceAgentServerEventSessionAvatarConnecting, + "session.avatar.switch_to_idle": _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + "session.avatar.switch_to_speaking": _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + "session.created": _models.RealtimeServerEventSessionCreated, + "session.subagent.aborted": _models.VoiceAgentServerEventSessionSubagentAborted, + "session.subagent.completed": _models.VoiceAgentServerEventSessionSubagentCompleted, + "session.subagent.started": _models.VoiceAgentServerEventSessionSubagentStarted, + "session.updated": _models.RealtimeServerEventSessionUpdated, + "warning": _models.VoiceAgentServerEventWarning, +} + +# Every generated server event model, for consumers that want a precise return type. +ServerEvent = Union[ + _models.RealtimeServerEventError, + _models.RealtimeServerEventResponseContentPartAdded, + _models.RealtimeServerEventConversationItemAdded, + _models.RealtimeServerEventConversationItemCreated, + _models.RealtimeServerEventConversationItemDeleted, + _models.RealtimeServerEventConversationItemDone, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + _models.RealtimeServerEventConversationItemRetrieved, + _models.RealtimeServerEventConversationItemTruncated, + _models.RealtimeServerEventInputAudioBufferCleared, + _models.RealtimeServerEventInputAudioBufferCommitted, + _models.RealtimeServerEventInputAudioBufferSpeechStarted, + _models.RealtimeServerEventInputAudioBufferSpeechStopped, + _models.RealtimeServerEventInputAudioBufferTimeoutTriggered, + _models.RealtimeServerEventMCPListToolsCompleted, + _models.RealtimeServerEventMCPListToolsFailed, + _models.RealtimeServerEventMCPListToolsInProgress, + _models.RealtimeServerEventOutputAudioBufferCleared, + _models.RealtimeServerEventRateLimitsUpdated, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDelta, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDone, + _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + _models.VoiceAgentServerEventResponseAnimationVisemeDone, + _models.RealtimeServerEventResponseAudioDelta, + _models.RealtimeServerEventResponseAudioDone, + _models.VoiceAgentServerEventResponseAudioTimestampDelta, + _models.VoiceAgentServerEventResponseAudioTimestampDone, + _models.RealtimeServerEventResponseAudioTranscriptDelta, + _models.RealtimeServerEventResponseAudioTranscriptDone, + _models.RealtimeServerEventResponseContentPartDone, + _models.RealtimeServerEventResponseCreated, + _models.RealtimeServerEventResponseDone, + _models.RealtimeServerEventResponseFunctionCallArgumentsDelta, + _models.RealtimeServerEventResponseFunctionCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + _models.RealtimeServerEventResponseMCPCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallCompleted, + _models.RealtimeServerEventResponseMCPCallFailed, + _models.RealtimeServerEventResponseMCPCallInProgress, + _models.RealtimeServerEventResponseOutputItemAdded, + _models.RealtimeServerEventResponseOutputItemDone, + _models.RealtimeServerEventResponseTextDelta, + _models.RealtimeServerEventResponseTextDone, + _models.VoiceAgentServerEventResponseVideoDelta, + _models.VoiceAgentServerEventRtcCallError, + _models.VoiceAgentServerEventRtcCallSdpCreated, + _models.VoiceAgentServerEventSessionAvatarConnecting, + _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + _models.RealtimeServerEventSessionCreated, + _models.VoiceAgentServerEventSessionSubagentAborted, + _models.VoiceAgentServerEventSessionSubagentCompleted, + _models.VoiceAgentServerEventSessionSubagentStarted, + _models.RealtimeServerEventSessionUpdated, + _models.VoiceAgentServerEventWarning, + Mapping[str, Any], +] + + +def _to_ws_url(endpoint: str, agent_name: str) -> str: + """Build the realtime WebSocket URL from the HTTPS project endpoint. + + Only the ``https://`` scheme is translated (to ``wss://``); any other scheme is left + unchanged so that :meth:`RealtimeConnectionManager.enter`'s ``wss://``-only check rejects + it with a clear error instead of silently producing an unencrypted ``ws://`` URL that would + also send the live Authorization token in plain text. + + :param str endpoint: The Foundry project endpoint (``https://.../api/projects/...``). + :param str agent_name: The name of the voice agent to connect to. + :return: A ``wss://`` URL targeting the realtime route. + :rtype: str + """ + base = endpoint.rstrip("/") + if base.startswith("https://"): + base = "wss://" + base[len("https://") :] + return f"{base}/agents/{agent_name}/endpoint/protocols/voice" + + +_DEFAULT_PORT_BY_SCHEME = {"http": 80, "https": 443, "ws": 80, "wss": 443} + + +def _normalized_authority(url: str) -> Tuple[str, Optional[int]]: + """Return a ``(hostname, port)`` tuple with the scheme's default port filled in. + + ``urlparse(...).port`` is ``None`` when a URL omits an explicit port, which would make + ``https://host/...`` and ``https://host:8443/...`` compare as equal on hostname alone. + Resolving the scheme's default port here lets callers compare authorities (not just + hostnames) so a same-host override on a different, non-default port is correctly rejected. + + :param str url: The URL to parse. + :return: A tuple of the lower-cased hostname (or empty string) and the resolved port + (or ``None`` if the scheme has no known default and none was specified). + :rtype: tuple[str, Optional[int]] + """ + parsed = urlparse(url) + port = parsed.port + if port is None: + port = _DEFAULT_PORT_BY_SCHEME.get((parsed.scheme or "").lower()) + return (parsed.hostname or "").lower(), port + + +def _assert_trusted_connection_url(connection_url: str, endpoint: str) -> None: + """Guard against attaching the caller's Entra bearer token to an untrusted host. + + ``connection_url`` is an escape hatch that lets a caller override the computed + scheme/host/path, but the Authorization header carrying the live credential's + token must never be sent to a host other than the configured Foundry project + endpoint: a caller-controlled or compromised URL could otherwise be used to + exfiltrate the token to an arbitrary host or port. + + :param str connection_url: The caller-supplied override URL. + :param str endpoint: The configured, trusted Foundry project endpoint. + :raises ValueError: If the override URL's host or port does not match the endpoint's. + """ + override_host, override_port = _normalized_authority(connection_url) + trusted_host, trusted_port = _normalized_authority(endpoint) + if not override_host or (override_host, override_port) != (trusted_host, trusted_port): + got = override_host or connection_url + if override_host and override_port: + got = f"{override_host}:{override_port}" + raise ValueError( + "The 'connection_url' override must target the same host and port as the configured " + f"Foundry project endpoint ('{trusted_host}:{trusted_port}') to avoid sending the " + f"Authorization token to an untrusted host; got '{got}'." + ) + + +class _BaseResource: # pylint: disable=too-few-public-methods + """Base helper that forwards typed helpers to the parent connection.""" + + def __init__(self, connection: "RealtimeConnection") -> None: + self._connection = connection + + def _send(self, event: ClientEvent) -> None: + self._connection.send(event) + + +class SessionResource(_BaseResource): + """Send ``session.*`` client events.""" + + def update( + self, + *, + session: Union["_models.VoiceAgentSessionUpdateConfig", Mapping[str, Any]], + event_id: Optional[str] = None, + ) -> None: + """Update the realtime session configuration. + + :keyword session: The session configuration to apply. + :paramtype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig or + Mapping[str, Any] + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.VoiceAgentClientEventSessionUpdate)( + type=_models.RealtimeClientEventType.SESSION_UPDATE, + session=session, + event_id=event_id, + ) + ) + + def avatar_connect(self, *, client_sdp: str, event_id: Optional[str] = None) -> None: + """Negotiate an avatar media session over WebRTC. + + :keyword str client_sdp: The client's SDP offer for avatar media negotiation. + :keyword event_id: An optional client-generated event identifier. + :paramtype event_id: str or None + """ + self._send( + _models.VoiceAgentClientEventSessionAvatarConnect( + client_sdp=client_sdp, + event_id=event_id, + ) + ) + + +class InputAudioBufferResource(_BaseResource): + """Send ``input_audio_buffer.*`` client events.""" + + def append(self, *, audio: Union[str, bytes], event_id: Optional[str] = None) -> None: + """Append audio bytes to the input buffer. + + :keyword audio: Raw audio bytes, or an already base64-encoded string. + :paramtype audio: str or bytes + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + if isinstance(audio, (bytes, bytearray)): + audio = base64.b64encode(bytes(audio)).decode("ascii") + self._send( + _models.RealtimeClientEventInputAudioBufferAppend( + audio=audio, + event_id=event_id, + ) + ) + + def commit(self, *, event_id: Optional[str] = None) -> None: + """Commit the buffered input audio as a user turn. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventInputAudioBufferCommit(event_id=event_id)) + + def clear(self, *, event_id: Optional[str] = None) -> None: + """Discard any buffered input audio. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventInputAudioBufferClear(event_id=event_id)) + + +class OutputAudioBufferResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``output_audio_buffer.*`` client events.""" + + def clear(self, *, event_id: Optional[str] = None) -> None: + """Stop and clear any audio the service is currently playing back (barge-in). + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventOutputAudioBufferClear(event_id=event_id)) + + +class ConversationItemResource(_BaseResource): + """Send ``conversation.item.*`` client events.""" + + def create( + self, + *, + item: ConversationItem, + previous_item_id: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: + """Insert an item into the conversation. + + :keyword item: The conversation item to create. + :paramtype item: ~azure.ai.projects.models.RealtimeConversationItemMessageSystem or + ~azure.ai.projects.models.RealtimeConversationItemMessageUser or + ~azure.ai.projects.models.RealtimeConversationItemMessageAssistant or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCall or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput or + ~azure.ai.projects.models.RealtimeMCPApprovalResponse or Mapping[str, Any] + :keyword previous_item_id: The ID of the preceding item after which the new item will be + inserted. Default value is None. + :paramtype previous_item_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.RealtimeClientEventConversationItemCreate)( + item=item, + previous_item_id=previous_item_id, + event_id=event_id, + ) + ) + + def delete(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Delete an item from the conversation. + + :keyword str item_id: The ID of the item to delete. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemDelete( + item_id=item_id, + event_id=event_id, + ) + ) + + def retrieve(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Ask the server to emit a ``conversation.item.retrieved`` event for an item. + + :keyword str item_id: The ID of the item to retrieve. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemRetrieve( + item_id=item_id, + event_id=event_id, + ) + ) + + def truncate(self, *, item_id: str, content_index: int, audio_end_ms: int, event_id: Optional[str] = None) -> None: + """Truncate a previously produced assistant audio item (used for barge-in). + + :keyword str item_id: The ID of the assistant message item to truncate. + :keyword int content_index: The index of the content part to truncate. Use ``0``. + :keyword int audio_end_ms: The point, in milliseconds, to truncate the audio to. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemTruncate( + item_id=item_id, + content_index=content_index, + audio_end_ms=audio_end_ms, + event_id=event_id, + ) + ) + + +class ConversationResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``conversation.*`` client events.""" + + def __init__(self, connection: "RealtimeConnection") -> None: + super().__init__(connection) + self.item: ConversationItemResource = ConversationItemResource(connection) + + +class ResponseResource(_BaseResource): + """Send ``response.*`` client events.""" + + def create( + self, + *, + response: Optional[Union["_models.VoiceAgentResponseCreateParams", Mapping[str, Any]]] = None, + event_id: Optional[str] = None, + ) -> None: + """Ask the model to generate a response. + + :keyword response: Optional per-response overrides. Default value is None. + :paramtype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams or + Mapping[str, Any] or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.RealtimeClientEventResponseCreate)( + response=response, + event_id=event_id, + ) + ) + + def cancel(self, *, response_id: Optional[str] = None, event_id: Optional[str] = None) -> None: + """Cancel an in-progress response. + + :keyword response_id: The ID of the response to cancel, if targeting a specific one. + Default value is None. + :paramtype response_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventResponseCancel( + response_id=response_id, + event_id=event_id, + ) + ) + + +class RealtimeConnection: # pylint: disable=too-many-instance-attributes + """An open realtime WebSocket connection to a voice agent. + + Iterate over the connection to receive strongly-typed server events, and use the + sub-namespaces to send strongly-typed client events:: + + with client.realtime.connect(agent_name="my-agent") as conn: + conn.input_audio_buffer.append(audio=chunk) + conn.input_audio_buffer.commit() + conn.response.create() + for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + """ + + def __init__(self, connection: "ClientConnection") -> None: + self._connection = connection + self._closed = False + self.session: SessionResource = SessionResource(self) + self.input_audio_buffer: InputAudioBufferResource = InputAudioBufferResource(self) + self.output_audio_buffer: OutputAudioBufferResource = OutputAudioBufferResource(self) + self.conversation: ConversationResource = ConversationResource(self) + self.response: ResponseResource = ResponseResource(self) + + def __enter__(self) -> "RealtimeConnection": + return self + + def __exit__(self, *exc_details: Any) -> None: + self.close() + + def __repr__(self) -> str: + state = "closed" if self.closed else "open" + return f"" + + @property + def closed(self) -> bool: + """Whether the underlying WebSocket connection has been closed. + + :rtype: bool + """ + return self._closed + + def __iter__(self) -> Iterator[ServerEvent]: + return self._iter() + + def _iter(self) -> Iterator[ServerEvent]: + while True: + try: + yield self.recv() + except ConnectionResetError: + return + + def recv(self, *, timeout: Optional[float] = None) -> ServerEvent: + """Receive and parse the next server event. + + Known event types are returned as their strongly-typed + ``VoiceAgentServerEventXxx`` model. Event types not (yet) represented by a + generated model are returned as a plain ``dict`` for forward compatibility. + + :keyword timeout: Maximum time in seconds to wait for the next event. If ``None`` + (the default), block until an event is received. If no event arrives within + ``timeout`` seconds, raise :exc:`TimeoutError`. + :paramtype timeout: float or None + :return: The parsed server event. + :rtype: ~azure.ai.projects.ServerEvent + :raises ConnectionResetError: If the connection was closed by the server. + :raises TimeoutError: If ``timeout`` elapses before an event is received. + """ + from websockets.exceptions import ConnectionClosed # pylint: disable=import-outside-toplevel + + try: + raw = self._connection.recv(timeout=timeout) + except ConnectionClosed as exc: + self._closed = True + raise ConnectionResetError("The realtime connection was closed.") from exc + data = raw.decode("utf-8") if isinstance(raw, (bytes, bytearray)) else raw + payload: Dict[str, Any] = json.loads(data) + event_type = payload.get("type") + if not isinstance(event_type, str): + return payload + event_cls = _SERVER_EVENT_TYPES.get(event_type) + if event_cls is None: + return payload + return event_cls(payload) + + def send(self, event: ClientEvent) -> None: + """Send a client event over the connection. + + :param event: A strongly-typed client event, a ready-made mapping, or a raw JSON string. + :type event: ~azure.ai.projects.ClientEvent or str + :raises ValueError: If ``event`` is a ``str`` that is not valid JSON. + """ + if isinstance(event, str): + try: + json.loads(event) + except ValueError as exc: + raise ValueError(f"'event' is not valid JSON: {exc}") from exc + payload = event + else: + payload = json.dumps(event, cls=SdkJSONEncoder) + self._connection.send(payload) + + def close(self, *, code: int = 1000, reason: str = "") -> None: + """Close the connection. + + :keyword int code: The WebSocket close code. + :keyword str reason: The close reason. + """ + if self._closed: + return + try: + self._connection.close(code=code, reason=reason) + finally: + self._closed = True + + +class RealtimeConnectionManager: # pylint: disable=too-many-instance-attributes + """Context manager that opens a :class:`RealtimeConnection`. + + Returned by :meth:`Realtime.connect`; you normally use it as + ``with client.realtime.connect(...) as conn:``. + """ + + def __init__( # pylint: disable=too-many-arguments + self, + *, + endpoint: str, + credential: "TokenCredential", + credential_scopes: List[str], + api_version: str, + agent_name: str, + foundry_features: str, + agent_session_id: Optional[str] = None, + agent_version_override: Optional[str] = None, + structured_inputs: Optional[str] = None, + connection_url: Optional[str] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> None: + self._endpoint = endpoint + self._credential = credential + self._credential_scopes = credential_scopes + self._api_version = api_version + self._agent_name = agent_name + self._foundry_features = foundry_features + self._agent_session_id = agent_session_id + self._agent_version_override = agent_version_override + self._structured_inputs = structured_inputs + self._connection_url = connection_url + self._extra_query = dict(extra_query or {}) + self._extra_headers = dict(extra_headers or {}) + self._kwargs = kwargs + self._connection: Optional[RealtimeConnection] = None + + def __enter__(self) -> RealtimeConnection: + return self.enter() + + def enter(self) -> RealtimeConnection: # pylint: disable=too-many-locals + """Open the connection. + + :return: The live realtime connection. + :rtype: ~azure.ai.projects.RealtimeConnection + :raises RuntimeError: If ``websockets`` is not installed. + :raises ValueError: If the computed or supplied WebSocket URL does not use ``wss://``. + :raises ConnectionError: If the WebSocket upgrade handshake fails (for example, a + network error, DNS failure, or a non-101 response from the service). + """ + try: + from websockets.sync.client import connect as _ws_connect # pylint: disable=import-outside-toplevel + from websockets.typing import Subprotocol # pylint: disable=import-outside-toplevel + except ImportError as exc: # pragma: no cover - dependency guard + raise RuntimeError( + "The realtime client requires `websockets`. Install it with `pip install websockets`." + ) from exc + + # ``connection_url`` fully overrides the computed route (scheme/host/path). This is the + # escape hatch used to reach a specific data-plane host/path directly. + if self._connection_url is not None: + _assert_trusted_connection_url(self._connection_url, self._endpoint) + url = self._connection_url or _to_ws_url(self._endpoint, self._agent_name) + if not url.startswith("wss://"): + raise ValueError("The realtime WebSocket URL must use wss:// to protect credentials in transit.") + + params: Dict[str, str] = {"api-version": self._api_version, "x-ms-client-sdk": _USER_AGENT} + if self._agent_session_id is not None: + params["agent_session_id"] = self._agent_session_id + if self._agent_version_override is not None: + params["x-agent-version-override"] = self._agent_version_override + params.update(self._extra_query) + + if params: + # Preserve an existing query string on a `connection_url` override (for example a + # SAS-style `?sig=...`) instead of unconditionally appending a second `?`. + delimiter = "&" if urlparse(url).query else "?" + full_url = f"{url}{delimiter}{urlencode(params)}" + else: + full_url = url + + token = self._credential.get_token(*self._credential_scopes) + headers: Dict[str, str] = { + "Authorization": f"Bearer {token.token}", + _FOUNDRY_FEATURES_HEADER_NAME: self._foundry_features, + } + if self._structured_inputs is not None: + headers["x-ms-voice-structured-inputs"] = self._structured_inputs + headers.update(self._extra_headers) + if not _has_header_case_insensitive(headers, "User-Agent"): + # Only set our default if the caller didn't supply their own (in any casing) -- + # a plain dict merge would otherwise leave both as separate keys (HTTP header names + # are case-insensitive, but Python dict keys are not), sending two User-Agent-like + # headers instead of cleanly honoring the caller's override. + headers["User-Agent"] = _USER_AGENT + + try: + # Force the "realtime" WebSocket subprotocol regardless of any caller-supplied + # override in ``self._kwargs``: the service requires this exact subprotocol, so + # silently accepting a different one here would just move the failure to a less + # clear error inside the handshake. Also disable ``websockets``' own + # ``user_agent_header`` default: unlike aiohttp, it is a wholly separate mechanism + # from ``additional_headers`` -- passing our own "User-Agent" there does not + # override it, so without this the connection would carry two distinct + # User-Agent-like values. + ws_connect_kwargs = dict(self._kwargs) + ws_connect_kwargs.pop("subprotocols", None) + connection = _ws_connect( + full_url, + additional_headers=headers, + subprotocols=[Subprotocol("realtime")], + user_agent_header=None, + **ws_connect_kwargs, + ) + except BaseException as exc: + if not isinstance(exc, Exception) or isinstance(exc, (ValueError, RuntimeError)): + raise + raise ConnectionError( + f"Failed to open the realtime WebSocket connection to voice agent " + f"'{self._agent_name}' at '{url}': {exc}" + ) from exc + self._connection = RealtimeConnection(connection) + return self._connection + + def __exit__(self, *exc_details: Any) -> None: + if self._connection is not None: + self._connection.close() + self._connection = None + + +class Realtime: # pylint: disable=too-few-public-methods + """Realtime streaming entry point, exposed as ``client.realtime``. + + Follows the OpenAI Python realtime surface: obtain it from the HTTP client and open a + connection with :meth:`connect`:: + + from azure.ai.projects import AIProjectClient + from azure.identity import DefaultAzureCredential + + client = AIProjectClient(endpoint, DefaultAzureCredential()) + with client.realtime.connect(agent_name="my-agent") as conn: + conn.input_audio_buffer.append(audio=chunk) + conn.input_audio_buffer.commit() + conn.response.create() + for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + + :param client: The HTTP client whose endpoint and credential are reused for the realtime + handshake. + :type client: ~azure.ai.projects.AIProjectClient + """ + + def __init__(self, client: "AIProjectClient") -> None: + self._config = client._config # pylint: disable=protected-access + + def connect( # pylint: disable=too-many-arguments + self, + *, + agent_name: str, + foundry_features: str = _VOICE_AGENT_FEATURE_HEADER, + agent_session_id: Optional[str] = None, + agent_version_override: Optional[str] = None, + structured_inputs: Optional[str] = None, + connection_url: Optional[str] = None, + api_version: Optional[str] = None, + credential_scopes: Optional[List[str]] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> RealtimeConnectionManager: + """Open a realtime WebSocket connection to a voice agent. + + :keyword str agent_name: The name of the voice agent to connect to. + :keyword foundry_features: Preview opt-in value(s) for the ``Foundry-Features`` header. + Defaults to ``VoiceAgents=V1Preview``. Pass a comma-separated value to opt in to + additional preview features on the same request. + :paramtype foundry_features: str + :keyword agent_session_id: An optional identifier used to correlate the voice session. + Default value is None. + :paramtype agent_session_id: str or None + :keyword agent_version_override: Selects a specific version of the voice agent for this + session. Default value is None. + :paramtype agent_version_override: str or None + :keyword structured_inputs: A JSON object that maps structured-input names to their + values for this session. Default value is None. + :paramtype structured_inputs: str or None + :keyword connection_url: Full ``wss://`` URL that overrides the route computed + from the client endpoint. Query parameters are still appended. Default value is None. + :paramtype connection_url: str or None + :keyword api_version: Overrides the client's API version for the handshake. Default + value is None. + :paramtype api_version: str or None + :keyword credential_scopes: Overrides the client's token scopes for the handshake. + Default value is None. + :paramtype credential_scopes: list[str] or None + :keyword extra_query: Additional query-string parameters for the handshake. + :paramtype extra_query: Mapping[str, str] or None + :keyword extra_headers: Additional headers for the handshake. + :paramtype extra_headers: Mapping[str, str] or None + :return: A context manager yielding a :class:`RealtimeConnection`. + :rtype: ~azure.ai.projects.RealtimeConnectionManager + """ + return RealtimeConnectionManager( + endpoint=self._config.endpoint, + credential=self._config.credential, + credential_scopes=credential_scopes or self._config.credential_scopes, + api_version=api_version or self._config.api_version, + agent_name=agent_name, + foundry_features=foundry_features, + agent_session_id=agent_session_id, + agent_version_override=agent_version_override, + structured_inputs=structured_inputs, + connection_url=connection_url, + extra_query=extra_query, + extra_headers=extra_headers, + **kwargs, + ) diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py index abad0c3afee4..729a849b7653 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py @@ -6,9 +6,16 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import TYPE_CHECKING, Union +from typing import Literal, TYPE_CHECKING, Union if TYPE_CHECKING: from . import models as _models Filters = Union["_models.ComparisonFilter", "_models.CompoundFilter"] RoutineRunStatus = str +VoiceAgentToolChoice = Union[ + Literal["none"], Literal["auto"], Literal["required"], "_models.ToolChoiceFunction", "_models.ToolChoiceMCP" +] +VoiceAgentMaxOutputTokens = Union[int, Literal["inf"]] +VoiceAgentSessionUpdate = "_models.VoiceAgentSessionUpdateConfig" +VoiceAgentSessionResponse = "_models.VoiceAgentSessionResponseConfig" +GenerateAgentRequest = "_models.GenerateVoiceAgentRequest" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py index c91d6470e2bf..13edbaf420db 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py @@ -9,8 +9,41 @@ import os from typing import Any, IO, Mapping, Optional, Union +from azure.core import MatchConditions + from .._utils.model_base import Model, SdkJSONEncoder + +def quote_etag(etag: Optional[str]) -> Optional[str]: + if not etag or etag == "*": + return etag + if etag.startswith("W/"): + return etag + if etag.startswith('"') and etag.endswith('"'): + return etag + if etag.startswith("'") and etag.endswith("'"): + return etag + return '"' + etag + '"' + + +def prep_if_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfNotModified: + if_match = quote_etag(etag) if etag else None + return if_match + if match_condition == MatchConditions.IfPresent: + return "*" + return None + + +def prep_if_none_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfModified: + if_none_match = quote_etag(etag) if etag else None + return if_none_match + if match_condition == MatchConditions.IfMissing: + return "*" + return None + + # file-like tuple could be `(filename, IO (or bytes))` or `(filename, IO (or bytes), content_type)` FileContent = Union[str, bytes, IO[str], IO[bytes]] diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py index 454133e48caa..f819dc0bb43a 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "2.6.0" +VERSION = "2.7.0b1" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_client.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_client.py index dd68e26b6d8a..0cccce387126 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_client.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_client.py @@ -17,6 +17,8 @@ from .._utils.serialization import Deserializer, Serializer from ._configuration import AIProjectClientConfiguration from .operations import ( + AgentEndpointConversationsOperations, + AgentTelephonyOperations, AgentsOperations, BetaOperations, ConnectionsOperations, @@ -53,6 +55,11 @@ class AIProjectClient: # pylint: disable=too-many-instance-attributes,docstring :vartype deployments: azure.ai.projects.aio.operations.DeploymentsOperations :ivar indexes: IndexesOperations operations :vartype indexes: azure.ai.projects.aio.operations.IndexesOperations + :ivar agent_endpoint_conversations: AgentEndpointConversationsOperations operations + :vartype agent_endpoint_conversations: + azure.ai.projects.aio.operations.AgentEndpointConversationsOperations + :ivar agent_telephony: AgentTelephonyOperations operations + :vartype agent_telephony: azure.ai.projects.aio.operations.AgentTelephonyOperations :ivar toolboxes: ToolboxesOperations operations :vartype toolboxes: azure.ai.projects.aio.operations.ToolboxesOperations :param endpoint: Foundry Project endpoint in the form @@ -113,6 +120,10 @@ def __init__( self.datasets = DatasetsOperations(self._client, self._config, self._serialize, self._deserialize) self.deployments = DeploymentsOperations(self._client, self._config, self._serialize, self._deserialize) self.indexes = IndexesOperations(self._client, self._config, self._serialize, self._deserialize) + self.agent_endpoint_conversations = AgentEndpointConversationsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.agent_telephony = AgentTelephonyOperations(self._client, self._config, self._serialize, self._deserialize) self.toolboxes = ToolboxesOperations(self._client, self._config, self._serialize, self._deserialize) def send_request( diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py index 3441904edb28..abca972d0e61 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py @@ -10,6 +10,7 @@ import os import logging +from functools import wraps from typing import List, Any, Optional, cast import httpx2 # pylint: disable=networking-import-outside-azure-core-transport from openai import AsyncOpenAI, DefaultAsyncHttpxClient @@ -28,11 +29,72 @@ ) from ._client import AIProjectClient as AIProjectClientGenerated from .operations import TelemetryOperations +from ..operations._patch import _OperationMethodHeaderProxy, _method_accepts_keyword_headers +from ..models._enums import _AgentDefinitionOptInKeys +from ..models._patch import _has_header_case_insensitive +from ._realtime import ( + AsyncRealtime, + AsyncRealtimeConnection, + AsyncRealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) _OPENAI_TRANSPORT_LOGGER_NAME = "azure.ai.projects.openai_transport" logger = logging.getLogger(__name__) _openai_transport_logger = logging.getLogger(_OPENAI_TRANSPORT_LOGGER_NAME) +# Workaround for a known azure-core/aiohttp issue where compressed (e.g. gzip/brotli) response +# bodies on some non-2xx or write (POST/PATCH/DELETE) calls can reach text/JSON deserialization +# before being decompressed, causing a spurious UnicodeDecodeError. Forcing "Accept-Encoding: +# identity" disables response compression for the affected operation groups so the response body +# is never compressed in the first place. This is scoped narrowly (not applied client-wide) to +# avoid unnecessarily disabling compression on unaffected operations. +_ACCEPT_ENCODING_HEADER_NAME = "Accept-Encoding" +_ACCEPT_ENCODING_IDENTITY_VALUE = "identity" + + +class _AcceptEncodingIdentityProxy: + """Proxy that forces 'Accept-Encoding: identity' on public operation method calls. + + Works around a known async aiohttp transport issue where compressed response bodies can be + handed to text/JSON deserialization before decompression, raising a spurious + UnicodeDecodeError. + """ + + def __init__(self, operation: Any): + object.__setattr__(self, "_operation", operation) + + def __getattr__(self, name: str) -> Any: + attribute = getattr(self._operation, name) + + if name.startswith("_") or not callable(attribute) or not _method_accepts_keyword_headers(attribute): + return attribute + + @wraps(attribute) + def _wrapped(*args: Any, **kwargs: Any) -> Any: + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_ACCEPT_ENCODING_HEADER_NAME: _ACCEPT_ENCODING_IDENTITY_VALUE} + elif not _has_header_case_insensitive(headers, _ACCEPT_ENCODING_HEADER_NAME): + try: + headers[_ACCEPT_ENCODING_HEADER_NAME] = _ACCEPT_ENCODING_IDENTITY_VALUE + except Exception: # pylint: disable=broad-except + # `headers` may be an immutable mapping; merge into a fresh mutable dict + # instead of discarding the caller-supplied entries. + kwargs["headers"] = {**headers, _ACCEPT_ENCODING_HEADER_NAME: _ACCEPT_ENCODING_IDENTITY_VALUE} + + return attribute(*args, **kwargs) + + return _wrapped + + def __dir__(self) -> list: + return dir(self._operation) + + def __setattr__(self, name: str, value: Any) -> None: + setattr(self._operation, name, value) + class AIProjectClient(AIProjectClientGenerated): # pylint: disable=too-many-instance-attributes """AIProjectClient. @@ -119,7 +181,49 @@ def __init__( super().__init__(endpoint=endpoint, credential=credential, allow_preview=allow_preview, **kwargs) + if allow_preview: + setattr( + self, + "agent_telephony", + _OperationMethodHeaderProxy( + self.agent_telephony, + _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value, + ), + ) + self.telemetry = TelemetryOperations(self) # type: ignore + self._realtime: Optional[AsyncRealtime] = None + # NOTE: voice-agent conversation reads (`agent_endpoint_conversations`) have round-tripped + # between living directly on `self` (top-level) and being nested under `self.beta` across + # several upstream TypeSpec regenerations. It is currently back to being a top-level, + # stable client attribute again -- its VoiceAgents=V1Preview opt-in header injection is + # handled per-method (gated behind `allow_preview`) in + # `operations/_patch_agent_endpoint_conversations_async.py`, not by + # `_BETA_OPERATION_FEATURE_HEADERS`/`BetaOperations.__init__` (which only applies to + # `.beta`'s sub-clients). If this moves back under `.beta` in a future regeneration, update + # both that file and the `_AcceptEncodingIdentityProxy` wiring below together. + # Work around a known async aiohttp transport issue (spurious UnicodeDecodeError caused by + # compressed response bodies reaching text/JSON deserialization before decompression) by + # disabling response compression for these two operation groups only. + # Guarded with hasattr since some tests mock out the generated __init__ entirely, in which + # case none of the generated operation-group attributes may be set. + if hasattr(self, "agents"): + self.agents = _AcceptEncodingIdentityProxy(self.agents) # type: ignore + if hasattr(self, "agent_endpoint_conversations"): + self.agent_endpoint_conversations = _AcceptEncodingIdentityProxy( # type: ignore + self.agent_endpoint_conversations + ) + + @property + def realtime(self) -> AsyncRealtime: + """Realtime streaming entry point for voice agents. + + :return: The realtime namespace, exposing ``connect(...)``. + :rtype: ~azure.ai.projects.aio.AsyncRealtime + """ + if self._realtime is None: + self._realtime = AsyncRealtime(self) + return self._realtime def _get_openai_api_key(self, kwargs: dict): """Resolve the API key for the AsyncOpenAI client. @@ -149,7 +253,9 @@ def _get_openai_http_client(self, kwargs: dict): logging_kwargs = getattr(self, "_kwargs", {}) logging_enabled = bool(logging_kwargs.get("logging_enable", False)) - return DefaultAsyncHttpxClient(transport=_OpenAILoggingTransport(logging_enabled=logging_enabled)) + return DefaultAsyncHttpxClient( + transport=_OpenAILoggingTransport(logging_enabled=logging_enabled) + ) # type: ignore[arg-type] @distributed_trace def get_openai_client( @@ -346,7 +452,15 @@ def _log_request_body(self, request: httpx2.Request) -> None: _openai_transport_logger.debug("Body: [Content exists]") -__all__: List[str] = ["AIProjectClient"] # Add all objects you want publicly available to users at this package level +__all__: List[str] = [ + "AIProjectClient", + "AsyncRealtime", + "AsyncRealtimeConnection", + "AsyncRealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] # Add all objects you want publicly available to users at this package level def patch_sdk(): diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.pyi b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.pyi index 2fd628b10a0f..98239366d650 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.pyi +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.pyi @@ -32,6 +32,14 @@ from openai.types.graders.string_check_grader_param import StringCheckGraderPara from openai.types.eval_create_response import EvalCreateResponse from openai.types.shared_params.metadata import Metadata from ._client import AIProjectClient as AIProjectClientGenerated +from ._realtime import ( + AsyncRealtime, + AsyncRealtimeConnection, + AsyncRealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) from .operations import TelemetryOperations from ..models import ( AzureAIBenchmarkPreviewEvalRunDataSource, @@ -45,7 +53,7 @@ from ..models import ( ) class _AzureAsyncEvalRuns(AsyncRuns): - async def create( + async def create( # type: ignore[reportIncompatibleMethodOverride] self, eval_id: str, *, @@ -69,7 +77,7 @@ class _AzureAsyncEvalRuns(AsyncRuns): ) -> RunCreateResponse: ... class _AzureAsyncEvals(AsyncEvals): - async def create( + async def create( # type: ignore[reportIncompatibleMethodOverride] self, *, data_source_config: Union[ @@ -101,6 +109,8 @@ class AsyncOpenAI(AsyncOpenAIClient): class AIProjectClient(AIProjectClientGenerated): telemetry: TelemetryOperations + @property + def realtime(self) -> AsyncRealtime: ... def get_openai_client( self, agent_name: Optional[str] = None, **kwargs: Any # pylint: disable=unused-argument ) -> AsyncOpenAI: ... @@ -114,6 +124,14 @@ class _LoggingAsyncByteStream(httpx2.AsyncByteStream): ... def _log_streaming_response_notice(logging_enabled: bool) -> bool: ... # To make mypy happy... otherwise imports of the below result in mypy "attr-defined" error -__all__: List[str] = ["AIProjectClient"] +__all__: List[str] = [ + "AIProjectClient", + "AsyncRealtime", + "AsyncRealtimeConnection", + "AsyncRealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] def patch_sdk() -> None: ... diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py new file mode 100644 index 000000000000..fe3826cb84db --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py @@ -0,0 +1,873 @@ +# pylint: disable=networking-import-outside-azure-core-transport +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- +"""Hand-written async realtime (WebSocket) streaming client for voice agents. + +Realtime uses a fundamentally different transport (a persistent WebSocket) than the +request/response HTTP surface generated from the service's TypeSpec definition, so it is +hand-written and exposed as the ``AIProjectClient.realtime`` namespace. + +The connection ergonomics follow the OpenAI Python realtime client so that developers moving +between the libraries get a familiar surface: + +* :meth:`AsyncRealtime.connect` returns an async context manager. +* Entering the context yields an :class:`AsyncRealtimeConnection`. +* The connection is async-iterable over inbound, strongly-typed server events and exposes + sub-namespaces (``session``, ``input_audio_buffer``, ``output_audio_buffer``, + ``conversation``, ``response``) for sending strongly-typed outbound client events. + +Outbound and inbound events use the generated ``VoiceAgentClientEventXxx``/ +``VoiceAgentServerEventXxx`` models directly where one exists. ``send`` and ``recv`` still +accept/return plain ``dict`` objects as a forward-compatible fallback for any event ``type`` +the generated models don't yet know about (for example ``conversation.created``, which is a +valid event but does not (yet) have a dedicated generated model in this package). + +``aiohttp`` is required for this feature and is *not* a hard dependency of the package; it is +imported lazily so importing the SDK never fails when it is absent. +""" + +from __future__ import annotations + +import base64 +import json +from urllib.parse import urlparse +from typing import ( + Any, + AsyncIterator, + cast, + Dict, + List, + Mapping, + Optional, + Tuple, + Type, + TYPE_CHECKING, + Union, +) + +from azure.core.pipeline.policies import UserAgentPolicy + +from .. import models as _models +from ..models._enums import _AgentDefinitionOptInKeys +from ..models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _has_header_case_insensitive +from .._utils.model_base import Model as _Model, SdkJSONEncoder +from .._version import VERSION + +# Scoped to just the voice-agent preview opt-in; callers connecting to other preview agent +# kinds through this same route can pass a broader value explicitly via ``foundry_features``. +_VOICE_AGENT_FEATURE_HEADER: str = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + +# Identifies the SDK to the service on the WebSocket handshake, which otherwise falls back to +# the underlying `aiohttp` library's generic default (the generated HTTP surface gets this for +# free from the pipeline's own UserAgentPolicy; this hand-written client builds its own request +# instead, so it needs to opt in explicitly the same way). +_USER_AGENT: str = UserAgentPolicy(sdk_moniker=f"ai-projects/{VERSION}").user_agent + +if TYPE_CHECKING: + from aiohttp import ClientSession, ClientWebSocketResponse + from azure.core.credentials_async import AsyncTokenCredential + + from ._client import AIProjectClient + + +__all__ = [ + "AsyncRealtime", + "AsyncRealtimeConnection", + "AsyncRealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] + +# Union of the client event models sendable over the connection, plus a raw mapping escape +# hatch for forward compatibility with event types not yet represented in the generated models. +ClientEvent = Union[ + _models.RealtimeClientEventConversationItemCreate, + _models.RealtimeClientEventConversationItemDelete, + _models.RealtimeClientEventConversationItemRetrieve, + _models.RealtimeClientEventConversationItemTruncate, + _models.RealtimeClientEventInputAudioBufferAppend, + _models.RealtimeClientEventInputAudioBufferClear, + _models.RealtimeClientEventInputAudioBufferCommit, + _models.RealtimeClientEventOutputAudioBufferClear, + _models.RealtimeClientEventResponseCancel, + _models.RealtimeClientEventResponseCreate, + _models.VoiceAgentClientEventRtcCallSdpCreate, + _models.VoiceAgentClientEventSessionAvatarConnect, + _models.VoiceAgentClientEventSessionUpdate, + str, + Mapping[str, Any], +] + +# The conversation item variants accepted by ``conversation.item.create``. +ConversationItem = Union[ + _models.RealtimeConversationItemMessageSystem, + _models.RealtimeConversationItemMessageUser, + _models.RealtimeConversationItemMessageAssistant, + _models.RealtimeConversationItemFunctionCall, + _models.RealtimeConversationItemFunctionCallOutput, + _models.RealtimeMCPApprovalResponse, + Mapping[str, Any], +] + +# Every server event ``type`` string mapped to its generated model, used to deserialize +# inbound frames into strongly-typed objects. Event types not represented by a dedicated +# generated model in this package (for example ``conversation.created``) are intentionally +# left out here and fall back to a plain ``dict``, as do any newly-added service events. +_SERVER_EVENT_TYPES: Dict[str, Type[_Model]] = { + "conversation.item.added": _models.RealtimeServerEventConversationItemAdded, + "conversation.item.created": _models.RealtimeServerEventConversationItemCreated, + "conversation.item.deleted": _models.RealtimeServerEventConversationItemDeleted, + "conversation.item.done": _models.RealtimeServerEventConversationItemDone, + "conversation.item.input_audio_transcription.completed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted + ), + "conversation.item.input_audio_transcription.delta": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta + ), + "conversation.item.input_audio_transcription.failed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed + ), + "conversation.item.input_audio_transcription.segment": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment + ), + "conversation.item.retrieved": _models.RealtimeServerEventConversationItemRetrieved, + "conversation.item.truncated": _models.RealtimeServerEventConversationItemTruncated, + # Shared OpenAI-style Realtime error event (not voice-agent specific in this package). + "error": _models.RealtimeServerEventError, + "input_audio_buffer.cleared": _models.RealtimeServerEventInputAudioBufferCleared, + "input_audio_buffer.committed": _models.RealtimeServerEventInputAudioBufferCommitted, + "input_audio_buffer.speech_started": _models.RealtimeServerEventInputAudioBufferSpeechStarted, + "input_audio_buffer.speech_stopped": _models.RealtimeServerEventInputAudioBufferSpeechStopped, + "input_audio_buffer.timeout_triggered": (_models.RealtimeServerEventInputAudioBufferTimeoutTriggered), + "mcp_list_tools.completed": _models.RealtimeServerEventMCPListToolsCompleted, + "mcp_list_tools.failed": _models.RealtimeServerEventMCPListToolsFailed, + "mcp_list_tools.in_progress": _models.RealtimeServerEventMCPListToolsInProgress, + "output_audio_buffer.cleared": _models.RealtimeServerEventOutputAudioBufferCleared, + "rate_limits.updated": _models.RealtimeServerEventRateLimitsUpdated, + "response.animation_blendshapes.delta": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDelta), + "response.animation_blendshapes.done": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDone), + "response.animation_viseme.delta": _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + "response.animation_viseme.done": _models.VoiceAgentServerEventResponseAnimationVisemeDone, + "response.audio_timestamp.delta": _models.VoiceAgentServerEventResponseAudioTimestampDelta, + "response.audio_timestamp.done": _models.VoiceAgentServerEventResponseAudioTimestampDone, + "response.content_part.added": _models.RealtimeServerEventResponseContentPartAdded, + "response.content_part.done": _models.RealtimeServerEventResponseContentPartDone, + "response.created": _models.RealtimeServerEventResponseCreated, + "response.done": _models.RealtimeServerEventResponseDone, + "response.function_call_arguments.delta": (_models.RealtimeServerEventResponseFunctionCallArgumentsDelta), + "response.function_call_arguments.done": (_models.RealtimeServerEventResponseFunctionCallArgumentsDone), + "response.mcp_call.completed": _models.RealtimeServerEventResponseMCPCallCompleted, + "response.mcp_call.failed": _models.RealtimeServerEventResponseMCPCallFailed, + "response.mcp_call.in_progress": _models.RealtimeServerEventResponseMCPCallInProgress, + "response.mcp_call_arguments.delta": _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + "response.mcp_call_arguments.done": _models.RealtimeServerEventResponseMCPCallArgumentsDone, + "response.output_audio.delta": _models.RealtimeServerEventResponseAudioDelta, + "response.output_audio.done": _models.RealtimeServerEventResponseAudioDone, + "response.output_audio_transcript.delta": (_models.RealtimeServerEventResponseAudioTranscriptDelta), + "response.output_audio_transcript.done": (_models.RealtimeServerEventResponseAudioTranscriptDone), + "response.output_item.added": _models.RealtimeServerEventResponseOutputItemAdded, + "response.output_item.done": _models.RealtimeServerEventResponseOutputItemDone, + "response.output_text.delta": _models.RealtimeServerEventResponseTextDelta, + "response.output_text.done": _models.RealtimeServerEventResponseTextDone, + "response.video.delta": _models.VoiceAgentServerEventResponseVideoDelta, + "rtc.call.error": _models.VoiceAgentServerEventRtcCallError, + "rtc.call.sdp.created": _models.VoiceAgentServerEventRtcCallSdpCreated, + "session.avatar.connecting": _models.VoiceAgentServerEventSessionAvatarConnecting, + "session.avatar.switch_to_idle": _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + "session.avatar.switch_to_speaking": _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + "session.created": _models.RealtimeServerEventSessionCreated, + "session.subagent.aborted": _models.VoiceAgentServerEventSessionSubagentAborted, + "session.subagent.completed": _models.VoiceAgentServerEventSessionSubagentCompleted, + "session.subagent.started": _models.VoiceAgentServerEventSessionSubagentStarted, + "session.updated": _models.RealtimeServerEventSessionUpdated, + "warning": _models.VoiceAgentServerEventWarning, +} + +# Every generated server event model, for consumers that want a precise return type. +ServerEvent = Union[ + _models.RealtimeServerEventError, + _models.RealtimeServerEventResponseContentPartAdded, + _models.RealtimeServerEventConversationItemAdded, + _models.RealtimeServerEventConversationItemCreated, + _models.RealtimeServerEventConversationItemDeleted, + _models.RealtimeServerEventConversationItemDone, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + _models.RealtimeServerEventConversationItemRetrieved, + _models.RealtimeServerEventConversationItemTruncated, + _models.RealtimeServerEventInputAudioBufferCleared, + _models.RealtimeServerEventInputAudioBufferCommitted, + _models.RealtimeServerEventInputAudioBufferSpeechStarted, + _models.RealtimeServerEventInputAudioBufferSpeechStopped, + _models.RealtimeServerEventInputAudioBufferTimeoutTriggered, + _models.RealtimeServerEventMCPListToolsCompleted, + _models.RealtimeServerEventMCPListToolsFailed, + _models.RealtimeServerEventMCPListToolsInProgress, + _models.RealtimeServerEventOutputAudioBufferCleared, + _models.RealtimeServerEventRateLimitsUpdated, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDelta, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDone, + _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + _models.VoiceAgentServerEventResponseAnimationVisemeDone, + _models.RealtimeServerEventResponseAudioDelta, + _models.RealtimeServerEventResponseAudioDone, + _models.VoiceAgentServerEventResponseAudioTimestampDelta, + _models.VoiceAgentServerEventResponseAudioTimestampDone, + _models.RealtimeServerEventResponseAudioTranscriptDelta, + _models.RealtimeServerEventResponseAudioTranscriptDone, + _models.RealtimeServerEventResponseContentPartDone, + _models.RealtimeServerEventResponseCreated, + _models.RealtimeServerEventResponseDone, + _models.RealtimeServerEventResponseFunctionCallArgumentsDelta, + _models.RealtimeServerEventResponseFunctionCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + _models.RealtimeServerEventResponseMCPCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallCompleted, + _models.RealtimeServerEventResponseMCPCallFailed, + _models.RealtimeServerEventResponseMCPCallInProgress, + _models.RealtimeServerEventResponseOutputItemAdded, + _models.RealtimeServerEventResponseOutputItemDone, + _models.RealtimeServerEventResponseTextDelta, + _models.RealtimeServerEventResponseTextDone, + _models.VoiceAgentServerEventResponseVideoDelta, + _models.VoiceAgentServerEventRtcCallError, + _models.VoiceAgentServerEventRtcCallSdpCreated, + _models.VoiceAgentServerEventSessionAvatarConnecting, + _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + _models.RealtimeServerEventSessionCreated, + _models.VoiceAgentServerEventSessionSubagentAborted, + _models.VoiceAgentServerEventSessionSubagentCompleted, + _models.VoiceAgentServerEventSessionSubagentStarted, + _models.RealtimeServerEventSessionUpdated, + _models.VoiceAgentServerEventWarning, + Mapping[str, Any], +] + + +def _to_ws_url(endpoint: str, agent_name: str) -> str: + """Build the realtime WebSocket URL from the HTTPS project endpoint. + + Only the ``https://`` scheme is translated (to ``wss://``); any other scheme is left + unchanged so that :meth:`AsyncRealtimeConnectionManager.enter`'s ``wss://``-only check + rejects it with a clear error instead of silently producing an unencrypted ``ws://`` URL + that would also send the live Authorization token in plain text. + + :param str endpoint: The Foundry project endpoint (``https://.../api/projects/...``). + :param str agent_name: The name of the voice agent to connect to. + :return: A ``wss://`` URL targeting the realtime route. + :rtype: str + """ + base = endpoint.rstrip("/") + if base.startswith("https://"): + base = "wss://" + base[len("https://") :] + return f"{base}/agents/{agent_name}/endpoint/protocols/voice" + + +_DEFAULT_PORT_BY_SCHEME = {"http": 80, "https": 443, "ws": 80, "wss": 443} + + +def _normalized_authority(url: str) -> Tuple[str, Optional[int]]: + """Return a ``(hostname, port)`` tuple with the scheme's default port filled in. + + ``urlparse(...).port`` is ``None`` when a URL omits an explicit port, which would make + ``https://host/...`` and ``https://host:8443/...`` compare as equal on hostname alone. + Resolving the scheme's default port here lets callers compare authorities (not just + hostnames) so a same-host override on a different, non-default port is correctly rejected. + + :param str url: The URL to parse. + :return: A tuple of the lower-cased hostname (or empty string) and the resolved port + (or ``None`` if the scheme has no known default and none was specified). + :rtype: tuple[str, Optional[int]] + """ + parsed = urlparse(url) + port = parsed.port + if port is None: + port = _DEFAULT_PORT_BY_SCHEME.get((parsed.scheme or "").lower()) + return (parsed.hostname or "").lower(), port + + +def _assert_trusted_connection_url(connection_url: str, endpoint: str) -> None: + """Guard against attaching the caller's Entra bearer token to an untrusted host. + + ``connection_url`` is an escape hatch that lets a caller override the computed + scheme/host/path, but the Authorization header carrying the live credential's + token must never be sent to a host other than the configured Foundry project + endpoint: a caller-controlled or compromised URL could otherwise be used to + exfiltrate the token to an arbitrary host or port. + + :param str connection_url: The caller-supplied override URL. + :param str endpoint: The configured, trusted Foundry project endpoint. + :raises ValueError: If the override URL's host or port does not match the endpoint's. + """ + override_host, override_port = _normalized_authority(connection_url) + trusted_host, trusted_port = _normalized_authority(endpoint) + if not override_host or (override_host, override_port) != (trusted_host, trusted_port): + got = override_host or connection_url + if override_host and override_port: + got = f"{override_host}:{override_port}" + raise ValueError( + "The 'connection_url' override must target the same host and port as the configured " + f"Foundry project endpoint ('{trusted_host}:{trusted_port}') to avoid sending the " + f"Authorization token to an untrusted host; got '{got}'." + ) + + +class _BaseResource: # pylint: disable=too-few-public-methods + """Base helper that forwards typed helpers to the parent connection.""" + + def __init__(self, connection: "AsyncRealtimeConnection") -> None: + self._connection = connection + + async def _send(self, event: ClientEvent) -> None: + await self._connection.send(event) + + +class SessionResource(_BaseResource): + """Send ``session.*`` client events.""" + + async def update( + self, + *, + session: Union["_models.VoiceAgentSessionUpdateConfig", Mapping[str, Any]], + event_id: Optional[str] = None, + ) -> None: + """Update the realtime session configuration. + + :keyword session: The session configuration to apply. + :paramtype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig or + Mapping[str, Any] + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.VoiceAgentClientEventSessionUpdate)( + type=_models.RealtimeClientEventType.SESSION_UPDATE, + session=session, + event_id=event_id, + ) + ) + + async def avatar_connect(self, *, client_sdp: str, event_id: Optional[str] = None) -> None: + """Negotiate an avatar media session over WebRTC. + + :keyword str client_sdp: The client's SDP offer for avatar media negotiation. + :keyword event_id: An optional client-generated event identifier. + :paramtype event_id: str or None + """ + await self._send( + _models.VoiceAgentClientEventSessionAvatarConnect( + client_sdp=client_sdp, + event_id=event_id, + ) + ) + + +class InputAudioBufferResource(_BaseResource): + """Send ``input_audio_buffer.*`` client events.""" + + async def append(self, *, audio: Union[str, bytes], event_id: Optional[str] = None) -> None: + """Append audio bytes to the input buffer. + + :keyword audio: Raw audio bytes, or an already base64-encoded string. + :paramtype audio: str or bytes + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + if isinstance(audio, (bytes, bytearray)): + audio = base64.b64encode(bytes(audio)).decode("ascii") + await self._send( + _models.RealtimeClientEventInputAudioBufferAppend( + audio=audio, + event_id=event_id, + ) + ) + + async def commit(self, *, event_id: Optional[str] = None) -> None: + """Commit the buffered input audio as a user turn. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventInputAudioBufferCommit(event_id=event_id)) + + async def clear(self, *, event_id: Optional[str] = None) -> None: + """Discard any buffered input audio. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventInputAudioBufferClear(event_id=event_id)) + + +class OutputAudioBufferResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``output_audio_buffer.*`` client events.""" + + async def clear(self, *, event_id: Optional[str] = None) -> None: + """Stop and clear any audio the service is currently playing back (barge-in). + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventOutputAudioBufferClear(event_id=event_id)) + + +class ConversationItemResource(_BaseResource): + """Send ``conversation.item.*`` client events.""" + + async def create( + self, + *, + item: ConversationItem, + previous_item_id: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: + """Insert an item into the conversation. + + :keyword item: The conversation item to create. + :paramtype item: ~azure.ai.projects.models.RealtimeConversationItemMessageSystem or + ~azure.ai.projects.models.RealtimeConversationItemMessageUser or + ~azure.ai.projects.models.RealtimeConversationItemMessageAssistant or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCall or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput or + ~azure.ai.projects.models.RealtimeMCPApprovalResponse or Mapping[str, Any] + :keyword previous_item_id: The ID of the preceding item after which the new item will be + inserted. Default value is None. + :paramtype previous_item_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.RealtimeClientEventConversationItemCreate)( + item=item, + previous_item_id=previous_item_id, + event_id=event_id, + ) + ) + + async def delete(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Delete an item from the conversation. + + :keyword str item_id: The ID of the item to delete. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemDelete( + item_id=item_id, + event_id=event_id, + ) + ) + + async def retrieve(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Ask the server to emit a ``conversation.item.retrieved`` event for an item. + + :keyword str item_id: The ID of the item to retrieve. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemRetrieve( + item_id=item_id, + event_id=event_id, + ) + ) + + async def truncate( + self, *, item_id: str, content_index: int, audio_end_ms: int, event_id: Optional[str] = None + ) -> None: + """Truncate a previously produced assistant audio item (used for barge-in). + + :keyword str item_id: The ID of the assistant message item to truncate. + :keyword int content_index: The index of the content part to truncate. Use ``0``. + :keyword int audio_end_ms: The point, in milliseconds, to truncate the audio to. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemTruncate( + item_id=item_id, + content_index=content_index, + audio_end_ms=audio_end_ms, + event_id=event_id, + ) + ) + + +class ConversationResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``conversation.*`` client events.""" + + def __init__(self, connection: "AsyncRealtimeConnection") -> None: + super().__init__(connection) + self.item: ConversationItemResource = ConversationItemResource(connection) + + +class ResponseResource(_BaseResource): + """Send ``response.*`` client events.""" + + async def create( + self, + *, + response: Optional[Union["_models.VoiceAgentResponseCreateParams", Mapping[str, Any]]] = None, + event_id: Optional[str] = None, + ) -> None: + """Ask the model to generate a response. + + :keyword response: Optional per-response overrides. Default value is None. + :paramtype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams or + Mapping[str, Any] or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.RealtimeClientEventResponseCreate)( + response=response, + event_id=event_id, + ) + ) + + async def cancel(self, *, response_id: Optional[str] = None, event_id: Optional[str] = None) -> None: + """Cancel an in-progress response. + + :keyword response_id: The ID of the response to cancel, if targeting a specific one. + Default value is None. + :paramtype response_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventResponseCancel( + response_id=response_id, + event_id=event_id, + ) + ) + + +class AsyncRealtimeConnection: # pylint: disable=too-many-instance-attributes + """An open realtime WebSocket connection to a voice agent. + + Iterate over the connection to receive strongly-typed server events, and use the + sub-namespaces to send strongly-typed client events:: + + async with client.realtime.connect(agent_name="my-agent") as conn: + await conn.input_audio_buffer.append(audio=chunk) + await conn.input_audio_buffer.commit() + await conn.response.create() + async for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + """ + + def __init__(self, connection: "ClientWebSocketResponse", session: "ClientSession") -> None: + self._connection = connection + self._session = session + self.session: SessionResource = SessionResource(self) + self.input_audio_buffer: InputAudioBufferResource = InputAudioBufferResource(self) + self.output_audio_buffer: OutputAudioBufferResource = OutputAudioBufferResource(self) + self.conversation: ConversationResource = ConversationResource(self) + self.response: ResponseResource = ResponseResource(self) + + async def __aenter__(self) -> "AsyncRealtimeConnection": + return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self.close() + + def __repr__(self) -> str: + state = "closed" if self.closed else "open" + return f"" + + @property + def closed(self) -> bool: + """Whether the underlying WebSocket connection has been closed. + + :rtype: bool + """ + return self._connection.closed + + def __aiter__(self) -> AsyncIterator[ServerEvent]: + return self._iter() + + async def _iter(self) -> AsyncIterator[ServerEvent]: + while True: + try: + yield await self.recv() + except ConnectionResetError: + return + + async def recv(self) -> ServerEvent: + """Receive and parse the next server event. + + Known event types are returned as their strongly-typed + ``VoiceAgentServerEventXxx`` model. Event types not (yet) represented by a + generated model are returned as a plain ``dict`` for forward compatibility. + + :return: The parsed server event. + :rtype: ~azure.ai.projects.aio.ServerEvent + :raises ConnectionResetError: If the connection was closed by the server. + """ + import aiohttp # pylint: disable=import-outside-toplevel + + msg = await self._connection.receive() + while msg.type in (aiohttp.WSMsgType.PING, aiohttp.WSMsgType.PONG): + msg = await self._connection.receive() + if msg.type in ( + aiohttp.WSMsgType.CLOSE, + aiohttp.WSMsgType.CLOSING, + aiohttp.WSMsgType.CLOSED, + ): + raise ConnectionResetError("The realtime connection was closed.") + if msg.type == aiohttp.WSMsgType.ERROR: + raise ConnectionResetError( + "The realtime connection encountered an error." + ) from self._connection.exception() + raw = msg.data.decode("utf-8") if msg.type == aiohttp.WSMsgType.BINARY else msg.data + payload: Dict[str, Any] = json.loads(raw) + event_type = payload.get("type") + if not isinstance(event_type, str): + return payload + event_cls = _SERVER_EVENT_TYPES.get(event_type) + if event_cls is None: + return payload + return event_cls(payload) + + async def send(self, event: ClientEvent) -> None: + """Send a client event over the connection. + + :param event: A strongly-typed client event, a ready-made mapping, or a raw JSON string. + :type event: ~azure.ai.projects.aio.ClientEvent or str + :raises ValueError: If ``event`` is a ``str`` that is not valid JSON. + """ + if isinstance(event, str): + try: + json.loads(event) + except ValueError as exc: + raise ValueError(f"'event' is not valid JSON: {exc}") from exc + payload = event + else: + payload = json.dumps(event, cls=SdkJSONEncoder) + await self._connection.send_str(payload) + + async def close(self, *, code: int = 1000, reason: str = "") -> None: + """Close the connection and release the underlying HTTP session. + + :keyword int code: The WebSocket close code. + :keyword str reason: The close reason. + """ + try: + await self._connection.close(code=code, message=reason.encode("utf-8")) + finally: + await self._session.close() + + +class AsyncRealtimeConnectionManager: # pylint: disable=too-many-instance-attributes + """Async context manager that opens an :class:`AsyncRealtimeConnection`. + + Returned by :meth:`AsyncRealtime.connect`; you normally use it as + ``async with client.realtime.connect(...) as conn:``. + """ + + def __init__( # pylint: disable=too-many-arguments + self, + *, + endpoint: str, + credential: "AsyncTokenCredential", + credential_scopes: List[str], + api_version: str, + agent_name: str, + foundry_features: str, + agent_session_id: Optional[str] = None, + agent_version_override: Optional[str] = None, + structured_inputs: Optional[str] = None, + connection_url: Optional[str] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> None: + self._endpoint = endpoint + self._credential = credential + self._credential_scopes = credential_scopes + self._api_version = api_version + self._agent_name = agent_name + self._foundry_features = foundry_features + self._agent_session_id = agent_session_id + self._agent_version_override = agent_version_override + self._structured_inputs = structured_inputs + self._connection_url = connection_url + self._extra_query = dict(extra_query or {}) + self._extra_headers = dict(extra_headers or {}) + self._kwargs = kwargs + self._connection: Optional[AsyncRealtimeConnection] = None + + async def __aenter__(self) -> AsyncRealtimeConnection: + return await self.enter() + + async def enter(self) -> AsyncRealtimeConnection: # pylint: disable=too-many-locals + """Open the connection. + + :return: The live realtime connection. + :rtype: ~azure.ai.projects.aio.AsyncRealtimeConnection + :raises RuntimeError: If ``aiohttp`` is not installed. + :raises ValueError: If the computed or supplied WebSocket URL does not use ``wss://``. + :raises ConnectionError: If the WebSocket upgrade handshake fails (for example, a + network error, DNS failure, or a non-101 response from the service). + """ + try: + import aiohttp # pylint: disable=import-outside-toplevel + except ImportError as exc: # pragma: no cover - dependency guard + raise RuntimeError( + "The realtime client requires `aiohttp`. Install it with `pip install aiohttp`." + ) from exc + + # ``connection_url`` fully overrides the computed route (scheme/host/path). This is the + # escape hatch used to reach a specific data-plane host/path directly. + if self._connection_url is not None: + _assert_trusted_connection_url(self._connection_url, self._endpoint) + url = self._connection_url or _to_ws_url(self._endpoint, self._agent_name) + if not url.startswith("wss://"): + raise ValueError("The realtime WebSocket URL must use wss:// to protect credentials in transit.") + + params: Dict[str, str] = {"api-version": self._api_version, "x-ms-client-sdk": _USER_AGENT} + if self._agent_session_id is not None: + params["agent_session_id"] = self._agent_session_id + if self._agent_version_override is not None: + params["x-agent-version-override"] = self._agent_version_override + params.update(self._extra_query) + + token = await self._credential.get_token(*self._credential_scopes) + headers: Dict[str, str] = { + "Authorization": f"Bearer {token.token}", + _FOUNDRY_FEATURES_HEADER_NAME: self._foundry_features, + } + if self._structured_inputs is not None: + headers["x-ms-voice-structured-inputs"] = self._structured_inputs + headers.update(self._extra_headers) + if not _has_header_case_insensitive(headers, "User-Agent"): + # Only set our default if the caller didn't supply their own (in any casing) -- + # a plain dict merge would otherwise leave both as separate keys (HTTP header names + # are case-insensitive, but Python dict keys are not), sending two User-Agent-like + # headers instead of cleanly honoring the caller's override. + headers["User-Agent"] = _USER_AGENT + + session = aiohttp.ClientSession() + try: + # Force the "realtime" WebSocket subprotocol regardless of any caller-supplied + # override in ``self._kwargs``: the service requires this exact subprotocol, so + # silently accepting a different one here would just move the failure to a less + # clear error inside aiohttp's handshake. + ws_connect_kwargs = dict(self._kwargs) + ws_connect_kwargs.pop("protocols", None) + connection = await session.ws_connect( + url, headers=headers, params=params, protocols=("realtime",), **ws_connect_kwargs + ) + except BaseException as exc: + await session.close() + if not isinstance(exc, Exception) or isinstance(exc, (ValueError, RuntimeError)): + raise + raise ConnectionError( + f"Failed to open the realtime WebSocket connection to voice agent " + f"'{self._agent_name}' at '{url}': {exc}" + ) from exc + self._connection = AsyncRealtimeConnection(cast("ClientWebSocketResponse", connection), session) + return self._connection + + async def __aexit__(self, *exc_details: Any) -> None: + if self._connection is not None: + await self._connection.close() + self._connection = None + + +class AsyncRealtime: # pylint: disable=too-few-public-methods + """Realtime streaming entry point, exposed as ``client.realtime``. + + Follows the OpenAI Python realtime surface: obtain it from the HTTP client and open a + connection with :meth:`connect`:: + + from azure.ai.projects.aio import AIProjectClient + from azure.identity.aio import DefaultAzureCredential + + client = AIProjectClient(endpoint, DefaultAzureCredential()) + async with client.realtime.connect(agent_name="my-agent") as conn: + await conn.input_audio_buffer.append(audio=chunk) + await conn.input_audio_buffer.commit() + await conn.response.create() + async for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + + :param client: The HTTP client whose endpoint and credential are reused for the realtime + handshake. + :type client: ~azure.ai.projects.aio.AIProjectClient + """ + + def __init__(self, client: "AIProjectClient") -> None: + self._config = client._config # pylint: disable=protected-access + + def connect( # pylint: disable=too-many-arguments + self, + *, + agent_name: str, + foundry_features: str = _VOICE_AGENT_FEATURE_HEADER, + agent_session_id: Optional[str] = None, + agent_version_override: Optional[str] = None, + structured_inputs: Optional[str] = None, + connection_url: Optional[str] = None, + api_version: Optional[str] = None, + credential_scopes: Optional[List[str]] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> AsyncRealtimeConnectionManager: + """Open a realtime WebSocket connection to a voice agent. + + :keyword str agent_name: The name of the voice agent to connect to. + :keyword foundry_features: Preview opt-in value(s) for the ``Foundry-Features`` header. + Defaults to ``VoiceAgents=V1Preview``. Pass a comma-separated value to opt in to + additional preview features on the same request. + :paramtype foundry_features: str + :keyword agent_session_id: An optional identifier used to correlate the voice session. + Default value is None. + :paramtype agent_session_id: str or None + :keyword agent_version_override: Selects a specific version of the voice agent for this + session. Default value is None. + :paramtype agent_version_override: str or None + :keyword structured_inputs: A JSON object that maps structured-input names to their + values for this session. Default value is None. + :paramtype structured_inputs: str or None + :keyword connection_url: Full ``wss://`` URL that overrides the route computed + from the client endpoint. Query parameters are still appended. Default value is None. + :paramtype connection_url: str or None + :keyword api_version: Overrides the client's API version for the handshake. Default + value is None. + :paramtype api_version: str or None + :keyword credential_scopes: Overrides the client's token scopes for the handshake. + Default value is None. + :paramtype credential_scopes: list[str] or None + :keyword extra_query: Additional query-string parameters for the handshake. + :paramtype extra_query: Mapping[str, str] or None + :keyword extra_headers: Additional headers for the handshake. + :paramtype extra_headers: Mapping[str, str] or None + :return: An async context manager yielding an :class:`AsyncRealtimeConnection`. + :rtype: ~azure.ai.projects.aio.AsyncRealtimeConnectionManager + """ + return AsyncRealtimeConnectionManager( + endpoint=self._config.endpoint, + credential=self._config.credential, + credential_scopes=credential_scopes or self._config.credential_scopes, + api_version=api_version or self._config.api_version, + agent_name=agent_name, + foundry_features=foundry_features, + agent_session_id=agent_session_id, + agent_version_override=agent_version_override, + structured_inputs=structured_inputs, + connection_url=connection_url, + extra_query=extra_query, + extra_headers=extra_headers, + **kwargs, + ) diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/__init__.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/__init__.py index d6cf67b4d8cf..19d6ddc7b035 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/__init__.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/__init__.py @@ -19,6 +19,9 @@ from ._operations import DatasetsOperations # type: ignore from ._operations import DeploymentsOperations # type: ignore from ._operations import IndexesOperations # type: ignore +from ._operations import VoiceAgentWebSocketOperations # type: ignore +from ._operations import AgentEndpointConversationsOperations # type: ignore +from ._operations import AgentTelephonyOperations # type: ignore from ._operations import ToolboxesOperations # type: ignore from ._patch import __all__ as _patch_all @@ -33,6 +36,9 @@ "DatasetsOperations", "DeploymentsOperations", "IndexesOperations", + "VoiceAgentWebSocketOperations", + "AgentEndpointConversationsOperations", + "AgentTelephonyOperations", "ToolboxesOperations", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py index 2ddf8953b1ea..e88db5a34c3f 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py @@ -7,17 +7,19 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from collections.abc import MutableMapping +import datetime from io import IOBase import json -from typing import Any, AsyncIterator, Callable, IO, Literal, Optional, TypeVar, Union, cast, overload +from typing import Any, AsyncIterator, Callable, IO, Literal, Optional, TYPE_CHECKING, TypeVar, Union, cast, overload import urllib.parse -from azure.core import AsyncPipelineClient +from azure.core import AsyncPipelineClient, MatchConditions from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import ( ClientAuthenticationError, HttpResponseError, ResourceExistsError, + ResourceModifiedError, ResourceNotFoundError, ResourceNotModifiedError, StreamClosedError, @@ -36,32 +38,72 @@ from ..._utils.model_base import Model as _Model, SdkJSONEncoder, _deserialize, _failsafe_deserialize from ..._utils.serialization import Deserializer, Serializer from ..._utils.utils import prepare_multipart_form_data +from ...models._enums import _AgentDefinitionOptInKeys from ...operations._operations import ( + build_agent_endpoint_conversations_delete_agent_conversation_request, + build_agent_endpoint_conversations_get_agent_conversation_audio_content_request, + build_agent_endpoint_conversations_get_agent_conversation_audio_request, + build_agent_endpoint_conversations_get_agent_conversation_item_audio_content_request, + build_agent_endpoint_conversations_get_agent_conversation_item_audio_request, + build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_content_request, + build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_request, + build_agent_endpoint_conversations_get_agent_conversation_item_request, + build_agent_endpoint_conversations_get_agent_conversation_request, + build_agent_endpoint_conversations_get_agent_conversation_response_request, + build_agent_endpoint_conversations_list_agent_conversation_items_request, + build_agent_endpoint_conversations_list_agent_conversation_response_items_request, + build_agent_endpoint_conversations_list_agent_conversation_responses_request, + build_agent_endpoint_conversations_list_agent_conversations_request, + build_agent_telephony_cancel_telephony_call_job_request, + build_agent_telephony_cancel_telephony_campaign_request, + build_agent_telephony_create_telephony_call_job_request, + build_agent_telephony_create_telephony_campaign_request, + build_agent_telephony_get_telephony_call_job_request, + build_agent_telephony_get_telephony_campaign_recipient_import_request, + build_agent_telephony_get_telephony_campaign_request, + build_agent_telephony_get_telephony_operation_request, + build_agent_telephony_import_telephony_campaign_recipients_request, + build_agent_telephony_pause_telephony_campaign_request, + build_agent_telephony_publish_telephony_campaign_request, + build_agent_telephony_resume_telephony_campaign_request, + build_agent_telephony_validate_telephony_campaign_request, build_agents_create_session_request, + build_agents_create_telephony_binding_request, build_agents_create_version_from_code_request, build_agents_create_version_from_manifest_request, build_agents_create_version_request, build_agents_delete_request, build_agents_delete_session_file_request, build_agents_delete_session_request, + build_agents_delete_telephony_binding_request, build_agents_delete_version_request, build_agents_disable_request, build_agents_download_code_request, build_agents_download_session_file_request, build_agents_enable_request, + build_agents_end_telephony_call_request, + build_agents_generate_agent_request, build_agents_get_microsoft365_package_request, build_agents_get_microsoft365_publish_defaults_request, build_agents_get_request, build_agents_get_session_log_stream_request, build_agents_get_session_request, + build_agents_get_telephony_binding_request, + build_agents_get_telephony_call_request, + build_agents_get_telephony_transfer_targets_request, build_agents_get_version_request, build_agents_list_request, build_agents_list_session_files_request, build_agents_list_sessions_request, + build_agents_list_telephony_bindings_request, + build_agents_list_telephony_calls_request, build_agents_list_versions_request, build_agents_publish_to_microsoft365_request, + build_agents_replace_telephony_transfer_targets_request, build_agents_stop_session_request, + build_agents_transfer_telephony_call_request, build_agents_update_details_request, + build_agents_update_telephony_binding_request, build_agents_upload_session_file_request, build_beta_agent_insight_monitors_cancel_run_request, build_beta_agent_insight_monitors_create_request, @@ -185,9 +227,12 @@ build_toolboxes_list_request, build_toolboxes_list_versions_request, build_toolboxes_update_request, + build_voice_agent_web_socket_connect_voice_agent_request, ) from .._configuration import AIProjectClientConfiguration +if TYPE_CHECKING: + from ... import _unions JSON = MutableMapping[str, Any] _Unset: Any = object() T = TypeVar("T") @@ -314,6 +359,80 @@ async def get(self, agent_name: str, **kwargs: Any) -> _models.AgentDetails: return deserialized # type: ignore + @distributed_trace_async + async def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: + """Generate an agent. + + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. + + :param body: The kind-specific inputs for generating and creating an agent. Is one of the + following types: GenerateVoiceAgentRequest Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_generate_agent_request( + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + @distributed_trace_async async def delete( self, agent_name: str, *, force: Optional[bool] = None, **kwargs: Any @@ -406,7 +525,7 @@ def list( Returns a paged collection of agent resources. :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values - are: "prompt", "hosted", "workflow", and "external". Default value is None. + are: "prompt", "hosted", "workflow", "external", and "voice". Default value is None. :paramtype kind: str or ~azure.ai.projects.models.AgentKind :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -2182,6 +2301,7 @@ async def get_session_log_stream( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) + kwargs.pop("stream", None) # must always stream; discard any caller override _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs @@ -2997,91 +3117,85 @@ async def get_microsoft365_publish_defaults( return deserialized # type: ignore @overload - async def upload_session_file( + async def create_telephony_binding( self, agent_name: str, - session_id: str, - content: bytes, + body: _models.CreateTelephonyBindingRequest, *, - path: str, - content_type: str = "application/octet-stream", + content_type: str = "application/json", **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + Creates a telephony binding for the voice agent named in the path. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the voice agent that owns the binding. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: bytes - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". + :param body: The provider-specific binding to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def upload_session_file( - self, - agent_name: str, - session_id: str, - content: IO[bytes], - *, - path: str, - content_type: str = "application/octet-stream", - **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. + async def create_telephony_binding( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + Creates a telephony binding for the voice agent named in the path. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the voice agent that owns the binding. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str + :param body: The provider-specific binding to create. Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_binding( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". + Default value is "application/json". :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def upload_session_file( - self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. + async def create_telephony_binding( + self, agent_name: str, body: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + Creates a telephony binding for the voice agent named in the path. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the voice agent that owns the binding. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Is either a bytes type or a IO[bytes] type. Required. - :type content: bytes or IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :param body: The provider-specific binding to create. Is one of the following types: + CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3096,15 +3210,17 @@ async def upload_session_file( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - content_type = content_type or "application/octet-stream" - _content = content + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_upload_session_file_request( + _request = build_agents_create_telephony_binding_request( agent_name=agent_name, - session_id=session_id, - path=path, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -3137,115 +3253,43 @@ async def upload_session_file( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - @distributed_trace_async - async def download_session_file( - self, agent_name: str, session_id: str, *, path: str, **kwargs: Any - ) -> AsyncIterator[bytes]: - """Download a session file. - - Downloads the file at the specified sandbox path as a binary stream. The path is resolved - relative to the session home directory. - - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file path to download from the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: AsyncIterator[bytes] - :rtype: AsyncIterator[bytes] - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - _request = build_agents_download_session_file_request( - agent_name=agent_name, - session_id=session_id, - path=path, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def list_session_files( + def list_telephony_bindings( self, agent_name: str, - session_id: str, *, - path: Optional[str] = None, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.SessionDirectoryEntry"]: - """List session files. + ) -> AsyncItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. - Returns files and directories at the specified path in the session sandbox. The response - includes only the immediate children of the target directory and defaults to the session home - directory when no path is supplied. + Returns the telephony bindings owned by the voice agent named in the path. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the voice agent whose bindings are listed. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The directory path to list, relative to the session home directory. Defaults to - the home directory if not provided. Default value is None. - :paramtype path: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -3260,15 +3304,15 @@ def list_session_files( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of SessionDirectoryEntry + :return: An iterator like instance of TelephonyBindingListItem :rtype: - ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.TelephonyBindingListItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -3280,10 +3324,10 @@ def list_session_files( def prepare_request(_continuation_token=None): - _request = build_agents_list_session_files_request( + _request = build_agents_list_telephony_bindings_request( agent_name=agent_name, - session_id=session_id, - path=path, + provider=provider, + status=status, limit=limit, order=order, after=_continuation_token, @@ -3301,8 +3345,8 @@ def prepare_request(_continuation_token=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.SessionDirectoryEntry], - deserialized.get("entries", []), + List[_models.TelephonyBindingListItem], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore @@ -3330,26 +3374,17 @@ async def get_next(_continuation_token=None): return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def delete_session_file( - self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any - ) -> None: - """Delete a session file. + async def get_telephony_binding(self, agent_name: str, binding_id: str, **kwargs: Any) -> _models.TelephonyBinding: + """Get an agent telephony binding. - Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, - deleting a non-empty directory returns 409 Conflict. + Retrieves a telephony binding owned by the voice agent named in the path. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the voice agent that owns the binding. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file or directory path to delete, relative to the session home directory. - Required. - :paramtype path: str - :keyword recursive: Whether to recursively delete directory contents. The service defaults to - ``false`` if a value is not specified by the caller. Default value is None. - :paramtype recursive: bool - :return: None - :rtype: None + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3363,13 +3398,11 @@ async def delete_session_file( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_agents_delete_session_file_request( + _request = build_agents_get_telephony_binding_request( agent_name=agent_name, - session_id=session_id, - path=path, - recursive=recursive, + binding_id=binding_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -3379,14 +3412,20 @@ async def delete_session_file( } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -3394,37 +3433,149 @@ async def delete_session_file( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyBinding, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized # type: ignore -class EvaluationRulesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + @overload + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`evaluation_rules` attribute. - """ + Updates a telephony binding owned by the voice agent named in the path. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: - """Get an evaluation rule. + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Retrieves the specified evaluation rule and its configuration. + Updates a telephony binding owned by the voice agent named in the path. - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3433,16 +3584,35 @@ async def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: 409: ResourceExistsError, 304: ResourceNotModifiedError, } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_evaluation_rules_get_request( - id=id, + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_update_telephony_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -3466,26 +3636,41 @@ async def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace_async - async def delete(self, id: str, **kwargs: Any) -> None: - """Delete an evaluation rule. + async def delete_telephony_binding( + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. - Removes the specified evaluation rule from the project. + Deletes a telephony binding owned by the voice agent named in the path. - :param id: Unique identifier for the evaluation rule. Required. - :type id: str + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -3496,6 +3681,12 @@ async def delete(self, id: str, **kwargs: Any) -> None: 409: ResourceExistsError, 304: ResourceNotModifiedError, } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError error_map.update(kwargs.pop("error_map", {}) or {}) _headers = kwargs.pop("headers", {}) or {} @@ -3503,8 +3694,11 @@ async def delete(self, id: str, **kwargs: Any) -> None: cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_evaluation_rules_delete_request( - id=id, + _request = build_agents_delete_telephony_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -3523,88 +3717,70 @@ async def delete(self, id: str, **kwargs: Any) -> None: if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if cls: return cls(pipeline_response, None, {}) # type: ignore - @overload - async def create_or_update( - self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. + @distributed_trace + def list_telephony_calls( + self, + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after: Optional[datetime.datetime] = None, + started_before: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + Returns the durable inbound call history for the voice agent named in the path. - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", "success", + and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after: Includes calls that started at or after this Unix timestamp in seconds. + Default value is None. + :paramtype started_after: ~datetime.datetime + :keyword started_before: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before: ~datetime.datetime + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyCallSummary] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def create_or_update( - self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + cls: ClsType[List[_models.TelephonyCallSummary]] = kwargs.pop("cls", None) - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Is one of the following types: - EvaluationRule, JSON, IO[bytes] Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -3613,152 +3789,40 @@ async def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(evaluation_rule, (IOBase, bytes)): - _content = evaluation_rule - else: - _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_evaluation_rules_create_or_update_request( - id=id, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200, 201]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - @distributed_trace - def list( - self, - *, - action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, - agent_name: Optional[str] = None, - enabled: Optional[bool] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.EvaluationRule"]: - """List evaluation rules. - - Returns the evaluation rules configured for the project, optionally filtered by action type, - agent name, or enabled state. - - :keyword action_type: Filter by the type of evaluation rule. Known values are: - "continuousEvaluation" and "humanEvaluationPreview". Default value is None. - :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType - :keyword agent_name: Filter by the agent name. Default value is None. - :paramtype agent_name: str - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of EvaluationRule - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluationRule] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_evaluation_rules_list_request( - action_type=action_type, - agent_name=agent_name, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_agents_list_telephony_calls_request( + agent_name=agent_name, + provider=provider, + status=status, + started_after=started_after, + started_before=started_before, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluationRule], - deserialized.get("value", []), + List[_models.TelephonyCallSummary], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - async def get_next(next_link=None): - _request = prepare_request(next_link) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -3768,41 +3832,28 @@ async def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return AsyncItemPaged(get_next, extract_data) - -class ConnectionsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`connections` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace_async - async def _get(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection. + async def get_telephony_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """Get an agent telephony call. - Retrieves the specified connection and its configuration details without including credential - values. + Retrieves a durable inbound call record owned by the voice agent named in the path. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3816,10 +3867,11 @@ async def _get(self, name: str, **kwargs: Any) -> _models.Connection: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_connections_get_request( - name=name, + _request = build_agents_get_telephony_call_request( + agent_name=agent_name, + call_id=call_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -3844,33 +3896,112 @@ async def _get(self, name: str, **kwargs: Any) -> _models.Connection: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @overload + async def transfer_telephony_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def transfer_telephony_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def transfer_telephony_call( + self, agent_name: str, call_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace_async - async def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection with credentials. + async def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + target: str = _Unset, + **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Retrieves the specified connection together with its credential values. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3881,14 +4012,30 @@ async def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Conne } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_connections_get_with_credentials_request( - name=name, + if body is _Unset: + if target is _Unset: + raise TypeError("missing required argument: target") + body = {"target": target} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_transfer_telephony_call_request( + agent_name=agent_name, + call_id=call_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -3912,52 +4059,36 @@ async def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Conne except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - connection_type: Optional[Union[str, _models.ConnectionType]] = None, - default_connection: Optional[bool] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.Connection"]: - """List connections. + @distributed_trace_async + async def end_telephony_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """End an active agent telephony call. - Returns the connections available in the current project, optionally filtered by type or - default status. + Ends an active inbound call owned by the voice agent named in the path. - :keyword connection_type: Lists connections of this specific type. Known values are: - "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", - "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. - :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType - :keyword default_connection: Lists connections that are default connections. Default value is - None. - :paramtype default_connection: bool - :return: An iterator like instance of Connection - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Connection] + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -3966,110 +4097,67 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_connections_list_request( - connection_type=connection_type, - default_connection=default_connection, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - return _request + _request = build_agents_end_telephony_call_request( + agent_name=agent_name, + call_id=call_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Connection], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - + raise HttpResponseError(response=response, model=error) -class DatasetsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`datasets` attribute. - """ + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.DatasetVersion"]: - """List versions. + @distributed_trace_async + async def get_telephony_transfer_targets(self, agent_name: str, **kwargs: Any) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. - List all versions of the given DatasetVersion. + Returns all transfer targets configured for the voice agent named in the path. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DatasetVersion] + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -4078,177 +4166,182 @@ def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.Dat } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_datasets_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - return _request + _request = build_agents_get_telephony_transfer_targets_request( + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) - return pipeline_response + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) - return AsyncItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged["_models.DatasetVersion"]: - """List latest versions. + return deserialized # type: ignore - List the latest version of each DatasetVersion. + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + transfer_targets: List[_models.TelephonyTransferTarget], + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DatasetVersion] + Replaces all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_datasets_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - async def get_next(next_link=None): - _request = prepare_request(next_link) + Replaces all transfer targets configured for the voice agent named in the path. - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - return pipeline_response + Replaces all transfer targets configured for the voice agent named in the path. - return AsyncItemPaged(get_next, extract_data) + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: - """Get a version. + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the - DatasetVersion does not exist. + Replaces all transfer targets configured for the voice agent named in the path. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to retrieve. Required. - :type version: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -4257,17 +4350,39 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVe 409: ResourceExistsError, 304: ResourceNotModifiedError, } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - _request = build_datasets_get_request( - name=name, - version=version, + if body is _Unset: + if transfer_targets is _Unset: + raise TypeError("missing required argument: transfer_targets") + body = {"transfer_targets": transfer_targets} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_replace_telephony_transfer_targets_request( + agent_name=agent_name, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -4291,50 +4406,137 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVe except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def delete(self, name: str, version: str, **kwargs: Any) -> None: - """Delete a version. + @overload + async def upload_session_file( + self, + agent_name: str, + session_id: str, + content: bytes, + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. - Delete the specific version of the DatasetVersion. The service returns 204 No Content if the - DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the DatasetVersion to delete. Required. - :type version: str - :return: None - :rtype: None + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: bytes + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + @overload + async def upload_session_file( + self, + agent_name: str, + session_id: str, + content: IO[bytes], + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. - cls: ClsType[None] = kwargs.pop("cls", None) + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. - _request = build_datasets_delete_request( - name=name, - version=version, + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def upload_session_file( + self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Is either a bytes type or a IO[bytes] type. Required. + :type content: bytes or IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) + + content_type = content_type or "application/octet-stream" + _content = content + + _request = build_agents_upload_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -4343,121 +4545,55 @@ async def delete(self, name: str, version: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - async def create_or_update( - self, - name: str, - version: str, - dataset_version: _models.DatasetVersion, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. - - Create a new or update an existing DatasetVersion with the given version id. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, - name: str, - version: str, - dataset_version: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. - - Create a new or update an existing DatasetVersion with the given version id. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @overload - async def create_or_update( - self, - name: str, - version: str, - dataset_version: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) - Create a new or update an existing DatasetVersion with the given version id. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace_async - async def create_or_update( - self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + async def download_session_file( + self, agent_name: str, session_id: str, *, path: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Download a session file. - Create a new or update an existing DatasetVersion with the given version id. + Downloads the file at the specified sandbox path as a binary stream. The path is resolved + relative to the session home directory. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Is one of the following types: - DatasetVersion, JSON, IO[bytes] Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file path to download from the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -4468,25 +4604,16 @@ async def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(dataset_version, (IOBase, bytes)): - _content = dataset_version - else: - _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_datasets_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_agents_download_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -4496,140 +4623,82 @@ async def create_or_update( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def pending_upload( + @distributed_trace + def list_session_files( self, - name: str, - version: str, - pending_upload_request: _models.PendingUploadRequest, + agent_name: str, + session_id: str, *, - content_type: str = "application/json", + path: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> AsyncItemPaged["_models.SessionDirectoryEntry"]: + """List session files. - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + Returns files and directories at the specified path in the session sandbox. The response + includes only the immediate children of the target directory and defaults to the session home + directory when no path is supplied. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The directory path to list, relative to the session home directory. Defaults to + the home directory if not provided. Default value is None. + :paramtype path: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SessionDirectoryEntry + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Is one of the following - types: PendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or - IO[bytes] - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -4638,72 +4707,78 @@ async def pending_upload( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request - else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + def prepare_request(_continuation_token=None): - _request = build_datasets_pending_upload_request( - name=name, - version=version, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request = build_agents_list_session_files_request( + agent_name=agent_name, + session_id=session_id, + path=path, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.SessionDirectoryEntry], + deserialized.get("entries", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - response = pipeline_response.http_response + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return pipeline_response - return deserialized # type: ignore + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: - """Get dataset credentials. + async def delete_session_file( + self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any + ) -> None: + """Delete a session file. - Retrieves the SAS credential to access the storage account associated with a dataset version. + Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, + deleting a non-empty directory returns 409 Conflict. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file or directory path to delete, relative to the session home directory. + Required. + :paramtype path: str + :keyword recursive: Whether to recursively delete directory contents. The service defaults to + ``false`` if a value is not specified by the caller. Default value is None. + :paramtype recursive: bool + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -4717,11 +4792,13 @@ async def get_credentials(self, name: str, version: str, **kwargs: Any) -> _mode _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_datasets_get_credentials_request( - name=name, - version=version, + _request = build_agents_delete_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + recursive=recursive, api_version=self._config.api_version, headers=_headers, params=_params, @@ -4731,42 +4808,33 @@ async def get_credentials(self, name: str, version: str, **kwargs: Any) -> _mode } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore -class DeploymentsOperations: # pylint: disable=docstring-missing-param +class EvaluationRulesOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`deployments` attribute. + :attr:`evaluation_rules` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -4777,15 +4845,15 @@ def __init__(self, *args, **kwargs) -> None: self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace_async - async def get(self, name: str, **kwargs: Any) -> _models.Deployment: - """Get a deployment. + async def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: + """Get an evaluation rule. - Retrieves a deployed model. + Retrieves the specified evaluation rule and its configuration. - :param name: Name of the deployment. Required. - :type name: str - :return: Deployment. The Deployment is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Deployment + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -4799,10 +4867,10 @@ async def get(self, name: str, **kwargs: Any) -> _models.Deployment: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) - _request = build_deployments_get_request( - name=name, + _request = build_evaluation_rules_get_request( + id=id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -4829,52 +4897,28 @@ async def get(self, name: str, **kwargs: Any) -> _models.Deployment: map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) - response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) - if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Deployment, response.json()) + deserialized = _deserialize(_models.EvaluationRule, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - model_publisher: Optional[str] = None, - model_name: Optional[str] = None, - deployment_type: Optional[Union[str, _models.DeploymentType]] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.Deployment"]: - """List deployments. + @distributed_trace_async + async def delete(self, id: str, **kwargs: Any) -> None: + """Delete an evaluation rule. - Returns the deployed models available in the current project, optionally filtered by publisher, - model name, or deployment type. + Removes the specified evaluation rule from the project. - :keyword model_publisher: Model publisher to filter models by. Default value is None. - :paramtype model_publisher: str - :keyword model_name: Model name (the publisher specific name) to filter models by. Default - value is None. - :paramtype model_name: str - :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value - is None. - :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType - :return: An iterator like instance of Deployment - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Deployment] + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -4883,124 +4927,219 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_deployments_list_request( - model_publisher=model_publisher, - model_name=model_name, - deployment_type=deployment_type, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[None] = kwargs.pop("cls", None) - return _request + _request = build_evaluation_rules_delete_request( + id=id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Deployment], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + if cls: + return cls(pipeline_response, None, {}) # type: ignore - return pipeline_response + @overload + async def create_or_update( + self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. - return AsyncItemPaged(get_next, extract_data) + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ -class IndexesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + @overload + async def create_or_update( + self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`indexes` attribute. - """ + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.Index"]: - """List versions. + @overload + async def create_or_update( + self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. - List all versions of the given Index. + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of Index - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Index] + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + @distributed_trace_async + async def create_or_update( + self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Is one of the following types: + EvaluationRule, JSON, IO[bytes] Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(evaluation_rule, (IOBase, bytes)): + _content = evaluation_rule + else: + _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_evaluation_rules_create_or_update_request( + id=id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationRule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, + agent_name: Optional[str] = None, + enabled: Optional[bool] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.EvaluationRule"]: + """List evaluation rules. + + Returns the evaluation rules configured for the project, optionally filtered by action type, + agent name, or enabled state. + + :keyword action_type: Filter by the type of evaluation rule. Known values are: + "continuousEvaluation" and "humanEvaluationPreview". Default value is None. + :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType + :keyword agent_name: Filter by the agent name. Default value is None. + :paramtype agent_name: str + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of EvaluationRule + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluationRule] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) def prepare_request(next_link=None): if not next_link: - _request = build_indexes_list_versions_request( - name=name, + _request = build_evaluation_rules_list_request( + action_type=action_type, + agent_name=agent_name, + enabled=enabled, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5040,7 +5179,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.Index], + List[_models.EvaluationRule], deserialized.get("value", []), ) if cls: @@ -5064,21 +5203,37 @@ async def get_next(next_link=None): return AsyncItemPaged(get_next, extract_data) - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged["_models.Index"]: - """List latest versions. - List the latest version of each Index. +class ConnectionsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - :return: An iterator like instance of Index - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Index] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`connections` attribute. + """ - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def _get(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection. + + Retrieves the specified connection and its configuration details without including credential + values. + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -5087,86 +5242,4337 @@ def list(self, **kwargs: Any) -> AsyncItemPaged["_models.Index"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - _request = build_indexes_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request = build_connections_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Index], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + response = pipeline_response.http_response - async def get_next(next_link=None): - _request = prepare_request(next_link) + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection with credentials. + + Retrieves the specified connection together with its credential values. + + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + + _request = build_connections_get_with_credentials_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + connection_type: Optional[Union[str, _models.ConnectionType]] = None, + default_connection: Optional[bool] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.Connection"]: + """List connections. + + Returns the connections available in the current project, optionally filtered by type or + default status. + + :keyword connection_type: Lists connections of this specific type. Known values are: + "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", + "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. + :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType + :keyword default_connection: Lists connections that are default connections. Default value is + None. + :paramtype default_connection: bool + :return: An iterator like instance of Connection + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Connection] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_connections_list_request( + connection_type=connection_type, + default_connection=default_connection, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Connection], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class DatasetsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`datasets` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.DatasetVersion"]: + """List versions. + + List all versions of the given DatasetVersion. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged["_models.DatasetVersion"]: + """List latest versions. + + List the latest version of each DatasetVersion. + + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: + """Get a version. + + Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the + DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to retrieve. Required. + :type version: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + _request = build_datasets_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def delete(self, name: str, version: str, **kwargs: Any) -> None: + """Delete a version. + + Delete the specific version of the DatasetVersion. The service returns 204 No Content if the + DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the DatasetVersion to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_datasets_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: _models.DatasetVersion, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, + name: str, + version: str, + dataset_version: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_or_update( + self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Is one of the following types: + DatasetVersion, JSON, IO[bytes] Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(dataset_version, (IOBase, bytes)): + _content = dataset_version + else: + _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_create_or_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Is one of the following + types: PendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + IO[bytes] + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request + else: + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_pending_upload_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: + """Get dataset credentials. + + Retrieves the SAS credential to access the storage account associated with a dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + + _request = build_datasets_get_credentials_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetCredential, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class DeploymentsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`deployments` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def get(self, name: str, **kwargs: Any) -> _models.Deployment: + """Get a deployment. + + Retrieves a deployed model. + + :param name: Name of the deployment. Required. + :type name: str + :return: Deployment. The Deployment is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Deployment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + + _request = build_deployments_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Deployment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + model_publisher: Optional[str] = None, + model_name: Optional[str] = None, + deployment_type: Optional[Union[str, _models.DeploymentType]] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.Deployment"]: + """List deployments. + + Returns the deployed models available in the current project, optionally filtered by publisher, + model name, or deployment type. + + :keyword model_publisher: Model publisher to filter models by. Default value is None. + :paramtype model_publisher: str + :keyword model_name: Model name (the publisher specific name) to filter models by. Default + value is None. + :paramtype model_name: str + :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value + is None. + :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType + :return: An iterator like instance of Deployment + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Deployment] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_deployments_list_request( + model_publisher=model_publisher, + model_name=model_name, + deployment_type=deployment_type, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Deployment], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class IndexesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`indexes` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.Index"]: + """List versions. + + List all versions of the given Index. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of Index + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged["_models.Index"]: + """List latest versions. + + List the latest version of each Index. + + :return: An iterator like instance of Index + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: + """Get a version. + + Get the specific version of the Index. The service returns 404 Not Found error if the Index + does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to retrieve. Required. + :type version: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Index] = kwargs.pop("cls", None) + + _request = build_indexes_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Index, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def delete(self, name: str, version: str, **kwargs: Any) -> None: + """Delete a version. + + Delete the specific version of the Index. The service returns 204 No Content if the Index was + deleted successfully or if the Index does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the Index to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_indexes_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: _models.Index, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: ~azure.ai.projects.models.Index + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_or_update( + self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Is one of the following types: Index, JSON, + IO[bytes] Required. + :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Index] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(index, (IOBase, bytes)): + _content = index + else: + _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_indexes_create_or_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Index, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class VoiceAgentWebSocketOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`voice_agent_web_socket` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def connect_voice_agent( + self, + agent_name: str, + *, + foundry_features_query: Optional[Literal[_AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW]] = None, + transport: Optional[Union[str, _models.VoiceAgentTransport]] = None, + store: Optional[bool] = None, + structured_input: Optional[str] = None, + agent_version_override: Optional[str] = None, + websocket_subprotocol: Optional[Union[str, _models.VoiceAgentWebSocketSubprotocol]] = None, + **kwargs: Any + ) -> None: + """Connect to a voice agent. + + Connects to a voice agent over WebSocket. The client must send an HTTP GET with ``Upgrade: + websocket`` + headers. The optional ``realtime`` subprotocol is the only accepted subprotocol value. Supply + the + ``VoiceAgents=V1Preview`` opt-in through either the ``Foundry-Features`` header or the + ``foundry_features`` + query parameter. + + Handshake failures are evaluated in the following order, independent of the requested + ``transport``: + + + + 1. Agent enablement (any transport): if the target agent is disabled, the handshake fails + before the + `101 Switching Protocols` upgrade with `409 Conflict`, using the shared Foundry + `ApiErrorResponse` shape + with `error.code = agent_disabled`. This failure is terminal until the caller enables the + agent, and it + takes precedence over the WebRTC-specific checks below. + 2. WebRTC availability (only when `transport=webrtc`, and only once the agent itself is + enabled): the agent + must have the WebRTC transport capability configured. If the agent is enabled but WebRTC is not + available + for it, the handshake fails with `404 Not Found`. This is distinct from the `409 + agent_disabled` case + above, which concerns the agent itself rather than its WebRTC capability. + 3. WebRTC compatibility (only when `transport=webrtc`): WebRTC does not support + bring-your-own-model (BYOM) + or hosted-agent voice agents; those requests fail with `400 Bad Request`. + + :param agent_name: The name of the voice agent. Required. + :type agent_name: str + :keyword foundry_features_query: A query alternative to the ``Foundry-Features`` header for + clients that cannot set headers during a + WebSocket handshake. Set this to ``VoiceAgents=V1Preview``. Either this query parameter or the + header is + required. VOICE_AGENTS_V1_PREVIEW. Default value is None. + :paramtype foundry_features_query: str or ~azure.ai.projects.models.VOICE_AGENTS_V1_PREVIEW + :keyword transport: Selects the connection transport. Omit or send ``websocket`` for the + default, where signaling and audio are + exchanged as JSON events over this WebSocket. Send ``webrtc`` to negotiate a WebRTC + connection: the WebSocket + then carries only SDP signaling (``rtc.call.sdp.create`` / ``rtc.call.sdp.created``) while + media and the data + channel are peer-to-peer. Known values are: "websocket" and "webrtc". Default value is None. + :paramtype transport: str or ~azure.ai.projects.models.VoiceAgentTransport + :keyword store: Whether to persist the conversation created by this WebSocket session. If + omitted, the service honors the + persisted voice agent definition's configured ``store`` value. If supplied, this value + overrides the + definition's ``store`` setting for this session only. Default value is None. + :paramtype store: bool + :keyword structured_input: Per-session values for the voice agent's declared + ``structured_inputs``, serialized as a JSON object and + URL-encoded as this query parameter. Supplied values override definition defaults when + rendering the + agent's instructions and session-start greeting for this session only. The decoded value must + be a JSON + object no larger than 32 KiB with a maximum nesting depth of 16. Default value is None. + :paramtype structured_input: str + :keyword agent_version_override: Selects a specific version of the voice agent for this + session. Default value is None. + :paramtype agent_version_override: str + :keyword websocket_subprotocol: The requested WebSocket subprotocol. Omit this header or + request exactly ``realtime``. "realtime" Default value is None. + :paramtype websocket_subprotocol: str or + ~azure.ai.projects.models.VoiceAgentWebSocketSubprotocol + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_voice_agent_web_socket_connect_voice_agent_request( + agent_name=agent_name, + foundry_features_query=foundry_features_query, + transport=transport, + store=store, + structured_input=structured_input, + agent_version_override=agent_version_override, + websocket_subprotocol=websocket_subprotocol, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [101]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Sec-WebSocket-Protocol"] = self._deserialize( + "str", response.headers.get("Sec-WebSocket-Protocol") + ) + + if cls: + return cls(pipeline_response, None, response_headers) # type: ignore + + +class AgentEndpointConversationsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`agent_endpoint_conversations` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_agent_conversations( + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. + + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceConversation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.VoiceConversation]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversations_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.VoiceConversation], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get_agent_conversation( + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceConversation: + """Get a voice agent conversation. + + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.VoiceConversation] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceConversation, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def delete_agent_conversation(self, agent_name: str, conversation_id: str, **kwargs: Any) -> None: + """Delete a voice agent conversation. + + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_delete_agent_conversation_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_agent_conversation_responses( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. + + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceResponse] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.VoiceResponse]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversation_responses_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.VoiceResponse], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get_agent_conversation_response( + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. + + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.VoiceResponse] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_response_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_agent_conversation_response_items( + self, + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. + + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversation_response_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + def list_agent_conversation_items( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. + + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversation_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get_agent_conversation_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. + + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RealtimeConversationItem] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.RealtimeConversationItem, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_item_audio( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceItemAudioResponse: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceItemAudioResponse. The VoiceItemAudioResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.VoiceItemAudioResponse] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_item_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceItemAudioResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_item_audio_content( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's audio. + + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_item_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_item_generated_audio( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedItemAudioResponse: + """Get a voice agent conversation item's generated audio metadata. + + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedItemAudioResponse. The VoiceGeneratedItemAudioResponse is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.VoiceGeneratedItemAudioResponse] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceGeneratedItemAudioResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_item_generated_audio_content( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's generated audio. + + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_audio( + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceRecordingResponse: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecordingResponse. The VoiceRecordingResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecordingResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.VoiceRecordingResponse] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceRecordingResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_agent_conversation_audio_content( + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agent_endpoint_conversations_get_agent_conversation_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + +class AgentTelephonyOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`agent_telephony` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @overload + async def create_telephony_call_job( + self, + agent_name: str, + body: _models.CreateTelephonyCallJobRequest, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_call_job( + self, + agent_name: str, + body: JSON, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: JSON + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_telephony_call_job( + self, + agent_name: str, + body: Union[_models.CreateTelephonyCallJobRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Is one of the following types: + CreateTelephonyCallJobRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest or JSON or IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_create_telephony_call_job_request( + agent_name=agent_name, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_telephony_call_job( + self, agent_name: str, call_job_id: str, **kwargs: Any + ) -> _models.TelephonyCallJob: + """Get an outbound telephony call job. + + Retrieves a durable direct or campaign-created outbound call job. + + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) + + _request = build_agent_telephony_get_telephony_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def cancel_telephony_call_job( + self, agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> _models.TelephonyCallJob: + """Cancel an outbound telephony call job. + + Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) + + _request = build_agent_telephony_cancel_telephony_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, + etag=etag, + match_condition=match_condition, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + if response.status_code == 200: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if response.status_code == 202: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def create_telephony_campaign( + self, + agent_name: str, + body: _models.CreateTelephonyCampaignRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. + + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. + + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCampaignRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_campaign( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. + + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. + + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_campaign( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. + + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. + + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_telephony_campaign( + self, agent_name: str, body: Union[_models.CreateTelephonyCampaignRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. + + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. + + :param agent_name: Required. + :type agent_name: str + :param body: Is one of the following types: CreateTelephonyCampaignRequest, JSON, IO[bytes] + Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCampaignRequest or JSON or IO[bytes] + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_create_telephony_campaign_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> _models.TelephonyCampaign: + """Get an outbound telephony campaign. + + Retrieves an outbound campaign, including configuration, execution state, and aggregate + call-job counts. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) + + _request = build_agent_telephony_get_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + async def _import_telephony_campaign_recipients_initial( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: Union[_models.ImportTelephonyCampaignRecipientsRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_import_telephony_campaign_recipients_request( + agent_name=agent_name, + campaign_id=campaign_id, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: _models.ImportTelephonyCampaignRecipientsRequest, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. + + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: ~azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest + :keyword idempotency_key: Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: JSON, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. + + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: JSON + :keyword idempotency_key: Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. + + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: IO[bytes] + :keyword idempotency_key: Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: Union[_models.ImportTelephonyCampaignRecipientsRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. + + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Is one of the following types: ImportTelephonyCampaignRecipientsRequest, JSON, + IO[bytes] Required. + :type body: ~azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest or JSON or + IO[bytes] + :keyword idempotency_key: Required. + :paramtype idempotency_key: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._import_telephony_campaign_recipients_initial( + agent_name=agent_name, + campaign_id=campaign_id, + body=body, + idempotency_key=idempotency_key, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + @distributed_trace_async + async def get_telephony_campaign_recipient_import( + self, agent_name: str, campaign_id: str, import_id: str, **kwargs: Any + ) -> _models.TelephonyCampaignRecipientImport: + """Get an outbound telephony campaign recipient import. + + Retrieves the durable status and counters for a campaign recipient import. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param import_id: Required. + :type import_id: str + :return: TelephonyCampaignRecipientImport. The TelephonyCampaignRecipientImport is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaignRecipientImport + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCampaignRecipientImport] = kwargs.pop("cls", None) + + _request = build_agent_telephony_get_telephony_campaign_recipient_import_request( + agent_name=agent_name, + campaign_id=campaign_id, + import_id=import_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaignRecipientImport, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + async def _validate_telephony_campaign_initial( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agent_telephony_validate_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def begin_validate_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Validate an outbound telephony campaign. + + Starts asynchronous validation of the current campaign draft and imported recipient snapshot. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._validate_telephony_campaign_initial( + agent_name=agent_name, + campaign_id=campaign_id, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + async def _publish_telephony_campaign_initial( + self, + agent_name: str, + campaign_id: str, + body: Union[_models.PublishTelephonyCampaignRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_publish_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: _models.PublishTelephonyCampaignRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. + + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: ~azure.ai.projects.models.PublishTelephonyCampaignRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_publish_telephony_campaign( + self, agent_name: str, campaign_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. + + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. + + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: Union[_models.PublishTelephonyCampaignRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncLROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. + + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Is one of the following types: PublishTelephonyCampaignRequest, JSON, IO[bytes] + Required. + :type body: ~azure.ai.projects.models.PublishTelephonyCampaignRequest or JSON or IO[bytes] + :return: An instance of AsyncLROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._publish_telephony_campaign_initial( + agent_name=agent_name, + campaign_id=campaign_id, + body=body, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - return pipeline_response + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return AsyncItemPaged(get_next, extract_data) + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace_async - async def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: - """Get a version. + async def pause_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> _models.TelephonyCampaign: + """Pause an outbound telephony campaign. - Get the specific version of the Index. The service returns 404 Not Found error if the Index - does not exist. + Pauses dispatch of call jobs owned by a published campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to retrieve. Required. - :type version: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5180,11 +9586,11 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Index] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - _request = build_indexes_get_request( - name=name, - version=version, + _request = build_agent_telephony_pause_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5209,12 +9615,16 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -5222,18 +9632,19 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: return deserialized # type: ignore @distributed_trace_async - async def delete(self, name: str, version: str, **kwargs: Any) -> None: - """Delete a version. + async def resume_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> _models.TelephonyCampaign: + """Resume an outbound telephony campaign. - Delete the specific version of the Index. The service returns 204 No Content if the Index was - deleted successfully or if the Index does not exist. + Resumes dispatch of call jobs owned by a paused campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the Index to delete. Required. - :type version: str - :return: None - :rtype: None + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5247,11 +9658,11 @@ async def delete(self, name: str, version: str, **kwargs: Any) -> None: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - _request = build_indexes_delete_request( - name=name, - version=version, + _request = build_agent_telephony_resume_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5261,115 +9672,123 @@ async def delete(self, name: str, version: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore - @overload - async def create_or_update( - self, - name: str, - version: str, - index: _models.Index, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.Index: - """Create or update a version. + return deserialized # type: ignore - Create a new or update an existing Index with the given version id. + @distributed_trace_async + async def cancel_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> _models.TelephonyCampaign: + """Cancel an outbound telephony campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: ~azure.ai.projects.models.Index - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + Cancels a campaign and prevents any further call-job dispatch. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - async def create_or_update( - self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.Index: - """Create or update a version. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Create a new or update an existing Index with the given version id. + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_agent_telephony_cancel_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - @overload - async def create_or_update( - self, - name: str, - version: str, - index: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.Index: - """Create or update a version. + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - Create a new or update an existing Index with the given version id. + response = pipeline_response.http_response - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace_async - async def create_or_update( - self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any - ) -> _models.Index: - """Create or update a version. + async def get_telephony_operation( + self, agent_name: str, operation_id: str, **kwargs: Any + ) -> _models.TelephonyOperation: + """Get an outbound telephony operation. - Create a new or update an existing Index with the given version id. + Retrieves an asynchronous outbound campaign operation. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Is one of the following types: Index, JSON, - IO[bytes] Required. - :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param agent_name: Required. + :type agent_name: str + :param operation_id: Required. + :type operation_id: str + :return: TelephonyOperation. The TelephonyOperation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyOperation :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5380,25 +9799,15 @@ async def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Index] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(index, (IOBase, bytes)): - _content = index - else: - _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyOperation] = kwargs.pop("cls", None) - _request = build_indexes_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_agent_telephony_get_telephony_operation_request( + agent_name=agent_name, + operation_id=operation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -5415,19 +9824,23 @@ async def create_or_update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.TelephonyOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py index 6462512ea065..c43045c8cdda 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py @@ -10,6 +10,7 @@ from typing import Any, List from ._patch_agents_async import AgentsOperations, BetaAgentsOperations +from ._patch_agent_endpoint_conversations_async import AgentEndpointConversationsOperations from ._patch_agent_insights_async import BetaAgentInsightMonitorsOperations from ._patch_datasets_async import BetaDatasetsOperations, DatasetsOperations from ._patch_evaluators_async import BetaEvaluatorsOperations @@ -92,6 +93,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: __all__: List[str] = [ "AgentsOperations", + "AgentEndpointConversationsOperations", "BetaAgentInsightMonitorsOperations", "BetaAgentsOperations", "BetaDatasetsOperations", diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agent_endpoint_conversations_async.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agent_endpoint_conversations_async.py new file mode 100644 index 000000000000..563182dfee95 --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agent_endpoint_conversations_async.py @@ -0,0 +1,752 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" + +from typing import Any, AsyncIterator, Optional, Union +from azure.core.async_paging import AsyncItemPaged +from azure.core.exceptions import HttpResponseError +from azure.core.tracing.decorator import distributed_trace +from azure.core.tracing.decorator_async import distributed_trace_async +from ._operations import AgentEndpointConversationsOperations as GeneratedAgentEndpointConversationsOperations +from ... import models as _models +from ...models._enums import _AgentDefinitionOptInKeys +from ...models._patch import ( + _FOUNDRY_FEATURES_HEADER_NAME, + _has_header_case_insensitive, + _PREVIEW_FEATURE_REQUIRED_CODE, + _PREVIEW_FEATURE_ADDED_ERROR_MESSAGE, +) + +# All methods on this class always require the VoiceAgents=V1Preview opt-in (voice-agent +# conversation reads), regardless of `allow_preview` -- see the matching NOTE in the sync +# `_patch_agent_endpoint_conversations.py` for the full explanation (confirmed empirically against +# the live service). +_VOICE_AGENTS_HEADER_VALUE = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + + +class AgentEndpointConversationsOperations(GeneratedAgentEndpointConversationsOperations): + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`agent_endpoint_conversations` attribute. + """ + + @distributed_trace + def list_agent_conversations( # type: ignore[override] + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> AsyncItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. + + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. When the client is constructed + with ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceConversation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversations(agent_name, limit=limit, order=order, before=before, **kwargs) + + @distributed_trace_async + async def get_agent_conversation( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceConversation: + """Get a voice agent conversation. + + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. + When the client is constructed with ``allow_preview=True``, the required preview opt-in header + is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def delete_agent_conversation( # pylint: disable=inconsistent-return-statements # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> None: + """Delete a voice agent conversation. + + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. When the client + is constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().delete_agent_conversation(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_agent_conversation_responses( # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> AsyncItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. + + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). When the client is constructed with ``allow_preview=True``, + the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceResponse] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_responses( + agent_name, conversation_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace_async + async def get_agent_conversation_response( # type: ignore[override] + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. + + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). When the client is constructed with ``allow_preview=True``, the + required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_response(agent_name, conversation_id, response_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_agent_conversation_response_items( # pylint: disable=name-too-long # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. + + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_response_items( + agent_name, conversation_id, response_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace + def list_agent_conversation_items( # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. + + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_items( + agent_name, conversation_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace_async + async def get_agent_conversation_item( # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. + + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_item(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_item_audio( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceItemAudioResponse: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. When the client is constructed with ``allow_preview=True``, the required preview + opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceItemAudioResponse. The VoiceItemAudioResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_item_audio(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_item_audio_content( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's audio. + + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_item_audio_content( + agent_name, conversation_id, item_id, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_item_generated_audio( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedItemAudioResponse: + """Get a voice agent conversation item's generated audio metadata. + + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedItemAudioResponse. The VoiceGeneratedItemAudioResponse is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = { + _FOUNDRY_FEATURES_HEADER_NAME: _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + } + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_item_generated_audio( + agent_name, conversation_id, item_id, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_item_generated_audio_content( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's generated audio. + + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. When the client is constructed with ``allow_preview=True``, the required preview + opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = { + _FOUNDRY_FEATURES_HEADER_NAME: _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + } + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_item_generated_audio_content( + agent_name, conversation_id, item_id, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_audio( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceRecordingResponse: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecordingResponse. The VoiceRecordingResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecordingResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_audio(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_agent_conversation_audio_content( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return await super().get_agent_conversation_audio_content(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agents_async.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agents_async.py index adece538505b..70138de44d37 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agents_async.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_agents_async.py @@ -1,4 +1,4 @@ -# pylint: disable=line-too-long,useless-suppression +# pylint: disable=line-too-long,useless-suppression,too-many-lines # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -8,10 +8,14 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ -from typing import Union, Optional, Any, IO, cast, overload +import datetime +from typing import Union, Optional, Any, IO, List, cast, overload, TYPE_CHECKING +from azure.core import MatchConditions +from azure.core.async_paging import AsyncItemPaged from azure.core.exceptions import HttpResponseError from azure.core.polling import AsyncNoPolling, AsyncPollingMethod from azure.core.polling.async_base_polling import AsyncLROBasePolling +from azure.core.tracing.decorator import distributed_trace from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.utils import case_insensitive_dict from ._operations import ( @@ -32,6 +36,9 @@ _PREVIEW_FEATURE_ADDED_ERROR_MESSAGE, ) +if TYPE_CHECKING: + from ... import _unions + class AgentsOperations(GeneratedAgentsOperations): """ @@ -43,7 +50,7 @@ class AgentsOperations(GeneratedAgentsOperations): :attr:`agents` attribute. """ - @overload + @overload # type: ignore[override] async def create_version( self, agent_name: str, @@ -145,7 +152,7 @@ async def create_version( """ @distributed_trace_async - async def create_version( + async def create_version( # type: ignore[override] self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, @@ -203,9 +210,9 @@ async def create_version( kwargs["headers"] = headers try: - return await super().create_version( + return await super().create_version( # type: ignore[misc] agent_name, - body, + body, # type: ignore[arg-type] definition=definition, metadata=metadata, description=description, @@ -325,42 +332,1000 @@ async def create_version_from_code( raise new_exc from exc raise + @distributed_trace_async + async def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: # type: ignore[override] + """Generate an agent. -class BetaAgentsOperations(BetaAgentsOperationsGenerated): - """Custom async operations for beta agent optimization jobs.""" + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. - @overload - async def begin_create_optimization_job( + :param body: The kind-specific inputs for generating and creating an agent. Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().generate_agent(body, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + async def create_telephony_binding( self, - job: _models.AgentOptimizationJob, + agent_name: str, + body: _models.CreateTelephonyBindingRequest, *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any, - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @overload - async def begin_create_optimization_job( + async def create_telephony_binding( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_telephony_binding( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_telephony_binding( # type: ignore[override] + self, agent_name: str, body: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Is one of the following types: + CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().create_telephony_binding(agent_name, body, **kwargs) # type: ignore[arg-type] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_telephony_bindings( # type: ignore[override] self, - job: JSON, + agent_name: str, *, - operation_id: Optional[str] = None, - content_type: str = "application/json", + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any, - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> AsyncItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. + + Returns the telephony bindings owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent whose bindings are listed. Required. + :type agent_name: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :keyword limit: A limit on the number of objects to be returned. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. Known values are: + "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyBindingListItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + return super().list_telephony_bindings( + agent_name, provider=provider, status=status, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace_async + async def get_telephony_binding( # type: ignore[override] + self, agent_name: str, binding_id: str, **kwargs: Any + ) -> _models.TelephonyBinding: + """Get an agent telephony binding. + + Retrieves a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().get_telephony_binding(agent_name, binding_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @overload - async def begin_create_optimization_job( + async def update_telephony_binding( self, - job: IO[bytes], + agent_name: str, + binding_id: str, + body: JSON, *, - operation_id: Optional[str] = None, - content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", **kwargs: Any, - ) -> AsyncAgentOptimizationLROPoller: ... + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def begin_create_optimization_job( + async def update_telephony_binding( # type: ignore[override] + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().update_telephony_binding( # type: ignore[arg-type] + agent_name, binding_id, body, etag=etag, match_condition=match_condition, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def delete_telephony_binding( # type: ignore[override] # pylint: disable=inconsistent-return-statements + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. + + Deletes a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().delete_telephony_binding(agent_name, binding_id, etag=etag, match_condition=match_condition, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_telephony_calls( # type: ignore[override] + self, + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after: Optional[datetime.datetime] = None, + started_before: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> AsyncItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. + + Returns the durable inbound call history for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", + "success", and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after: Includes calls that started at or after this Unix timestamp in + seconds. Default value is None. + :paramtype started_after: ~datetime.datetime + :keyword started_before: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before: ~datetime.datetime + :keyword limit: A limit on the number of objects to be returned. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. Known values are: + "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyCallSummary] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + return super().list_telephony_calls( + agent_name, + provider=provider, + status=status, + started_after=started_after, + started_before=started_before, + limit=limit, + order=order, + before=before, + **kwargs, + ) + + @distributed_trace_async + async def get_telephony_call( # type: ignore[override] + self, agent_name: str, call_id: str, **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Get an agent telephony call. + + Retrieves a durable inbound call record owned by the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().get_telephony_call(agent_name, call_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + async def transfer_telephony_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def transfer_telephony_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def transfer_telephony_call( # type: ignore[override] + self, + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + target: str = _Unset, + **kwargs: Any, + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().transfer_telephony_call(agent_name, call_id, body, target=target, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def end_telephony_call( # type: ignore[override] + self, agent_name: str, call_id: str, **kwargs: Any + ) -> _models.TelephonyCallRecord: + """End an active agent telephony call. + + Ends an active inbound call owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().end_telephony_call(agent_name, call_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace_async + async def get_telephony_transfer_targets( # type: ignore[override] + self, agent_name: str, **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. + + Returns all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().get_telephony_transfer_targets(agent_name, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + async def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + transfer_targets: List[_models.TelephonyTransferTarget], + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def replace_telephony_transfer_targets( # type: ignore[override] + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, + etag: str, + match_condition: MatchConditions, + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return await super().replace_telephony_transfer_targets( # type: ignore[arg-type] + agent_name, + body, + transfer_targets=transfer_targets, + etag=etag, + match_condition=match_condition, + **kwargs, + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + +class BetaAgentsOperations(BetaAgentsOperationsGenerated): + """Custom async operations for beta agent optimization jobs.""" + + @overload # type: ignore[override] + async def begin_create_optimization_job( + self, + job: _models.AgentOptimizationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AsyncAgentOptimizationLROPoller: ... + + @overload + async def begin_create_optimization_job( + self, + job: JSON, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AsyncAgentOptimizationLROPoller: ... + + @overload + async def begin_create_optimization_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AsyncAgentOptimizationLROPoller: ... + + @distributed_trace_async + async def begin_create_optimization_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], *, @@ -389,7 +1354,7 @@ async def begin_create_optimization_job( raw_result = None if continuation_token is None: raw_result = await self._create_optimization_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_datasets_async.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_datasets_async.py index 6612e31eacad..a0c389b051e9 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_datasets_async.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_datasets_async.py @@ -12,7 +12,6 @@ import re import logging from typing import Any, IO, Tuple, Optional, Union, cast, overload -from collections.abc import MutableMapping from pathlib import Path from urllib.parse import urlsplit from azure.storage.blob.aio import ContainerClient @@ -24,6 +23,7 @@ from ._operations import ( BetaDatasetsOperations as BetaDatasetsOperationsGenerated, DatasetsOperations as DatasetsOperationsGenerated, + JSON, ) from ... import models as _models from ..._utils.model_base import _deserialize @@ -38,13 +38,11 @@ logger = logging.getLogger(__name__) -JSON = MutableMapping[str, Any] - class BetaDatasetsOperations(BetaDatasetsOperationsGenerated): """Custom async operations for beta data generation jobs.""" - @overload + @overload # type: ignore[override] async def begin_create_generation_job( self, job: _models.DataGenerationJob, @@ -75,7 +73,7 @@ async def begin_create_generation_job( ) -> AsyncDatasetGenerationLROPoller: ... @distributed_trace_async - async def begin_create_generation_job( + async def begin_create_generation_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.DataGenerationJob, JSON, IO[bytes]], *, @@ -104,7 +102,7 @@ async def begin_create_generation_job( raw_result = None if continuation_token is None: raw_result = await self._create_generation_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluation_rules_async.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluation_rules_async.py index 7e61eeb2866c..7f7d1902d5ff 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluation_rules_async.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluation_rules_async.py @@ -32,7 +32,7 @@ class EvaluationRulesOperations(GeneratedEvaluationRulesOperations): :attr:`evaluation_rules` attribute. """ - @overload + @overload # type: ignore[override] async def create_or_update( self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any ) -> _models.EvaluationRule: @@ -90,7 +90,7 @@ async def create_or_update( ... @distributed_trace_async - async def create_or_update( + async def create_or_update( # type: ignore[override] self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any ) -> _models.EvaluationRule: """Create or update an evaluation rule. @@ -116,7 +116,7 @@ async def create_or_update( kwargs["headers"] = headers try: - return await super().create_or_update(id, evaluation_rule, **kwargs) + return await super().create_or_update(id, evaluation_rule, **kwargs) # type: ignore[arg-type] except HttpResponseError as exc: if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: api_error_response = exc.model diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluators_async.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluators_async.py index 50876c48cdfe..f1e76ff5c3d9 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluators_async.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluators_async.py @@ -5,7 +5,6 @@ # ------------------------------------ """Custom async evaluator operations.""" -from collections.abc import MutableMapping from typing import Any, IO, Optional, Union, cast, overload from azure.core.polling import AsyncNoPolling, AsyncPollingMethod @@ -13,18 +12,16 @@ from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.utils import case_insensitive_dict -from ._operations import BetaEvaluatorsOperations as BetaEvaluatorsOperationsGenerated +from ._operations import BetaEvaluatorsOperations as BetaEvaluatorsOperationsGenerated, JSON from ... import models as _models from ..._utils.model_base import _deserialize from ...models import AsyncEvaluatorGenerationLROPoller -JSON = MutableMapping[str, Any] - class BetaEvaluatorsOperations(BetaEvaluatorsOperationsGenerated): """Custom async operations for beta evaluator generation jobs.""" - @overload + @overload # type: ignore[override] async def begin_create_generation_job( self, job: _models.EvaluatorGenerationJob, @@ -55,7 +52,7 @@ async def begin_create_generation_job( ) -> AsyncEvaluatorGenerationLROPoller: ... @distributed_trace_async - async def begin_create_generation_job( + async def begin_create_generation_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], *, @@ -84,7 +81,7 @@ async def begin_create_generation_job( raw_result = None if continuation_token is None: raw_result = await self._create_generation_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py index 2a0def115184..2e575d8b21b4 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py @@ -132,6 +132,12 @@ CosmosDBIndex, CreateAsyncResponse, CreateSkillVersionFromFilesBody, + CreateTeamsPhoneExtensionTelephonyBindingRequest, + CreateTelephonyBindingRequest, + CreateTelephonyCallJobRequest, + CreateTelephonyCampaignRequest, + CreateTranscriptionResponseJsonUsage, + CreateTwilioTelephonyBindingRequest, CronTrigger, CustomCredential, CustomGrammarFormatParam, @@ -212,6 +218,7 @@ FunctionShellToolParamEnvironmentLocalEnvironmentParam, FunctionTool, FunctionToolParam, + GenerateVoiceAgentRequest, GitHubIssueRoutineTrigger, HeaderTelemetryEndpointAuth, HostedAgentDefinition, @@ -220,6 +227,7 @@ HybridSearchOptions, ImageGenTool, ImageGenToolInputImageMask, + ImportTelephonyCampaignRecipientsRequest, Index, InlineSkillParam, InlineSkillSourceParam, @@ -240,7 +248,11 @@ InvokeAgentResponsesApiRoutineAction, LocalShellToolParam, LocalSkillParam, + LogProbProperties, LoraConfig, + MCPListToolsTool, + MCPListToolsToolAnnotations, + MCPListToolsToolInputSchema, MCPTool, MCPToolFilter, MCPToolRequireApproval, @@ -262,6 +274,7 @@ MemoryStoreSearchResult, MemoryStoreUpdateCompletedResult, MemoryStoreUpdateResult, + Metadata, Microsoft365PermissionScopes, Microsoft365PublishDefaults, Microsoft365PublishResult, @@ -290,8 +303,10 @@ OpenApiToolboxTool, OptimizedAgentIdentifier, OtlpTelemetryEndpoint, + PSTNTelephonyTransferDestination, PendingUploadRequest, PendingUploadResponse, + PickPropertiesVoiceAgentAudioConfig, ProceduralMemoryItem, ProgrammaticToolCallingParam, PromotionInfo, @@ -302,8 +317,101 @@ PromptEvaluatorGenerationJobSource, ProtocolConfiguration, ProtocolVersionRecord, + PublishTelephonyCampaignRequest, RaiConfig, + RaiInvocationModeration, + RaiSseTextSelector, RankingOptions, + RealtimeAudioFormats, + RealtimeAudioFormatsAudioPcm, + RealtimeAudioFormatsAudioPcma, + RealtimeAudioFormatsAudioPcmu, + RealtimeClientEvent, + RealtimeClientEventConversationItemCreate, + RealtimeClientEventConversationItemDelete, + RealtimeClientEventConversationItemRetrieve, + RealtimeClientEventConversationItemTruncate, + RealtimeClientEventInputAudioBufferAppend, + RealtimeClientEventInputAudioBufferClear, + RealtimeClientEventInputAudioBufferCommit, + RealtimeClientEventOutputAudioBufferClear, + RealtimeClientEventResponseCancel, + RealtimeClientEventResponseCreate, + RealtimeConversationItem, + RealtimeConversationItemFunctionCall, + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessage, + RealtimeConversationItemMessageAssistant, + RealtimeConversationItemMessageAssistantContent, + RealtimeConversationItemMessageSystem, + RealtimeConversationItemMessageSystemContent, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeFunctionTool, + RealtimeFunctionToolParameters, + RealtimeMCPApprovalRequest, + RealtimeMCPApprovalResponse, + RealtimeMCPError, + RealtimeMCPHTTPError, + RealtimeMCPListTools, + RealtimeMCPProtocolError, + RealtimeMCPToolCall, + RealtimeMCPToolExecutionError, + RealtimeReasoning, + RealtimeResponseStatusDetails, + RealtimeResponseStatusDetailsError, + RealtimeResponseUsage, + RealtimeResponseUsageInputTokenDetails, + RealtimeResponseUsageInputTokenDetailsCachedTokensDetails, + RealtimeResponseUsageOutputTokenDetails, + RealtimeServerEvent, + RealtimeServerEventConversationItemAdded, + RealtimeServerEventConversationItemCreated, + RealtimeServerEventConversationItemDeleted, + RealtimeServerEventConversationItemDone, + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + RealtimeServerEventConversationItemInputAudioTranscriptionFailedError, + RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + RealtimeServerEventConversationItemRetrieved, + RealtimeServerEventConversationItemTruncated, + RealtimeServerEventError, + RealtimeServerEventErrorError, + RealtimeServerEventInputAudioBufferCleared, + RealtimeServerEventInputAudioBufferCommitted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventInputAudioBufferSpeechStopped, + RealtimeServerEventInputAudioBufferTimeoutTriggered, + RealtimeServerEventMCPListToolsCompleted, + RealtimeServerEventMCPListToolsFailed, + RealtimeServerEventMCPListToolsInProgress, + RealtimeServerEventOutputAudioBufferCleared, + RealtimeServerEventRateLimitsUpdated, + RealtimeServerEventRateLimitsUpdatedRateLimits, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioDone, + RealtimeServerEventResponseAudioTranscriptDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseContentPartAdded, + RealtimeServerEventResponseContentPartAddedPart, + RealtimeServerEventResponseContentPartDone, + RealtimeServerEventResponseContentPartDonePart, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDelta, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseMCPCallArgumentsDelta, + RealtimeServerEventResponseMCPCallArgumentsDone, + RealtimeServerEventResponseMCPCallCompleted, + RealtimeServerEventResponseMCPCallFailed, + RealtimeServerEventResponseMCPCallInProgress, + RealtimeServerEventResponseOutputItemAdded, + RealtimeServerEventResponseOutputItemDone, + RealtimeServerEventResponseTextDelta, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventSessionUpdated, Reasoning, RecurrenceSchedule, RecurrenceTrigger, @@ -335,6 +443,7 @@ ShellToolboxTool, SimpleQnADataGenerationJobOptions, SimulationSeedDataGenerationJobOptions, + SipTelephonyTransferDestination, SkillDetails, SkillInlineContent, SkillReferenceParam, @@ -346,9 +455,39 @@ StructuredOutputDefinition, TaxonomyCategory, TaxonomySubCategory, + TeamsPhoneExtensionTelephonyBinding, + TeamsPhoneExtensionTelephonyBindingListItem, + TeamsTelephonyTransferDestination, TelemetryConfig, TelemetryEndpoint, TelemetryEndpointAuth, + TelephonyBinding, + TelephonyBindingListItem, + TelephonyCallJob, + TelephonyCallJobCancellation, + TelephonyCallJobSchedule, + TelephonyCallLifecycleEvent, + TelephonyCallRecord, + TelephonyCallSummary, + TelephonyCallTiming, + TelephonyCallTrace, + TelephonyCampaign, + TelephonyCampaignCallJobCounts, + TelephonyCampaignRecipientImport, + TelephonyCampaignRecipientImportSource, + TelephonyCampaignRecipientMapping, + TelephonyCampaignRecipientMappingRequest, + TelephonyCampaignSchedule, + TelephonyOperation, + TelephonyOperationResource, + TelephonyOutboundDestination, + TelephonyOutboundFixedIntervalRetryPolicy, + TelephonyOutboundFixedIntervalRetryPolicyResponse, + TelephonyOutboundRetryPolicy, + TelephonyOutboundRetryPolicyResponse, + TelephonyTransferDestination, + TelephonyTransferTarget, + TelephonyTransferTargets, TextResponseFormat, TextResponseFormatJsonObject, TextResponseFormatJsonSchema, @@ -389,14 +528,97 @@ TracesDataGenerationJobOptions, TracesDataGenerationJobSource, TracesEvaluatorGenerationJobSource, + TranscriptTextUsageDuration, + TranscriptTextUsageTokens, + TranscriptTextUsageTokensInputTokenDetails, + TranscriptionLanguage, Trigger, + TwilioTelephonyBinding, + TwilioTelephonyBindingListItem, UpdateModelVersionRequest, + UpdateTelephonyBindingRequest, UpdateToolboxRequest, UserProfileMemoryItem, VersionIndicator, VersionRefIndicator, VersionSelectionRule, VersionSelector, + VoiceAgentAnimationConfig, + VoiceAgentAudioConfig, + VoiceAgentAudioInputConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentAvatarConfig, + VoiceAgentAvatarIceServer, + VoiceAgentAvatarScene, + VoiceAgentAvatarVideoBackground, + VoiceAgentAvatarVideoCrop, + VoiceAgentAvatarVideoParams, + VoiceAgentAvatarVideoResolution, + VoiceAgentAzureSemanticVadEnTurnDetection, + VoiceAgentAzureSemanticVadMultilingualTurnDetection, + VoiceAgentAzureSemanticVadTurnDetection, + VoiceAgentClientEventRtcCallSdpCreate, + VoiceAgentClientEventSessionAvatarConnect, + VoiceAgentClientEventSessionUpdate, + VoiceAgentDefinition, + VoiceAgentEchoCancellation, + VoiceAgentEndOfUtteranceDetection, + VoiceAgentFunctionTool, + VoiceAgentGreetingConfig, + VoiceAgentInputTranscription, + VoiceAgentInterimResponseConfig, + VoiceAgentLlmGeneratedGreetingConfig, + VoiceAgentLlmInterimResponseConfig, + VoiceAgentMcpTool, + VoiceAgentNoiseReduction, + VoiceAgentRealtimeResponse, + VoiceAgentRealtimeResponseBase, + VoiceAgentResponseCreateParams, + VoiceAgentRtcCallErrorDetails, + VoiceAgentSemanticVadTurnDetection, + VoiceAgentServerEventResponseAnimationBlendshapesDelta, + VoiceAgentServerEventResponseAnimationBlendshapesDone, + VoiceAgentServerEventResponseAnimationVisemeDelta, + VoiceAgentServerEventResponseAnimationVisemeDone, + VoiceAgentServerEventResponseAudioTimestampDelta, + VoiceAgentServerEventResponseAudioTimestampDone, + VoiceAgentServerEventResponseVideoDelta, + VoiceAgentServerEventRtcCallError, + VoiceAgentServerEventRtcCallSdpCreated, + VoiceAgentServerEventSessionAvatarConnecting, + VoiceAgentServerEventSessionAvatarSwitchToIdle, + VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + VoiceAgentServerEventSessionSubagentAborted, + VoiceAgentServerEventSessionSubagentCompleted, + VoiceAgentServerEventSessionSubagentStarted, + VoiceAgentServerEventWarning, + VoiceAgentServerEventWarningDetails, + VoiceAgentServerVadTurnDetection, + VoiceAgentSessionAvatarConfig, + VoiceAgentSessionResponseConfig, + VoiceAgentSessionUpdateConfig, + VoiceAgentStaticInterimResponseConfig, + VoiceAgentSubagent, + VoiceAgentSubagentConfig, + VoiceAgentSubagentResponsePolicy, + VoiceAgentSystemTool, + VoiceAgentTemplateGreetingConfig, + VoiceAgentTool, + VoiceAgentToolboxTool, + VoiceAgentTranscriptionPhrase, + VoiceAgentTranscriptionWord, + VoiceAgentTurnDetectionConfig, + VoiceConversation, + VoiceConversationEngine, + VoiceGeneratedItemAudioResponse, + VoiceHostedAgentConversationEngine, + VoiceItemAudioResponse, + VoiceRecordingChannelLayout, + VoiceRecordingResponse, + VoiceResponse, + VoiceResponseAudio, + VoiceResponseAudioOutput, + VoiceResponseBase, WebIQPreviewTool, WebIQPreviewToolboxTool, WebSearchApproximateLocation, @@ -440,6 +662,7 @@ ContainerMemoryLimit, ContainerNetworkPolicyParamType, ContainerSkillType, + CreateTranscriptionResponseJsonUsageType, CredentialType, CustomToolParamFormatType, DataGenerationJobOutputType, @@ -485,7 +708,16 @@ PageOrder, PendingUploadType, PublishApprovalStatus, + RaiInvocationContentType, + RaiInvocationMode, RankerVersionType, + RealtimeAudioFormatsType, + RealtimeClientEventType, + RealtimeConversationItemMessageType, + RealtimeConversationItemType, + RealtimeMcpErrorType, + RealtimeReasoningEffort, + RealtimeServerEventType, ReasoningEffort, ReasoningModeEnum, RecurrenceType, @@ -510,7 +742,30 @@ TelemetryEndpointAuthType, TelemetryEndpointKind, TelemetryTransportProtocol, + TelephonyBindingStatus, + TelephonyCallDurationBasis, + TelephonyCallJobStatus, + TelephonyCallLifecycleEventName, + TelephonyCallLifecycleEventOutcome, + TelephonyCallLifecycleEventSource, + TelephonyCallPhase, + TelephonyCallStatus, + TelephonyCallTimestampSource, + TelephonyCallTraceMode, + TelephonyCallTraceStatus, + TelephonyCampaignConfigurationStatus, + TelephonyCampaignDuplicateHandling, + TelephonyCampaignExecutionStatus, + TelephonyCampaignRecipientImportFormat, + TelephonyCampaignRecipientImportStatus, + TelephonyCampaignScheduleType, + TelephonyOperationStatus, + TelephonyOutboundDestinationType, + TelephonyOutboundRetryPolicyType, + TelephonyProvider, + TelephonyTransferDestinationKind, TextResponseFormatConfigurationType, + ToolChoiceOptions, ToolChoiceParamType, ToolSearchExecutionType, ToolType, @@ -519,6 +774,30 @@ TriggerType, VersionIndicatorType, VersionSelectorType, + VoiceAgentAnimationOutputType, + VoiceAgentAudioTimestampType, + VoiceAgentAvatarOutputProtocol, + VoiceAgentAvatarType, + VoiceAgentEchoCancellationReferenceSource, + VoiceAgentEndOfUtteranceDetectionModel, + VoiceAgentEndOfUtteranceThresholdLevel, + VoiceAgentInputTranscriptionModel, + VoiceAgentInterimResponseTrigger, + VoiceAgentNoiseReductionType, + VoiceAgentSessionIncludeOption, + VoiceAgentSubagentAbortReason, + VoiceAgentSystemToolName, + VoiceAgentToolResponseScheduling, + VoiceAgentTransport, + VoiceAgentTurnDetectionType, + VoiceAgentWebSocketSubprotocol, + VoiceAudioCodec, + VoiceAudioContainerFormat, + VoiceAudioRole, + VoiceConversationStatus, + VoiceModelType, + VoiceOutputModality, + VoiceType, ) from ._patch import __all__ as _patch_all from ._patch import * @@ -642,6 +921,12 @@ "CosmosDBIndex", "CreateAsyncResponse", "CreateSkillVersionFromFilesBody", + "CreateTeamsPhoneExtensionTelephonyBindingRequest", + "CreateTelephonyBindingRequest", + "CreateTelephonyCallJobRequest", + "CreateTelephonyCampaignRequest", + "CreateTranscriptionResponseJsonUsage", + "CreateTwilioTelephonyBindingRequest", "CronTrigger", "CustomCredential", "CustomGrammarFormatParam", @@ -722,6 +1007,7 @@ "FunctionShellToolParamEnvironmentLocalEnvironmentParam", "FunctionTool", "FunctionToolParam", + "GenerateVoiceAgentRequest", "GitHubIssueRoutineTrigger", "HeaderTelemetryEndpointAuth", "HostedAgentDefinition", @@ -730,6 +1016,7 @@ "HybridSearchOptions", "ImageGenTool", "ImageGenToolInputImageMask", + "ImportTelephonyCampaignRecipientsRequest", "Index", "InlineSkillParam", "InlineSkillSourceParam", @@ -750,7 +1037,11 @@ "InvokeAgentResponsesApiRoutineAction", "LocalShellToolParam", "LocalSkillParam", + "LogProbProperties", "LoraConfig", + "MCPListToolsTool", + "MCPListToolsToolAnnotations", + "MCPListToolsToolInputSchema", "MCPTool", "MCPToolFilter", "MCPToolRequireApproval", @@ -772,6 +1063,7 @@ "MemoryStoreSearchResult", "MemoryStoreUpdateCompletedResult", "MemoryStoreUpdateResult", + "Metadata", "Microsoft365PermissionScopes", "Microsoft365PublishDefaults", "Microsoft365PublishResult", @@ -800,8 +1092,10 @@ "OpenApiToolboxTool", "OptimizedAgentIdentifier", "OtlpTelemetryEndpoint", + "PSTNTelephonyTransferDestination", "PendingUploadRequest", "PendingUploadResponse", + "PickPropertiesVoiceAgentAudioConfig", "ProceduralMemoryItem", "ProgrammaticToolCallingParam", "PromotionInfo", @@ -812,8 +1106,101 @@ "PromptEvaluatorGenerationJobSource", "ProtocolConfiguration", "ProtocolVersionRecord", + "PublishTelephonyCampaignRequest", "RaiConfig", + "RaiInvocationModeration", + "RaiSseTextSelector", "RankingOptions", + "RealtimeAudioFormats", + "RealtimeAudioFormatsAudioPcm", + "RealtimeAudioFormatsAudioPcma", + "RealtimeAudioFormatsAudioPcmu", + "RealtimeClientEvent", + "RealtimeClientEventConversationItemCreate", + "RealtimeClientEventConversationItemDelete", + "RealtimeClientEventConversationItemRetrieve", + "RealtimeClientEventConversationItemTruncate", + "RealtimeClientEventInputAudioBufferAppend", + "RealtimeClientEventInputAudioBufferClear", + "RealtimeClientEventInputAudioBufferCommit", + "RealtimeClientEventOutputAudioBufferClear", + "RealtimeClientEventResponseCancel", + "RealtimeClientEventResponseCreate", + "RealtimeConversationItem", + "RealtimeConversationItemFunctionCall", + "RealtimeConversationItemFunctionCallOutput", + "RealtimeConversationItemMessage", + "RealtimeConversationItemMessageAssistant", + "RealtimeConversationItemMessageAssistantContent", + "RealtimeConversationItemMessageSystem", + "RealtimeConversationItemMessageSystemContent", + "RealtimeConversationItemMessageUser", + "RealtimeConversationItemMessageUserContent", + "RealtimeFunctionTool", + "RealtimeFunctionToolParameters", + "RealtimeMCPApprovalRequest", + "RealtimeMCPApprovalResponse", + "RealtimeMCPError", + "RealtimeMCPHTTPError", + "RealtimeMCPListTools", + "RealtimeMCPProtocolError", + "RealtimeMCPToolCall", + "RealtimeMCPToolExecutionError", + "RealtimeReasoning", + "RealtimeResponseStatusDetails", + "RealtimeResponseStatusDetailsError", + "RealtimeResponseUsage", + "RealtimeResponseUsageInputTokenDetails", + "RealtimeResponseUsageInputTokenDetailsCachedTokensDetails", + "RealtimeResponseUsageOutputTokenDetails", + "RealtimeServerEvent", + "RealtimeServerEventConversationItemAdded", + "RealtimeServerEventConversationItemCreated", + "RealtimeServerEventConversationItemDeleted", + "RealtimeServerEventConversationItemDone", + "RealtimeServerEventConversationItemInputAudioTranscriptionCompleted", + "RealtimeServerEventConversationItemInputAudioTranscriptionDelta", + "RealtimeServerEventConversationItemInputAudioTranscriptionFailed", + "RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + "RealtimeServerEventConversationItemInputAudioTranscriptionSegment", + "RealtimeServerEventConversationItemRetrieved", + "RealtimeServerEventConversationItemTruncated", + "RealtimeServerEventError", + "RealtimeServerEventErrorError", + "RealtimeServerEventInputAudioBufferCleared", + "RealtimeServerEventInputAudioBufferCommitted", + "RealtimeServerEventInputAudioBufferSpeechStarted", + "RealtimeServerEventInputAudioBufferSpeechStopped", + "RealtimeServerEventInputAudioBufferTimeoutTriggered", + "RealtimeServerEventMCPListToolsCompleted", + "RealtimeServerEventMCPListToolsFailed", + "RealtimeServerEventMCPListToolsInProgress", + "RealtimeServerEventOutputAudioBufferCleared", + "RealtimeServerEventRateLimitsUpdated", + "RealtimeServerEventRateLimitsUpdatedRateLimits", + "RealtimeServerEventResponseAudioDelta", + "RealtimeServerEventResponseAudioDone", + "RealtimeServerEventResponseAudioTranscriptDelta", + "RealtimeServerEventResponseAudioTranscriptDone", + "RealtimeServerEventResponseContentPartAdded", + "RealtimeServerEventResponseContentPartAddedPart", + "RealtimeServerEventResponseContentPartDone", + "RealtimeServerEventResponseContentPartDonePart", + "RealtimeServerEventResponseCreated", + "RealtimeServerEventResponseDone", + "RealtimeServerEventResponseFunctionCallArgumentsDelta", + "RealtimeServerEventResponseFunctionCallArgumentsDone", + "RealtimeServerEventResponseMCPCallArgumentsDelta", + "RealtimeServerEventResponseMCPCallArgumentsDone", + "RealtimeServerEventResponseMCPCallCompleted", + "RealtimeServerEventResponseMCPCallFailed", + "RealtimeServerEventResponseMCPCallInProgress", + "RealtimeServerEventResponseOutputItemAdded", + "RealtimeServerEventResponseOutputItemDone", + "RealtimeServerEventResponseTextDelta", + "RealtimeServerEventResponseTextDone", + "RealtimeServerEventSessionCreated", + "RealtimeServerEventSessionUpdated", "Reasoning", "RecurrenceSchedule", "RecurrenceTrigger", @@ -845,6 +1232,7 @@ "ShellToolboxTool", "SimpleQnADataGenerationJobOptions", "SimulationSeedDataGenerationJobOptions", + "SipTelephonyTransferDestination", "SkillDetails", "SkillInlineContent", "SkillReferenceParam", @@ -856,9 +1244,39 @@ "StructuredOutputDefinition", "TaxonomyCategory", "TaxonomySubCategory", + "TeamsPhoneExtensionTelephonyBinding", + "TeamsPhoneExtensionTelephonyBindingListItem", + "TeamsTelephonyTransferDestination", "TelemetryConfig", "TelemetryEndpoint", "TelemetryEndpointAuth", + "TelephonyBinding", + "TelephonyBindingListItem", + "TelephonyCallJob", + "TelephonyCallJobCancellation", + "TelephonyCallJobSchedule", + "TelephonyCallLifecycleEvent", + "TelephonyCallRecord", + "TelephonyCallSummary", + "TelephonyCallTiming", + "TelephonyCallTrace", + "TelephonyCampaign", + "TelephonyCampaignCallJobCounts", + "TelephonyCampaignRecipientImport", + "TelephonyCampaignRecipientImportSource", + "TelephonyCampaignRecipientMapping", + "TelephonyCampaignRecipientMappingRequest", + "TelephonyCampaignSchedule", + "TelephonyOperation", + "TelephonyOperationResource", + "TelephonyOutboundDestination", + "TelephonyOutboundFixedIntervalRetryPolicy", + "TelephonyOutboundFixedIntervalRetryPolicyResponse", + "TelephonyOutboundRetryPolicy", + "TelephonyOutboundRetryPolicyResponse", + "TelephonyTransferDestination", + "TelephonyTransferTarget", + "TelephonyTransferTargets", "TextResponseFormat", "TextResponseFormatJsonObject", "TextResponseFormatJsonSchema", @@ -899,14 +1317,97 @@ "TracesDataGenerationJobOptions", "TracesDataGenerationJobSource", "TracesEvaluatorGenerationJobSource", + "TranscriptTextUsageDuration", + "TranscriptTextUsageTokens", + "TranscriptTextUsageTokensInputTokenDetails", + "TranscriptionLanguage", "Trigger", + "TwilioTelephonyBinding", + "TwilioTelephonyBindingListItem", "UpdateModelVersionRequest", + "UpdateTelephonyBindingRequest", "UpdateToolboxRequest", "UserProfileMemoryItem", "VersionIndicator", "VersionRefIndicator", "VersionSelectionRule", "VersionSelector", + "VoiceAgentAnimationConfig", + "VoiceAgentAudioConfig", + "VoiceAgentAudioInputConfig", + "VoiceAgentAudioOutputConfig", + "VoiceAgentAvatarConfig", + "VoiceAgentAvatarIceServer", + "VoiceAgentAvatarScene", + "VoiceAgentAvatarVideoBackground", + "VoiceAgentAvatarVideoCrop", + "VoiceAgentAvatarVideoParams", + "VoiceAgentAvatarVideoResolution", + "VoiceAgentAzureSemanticVadEnTurnDetection", + "VoiceAgentAzureSemanticVadMultilingualTurnDetection", + "VoiceAgentAzureSemanticVadTurnDetection", + "VoiceAgentClientEventRtcCallSdpCreate", + "VoiceAgentClientEventSessionAvatarConnect", + "VoiceAgentClientEventSessionUpdate", + "VoiceAgentDefinition", + "VoiceAgentEchoCancellation", + "VoiceAgentEndOfUtteranceDetection", + "VoiceAgentFunctionTool", + "VoiceAgentGreetingConfig", + "VoiceAgentInputTranscription", + "VoiceAgentInterimResponseConfig", + "VoiceAgentLlmGeneratedGreetingConfig", + "VoiceAgentLlmInterimResponseConfig", + "VoiceAgentMcpTool", + "VoiceAgentNoiseReduction", + "VoiceAgentRealtimeResponse", + "VoiceAgentRealtimeResponseBase", + "VoiceAgentResponseCreateParams", + "VoiceAgentRtcCallErrorDetails", + "VoiceAgentSemanticVadTurnDetection", + "VoiceAgentServerEventResponseAnimationBlendshapesDelta", + "VoiceAgentServerEventResponseAnimationBlendshapesDone", + "VoiceAgentServerEventResponseAnimationVisemeDelta", + "VoiceAgentServerEventResponseAnimationVisemeDone", + "VoiceAgentServerEventResponseAudioTimestampDelta", + "VoiceAgentServerEventResponseAudioTimestampDone", + "VoiceAgentServerEventResponseVideoDelta", + "VoiceAgentServerEventRtcCallError", + "VoiceAgentServerEventRtcCallSdpCreated", + "VoiceAgentServerEventSessionAvatarConnecting", + "VoiceAgentServerEventSessionAvatarSwitchToIdle", + "VoiceAgentServerEventSessionAvatarSwitchToSpeaking", + "VoiceAgentServerEventSessionSubagentAborted", + "VoiceAgentServerEventSessionSubagentCompleted", + "VoiceAgentServerEventSessionSubagentStarted", + "VoiceAgentServerEventWarning", + "VoiceAgentServerEventWarningDetails", + "VoiceAgentServerVadTurnDetection", + "VoiceAgentSessionAvatarConfig", + "VoiceAgentSessionResponseConfig", + "VoiceAgentSessionUpdateConfig", + "VoiceAgentStaticInterimResponseConfig", + "VoiceAgentSubagent", + "VoiceAgentSubagentConfig", + "VoiceAgentSubagentResponsePolicy", + "VoiceAgentSystemTool", + "VoiceAgentTemplateGreetingConfig", + "VoiceAgentTool", + "VoiceAgentToolboxTool", + "VoiceAgentTranscriptionPhrase", + "VoiceAgentTranscriptionWord", + "VoiceAgentTurnDetectionConfig", + "VoiceConversation", + "VoiceConversationEngine", + "VoiceGeneratedItemAudioResponse", + "VoiceHostedAgentConversationEngine", + "VoiceItemAudioResponse", + "VoiceRecordingChannelLayout", + "VoiceRecordingResponse", + "VoiceResponse", + "VoiceResponseAudio", + "VoiceResponseAudioOutput", + "VoiceResponseBase", "WebIQPreviewTool", "WebIQPreviewToolboxTool", "WebSearchApproximateLocation", @@ -947,6 +1448,7 @@ "ContainerMemoryLimit", "ContainerNetworkPolicyParamType", "ContainerSkillType", + "CreateTranscriptionResponseJsonUsageType", "CredentialType", "CustomToolParamFormatType", "DataGenerationJobOutputType", @@ -992,7 +1494,16 @@ "PageOrder", "PendingUploadType", "PublishApprovalStatus", + "RaiInvocationContentType", + "RaiInvocationMode", "RankerVersionType", + "RealtimeAudioFormatsType", + "RealtimeClientEventType", + "RealtimeConversationItemMessageType", + "RealtimeConversationItemType", + "RealtimeMcpErrorType", + "RealtimeReasoningEffort", + "RealtimeServerEventType", "ReasoningEffort", "ReasoningModeEnum", "RecurrenceType", @@ -1017,7 +1528,30 @@ "TelemetryEndpointAuthType", "TelemetryEndpointKind", "TelemetryTransportProtocol", + "TelephonyBindingStatus", + "TelephonyCallDurationBasis", + "TelephonyCallJobStatus", + "TelephonyCallLifecycleEventName", + "TelephonyCallLifecycleEventOutcome", + "TelephonyCallLifecycleEventSource", + "TelephonyCallPhase", + "TelephonyCallStatus", + "TelephonyCallTimestampSource", + "TelephonyCallTraceMode", + "TelephonyCallTraceStatus", + "TelephonyCampaignConfigurationStatus", + "TelephonyCampaignDuplicateHandling", + "TelephonyCampaignExecutionStatus", + "TelephonyCampaignRecipientImportFormat", + "TelephonyCampaignRecipientImportStatus", + "TelephonyCampaignScheduleType", + "TelephonyOperationStatus", + "TelephonyOutboundDestinationType", + "TelephonyOutboundRetryPolicyType", + "TelephonyProvider", + "TelephonyTransferDestinationKind", "TextResponseFormatConfigurationType", + "ToolChoiceOptions", "ToolChoiceParamType", "ToolSearchExecutionType", "ToolType", @@ -1026,6 +1560,30 @@ "TriggerType", "VersionIndicatorType", "VersionSelectorType", + "VoiceAgentAnimationOutputType", + "VoiceAgentAudioTimestampType", + "VoiceAgentAvatarOutputProtocol", + "VoiceAgentAvatarType", + "VoiceAgentEchoCancellationReferenceSource", + "VoiceAgentEndOfUtteranceDetectionModel", + "VoiceAgentEndOfUtteranceThresholdLevel", + "VoiceAgentInputTranscriptionModel", + "VoiceAgentInterimResponseTrigger", + "VoiceAgentNoiseReductionType", + "VoiceAgentSessionIncludeOption", + "VoiceAgentSubagentAbortReason", + "VoiceAgentSystemToolName", + "VoiceAgentToolResponseScheduling", + "VoiceAgentTransport", + "VoiceAgentTurnDetectionType", + "VoiceAgentWebSocketSubprotocol", + "VoiceAudioCodec", + "VoiceAudioContainerFormat", + "VoiceAudioRole", + "VoiceConversationStatus", + "VoiceModelType", + "VoiceOutputModality", + "VoiceType", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py index d2e0105f2403..3ac7592c3bd4 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py @@ -136,6 +136,8 @@ class AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): """MCP.""" INVOCATIONS = "invocations" """INVOCATIONS.""" + VOICE = "voice" + """VOICE.""" INVOCATIONS_WS = "invocations_ws" """WebSocket-based protocol for hosted voice and real-time streaming agents.""" @@ -222,6 +224,8 @@ class AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): """WORKFLOW.""" EXTERNAL = "external" """EXTERNAL.""" + VOICE = "voice" + """VOICE.""" class AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): @@ -480,6 +484,15 @@ class ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """INLINE.""" +class CreateTranscriptionResponseJsonUsageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of CreateTranscriptionResponseJsonUsageType.""" + + TOKENS = "tokens" + """TOKENS.""" + DURATION = "duration" + """DURATION.""" + + class CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The credential type used by the connection.""" @@ -1001,6 +1014,28 @@ class PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): tenant-scoped titles are reviewed.""" +class RaiInvocationContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """How an invocations request/response body is parsed to locate text for content-safety + moderation. + """ + + JSON = "json" + """Parse the body as JSON and evaluate the declared paths/selectors.""" + TEXT = "text" + """Treat the whole (size-capped) body as text; paths/selectors are ignored.""" + + +class RaiInvocationMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Author-declared response shape for the invocations protocol.""" + + NON_STREAMING = "non_streaming" + """Non-streaming response body.""" + STREAMING = "streaming" + """Streaming response body.""" + BOTH = "both" + """Both non-streaming and streaming response bodies.""" + + class RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of RankerVersionType.""" @@ -1010,6 +1045,235 @@ class RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """DEFAULT_2024_11_15.""" +class RealtimeAudioFormatsType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeAudioFormatsType.""" + + AUDIO_PCM = "audio/pcm" + """AUDIO_PCM.""" + AUDIO_PCMU = "audio/pcmu" + """AUDIO_PCMU.""" + AUDIO_PCMA = "audio/pcma" + """AUDIO_PCMA.""" + + +class RealtimeClientEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeClientEventType.""" + + CONVERSATION_ITEM_CREATE = "conversation.item.create" + """CONVERSATION_ITEM_CREATE.""" + CONVERSATION_ITEM_DELETE = "conversation.item.delete" + """CONVERSATION_ITEM_DELETE.""" + CONVERSATION_ITEM_RETRIEVE = "conversation.item.retrieve" + """CONVERSATION_ITEM_RETRIEVE.""" + CONVERSATION_ITEM_TRUNCATE = "conversation.item.truncate" + """CONVERSATION_ITEM_TRUNCATE.""" + INPUT_AUDIO_BUFFER_APPEND = "input_audio_buffer.append" + """INPUT_AUDIO_BUFFER_APPEND.""" + INPUT_AUDIO_BUFFER_CLEAR = "input_audio_buffer.clear" + """INPUT_AUDIO_BUFFER_CLEAR.""" + OUTPUT_AUDIO_BUFFER_CLEAR = "output_audio_buffer.clear" + """OUTPUT_AUDIO_BUFFER_CLEAR.""" + INPUT_AUDIO_BUFFER_COMMIT = "input_audio_buffer.commit" + """INPUT_AUDIO_BUFFER_COMMIT.""" + RESPONSE_CANCEL = "response.cancel" + """RESPONSE_CANCEL.""" + RESPONSE_CREATE = "response.create" + """RESPONSE_CREATE.""" + SESSION_UPDATE = "session.update" + """SESSION_UPDATE.""" + SESSION_AVATAR_CONNECT = "session.avatar.connect" + """SESSION_AVATAR_CONNECT.""" + RTC_CALL_SDP_CREATE = "rtc.call.sdp.create" + """RTC_CALL_SDP_CREATE.""" + + +class RealtimeConversationItemMessageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeConversationItemMessageType.""" + + SYSTEM = "system" + """SYSTEM.""" + USER = "user" + """USER.""" + ASSISTANT = "assistant" + """ASSISTANT.""" + + +class RealtimeConversationItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeConversationItemType.""" + + FUNCTION_CALL = "function_call" + """FUNCTION_CALL.""" + FUNCTION_CALL_OUTPUT = "function_call_output" + """FUNCTION_CALL_OUTPUT.""" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + """MCP_APPROVAL_RESPONSE.""" + MCP_LIST_TOOLS = "mcp_list_tools" + """MCP_LIST_TOOLS.""" + MCP_CALL = "mcp_call" + """MCP_CALL.""" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + """MCP_APPROVAL_REQUEST.""" + MESSAGE = "message" + """MESSAGE.""" + + +class RealtimeMcpErrorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeMcpErrorType.""" + + PROTOCOL_ERROR = "protocol_error" + """PROTOCOL_ERROR.""" + TOOL_EXECUTION_ERROR = "tool_execution_error" + """TOOL_EXECUTION_ERROR.""" + HTTP_ERROR = "http_error" + """HTTP_ERROR.""" + + +class RealtimeReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Constrains effort on reasoning for reasoning-capable Realtime models such as + ``gpt-realtime-2``. + """ + + MINIMAL = "minimal" + """MINIMAL.""" + LOW = "low" + """LOW.""" + MEDIUM = "medium" + """MEDIUM.""" + HIGH = "high" + """HIGH.""" + XHIGH = "xhigh" + """XHIGH.""" + + +class RealtimeServerEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeServerEventType.""" + + CONVERSATION_CREATED = "conversation.created" + """CONVERSATION_CREATED.""" + CONVERSATION_ITEM_CREATED = "conversation.item.created" + """CONVERSATION_ITEM_CREATED.""" + CONVERSATION_ITEM_DELETED = "conversation.item.deleted" + """CONVERSATION_ITEM_DELETED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED = "conversation.item.input_audio_transcription.completed" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA = "conversation.item.input_audio_transcription.delta" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED = "conversation.item.input_audio_transcription.failed" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED.""" + CONVERSATION_ITEM_RETRIEVED = "conversation.item.retrieved" + """CONVERSATION_ITEM_RETRIEVED.""" + CONVERSATION_ITEM_TRUNCATED = "conversation.item.truncated" + """CONVERSATION_ITEM_TRUNCATED.""" + ERROR = "error" + """ERROR.""" + INPUT_AUDIO_BUFFER_CLEARED = "input_audio_buffer.cleared" + """INPUT_AUDIO_BUFFER_CLEARED.""" + INPUT_AUDIO_BUFFER_COMMITTED = "input_audio_buffer.committed" + """INPUT_AUDIO_BUFFER_COMMITTED.""" + INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED = "input_audio_buffer.dtmf_event_received" + """INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED.""" + INPUT_AUDIO_BUFFER_SPEECH_STARTED = "input_audio_buffer.speech_started" + """INPUT_AUDIO_BUFFER_SPEECH_STARTED.""" + INPUT_AUDIO_BUFFER_SPEECH_STOPPED = "input_audio_buffer.speech_stopped" + """INPUT_AUDIO_BUFFER_SPEECH_STOPPED.""" + RATE_LIMITS_UPDATED = "rate_limits.updated" + """RATE_LIMITS_UPDATED.""" + RESPONSE_OUTPUT_AUDIO_DELTA = "response.output_audio.delta" + """RESPONSE_OUTPUT_AUDIO_DELTA.""" + RESPONSE_OUTPUT_AUDIO_DONE = "response.output_audio.done" + """RESPONSE_OUTPUT_AUDIO_DONE.""" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA = "response.output_audio_transcript.delta" + """RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA.""" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE = "response.output_audio_transcript.done" + """RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE.""" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + """RESPONSE_CONTENT_PART_ADDED.""" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + """RESPONSE_CONTENT_PART_DONE.""" + RESPONSE_CREATED = "response.created" + """RESPONSE_CREATED.""" + RESPONSE_DONE = "response.done" + """RESPONSE_DONE.""" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + """RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA.""" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + """RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE.""" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + """RESPONSE_OUTPUT_ITEM_ADDED.""" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + """RESPONSE_OUTPUT_ITEM_DONE.""" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + """RESPONSE_OUTPUT_TEXT_DELTA.""" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + """RESPONSE_OUTPUT_TEXT_DONE.""" + SESSION_CREATED = "session.created" + """SESSION_CREATED.""" + SESSION_UPDATED = "session.updated" + """SESSION_UPDATED.""" + OUTPUT_AUDIO_BUFFER_STARTED = "output_audio_buffer.started" + """OUTPUT_AUDIO_BUFFER_STARTED.""" + OUTPUT_AUDIO_BUFFER_STOPPED = "output_audio_buffer.stopped" + """OUTPUT_AUDIO_BUFFER_STOPPED.""" + OUTPUT_AUDIO_BUFFER_CLEARED = "output_audio_buffer.cleared" + """OUTPUT_AUDIO_BUFFER_CLEARED.""" + CONVERSATION_ITEM_ADDED = "conversation.item.added" + """CONVERSATION_ITEM_ADDED.""" + CONVERSATION_ITEM_DONE = "conversation.item.done" + """CONVERSATION_ITEM_DONE.""" + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED = "input_audio_buffer.timeout_triggered" + """INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT = "conversation.item.input_audio_transcription.segment" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT.""" + MCP_LIST_TOOLS_IN_PROGRESS = "mcp_list_tools.in_progress" + """MCP_LIST_TOOLS_IN_PROGRESS.""" + MCP_LIST_TOOLS_COMPLETED = "mcp_list_tools.completed" + """MCP_LIST_TOOLS_COMPLETED.""" + MCP_LIST_TOOLS_FAILED = "mcp_list_tools.failed" + """MCP_LIST_TOOLS_FAILED.""" + RESPONSE_MCP_CALL_ARGUMENTS_DELTA = "response.mcp_call_arguments.delta" + """RESPONSE_MCP_CALL_ARGUMENTS_DELTA.""" + RESPONSE_MCP_CALL_ARGUMENTS_DONE = "response.mcp_call_arguments.done" + """RESPONSE_MCP_CALL_ARGUMENTS_DONE.""" + RESPONSE_MCP_CALL_IN_PROGRESS = "response.mcp_call.in_progress" + """RESPONSE_MCP_CALL_IN_PROGRESS.""" + RESPONSE_MCP_CALL_COMPLETED = "response.mcp_call.completed" + """RESPONSE_MCP_CALL_COMPLETED.""" + RESPONSE_MCP_CALL_FAILED = "response.mcp_call.failed" + """RESPONSE_MCP_CALL_FAILED.""" + WARNING = "warning" + """WARNING.""" + SESSION_SUBAGENT_STARTED = "session.subagent.started" + """SESSION_SUBAGENT_STARTED.""" + SESSION_SUBAGENT_COMPLETED = "session.subagent.completed" + """SESSION_SUBAGENT_COMPLETED.""" + SESSION_SUBAGENT_ABORTED = "session.subagent.aborted" + """SESSION_SUBAGENT_ABORTED.""" + SESSION_AVATAR_CONNECTING = "session.avatar.connecting" + """SESSION_AVATAR_CONNECTING.""" + SESSION_AVATAR_SWITCH_TO_SPEAKING = "session.avatar.switch_to_speaking" + """SESSION_AVATAR_SWITCH_TO_SPEAKING.""" + SESSION_AVATAR_SWITCH_TO_IDLE = "session.avatar.switch_to_idle" + """SESSION_AVATAR_SWITCH_TO_IDLE.""" + RTC_CALL_SDP_CREATED = "rtc.call.sdp.created" + """RTC_CALL_SDP_CREATED.""" + RTC_CALL_ERROR = "rtc.call.error" + """RTC_CALL_ERROR.""" + RESPONSE_AUDIO_TIMESTAMP_DELTA = "response.audio_timestamp.delta" + """RESPONSE_AUDIO_TIMESTAMP_DELTA.""" + RESPONSE_AUDIO_TIMESTAMP_DONE = "response.audio_timestamp.done" + """RESPONSE_AUDIO_TIMESTAMP_DONE.""" + RESPONSE_ANIMATION_BLENDSHAPES_DELTA = "response.animation_blendshapes.delta" + """RESPONSE_ANIMATION_BLENDSHAPES_DELTA.""" + RESPONSE_ANIMATION_BLENDSHAPES_DONE = "response.animation_blendshapes.done" + """RESPONSE_ANIMATION_BLENDSHAPES_DONE.""" + RESPONSE_ANIMATION_VISEME_DELTA = "response.animation_viseme.delta" + """RESPONSE_ANIMATION_VISEME_DELTA.""" + RESPONSE_ANIMATION_VISEME_DONE = "response.animation_viseme.done" + """RESPONSE_ANIMATION_VISEME_DONE.""" + RESPONSE_VIDEO_DELTA = "response.video.delta" + """RESPONSE_VIDEO_DELTA.""" + + class ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Constrains effort on reasoning for reasoning models. Currently supported values are ``none``, ``minimal``, ``low``, ``medium``, ``high``, ``xhigh``, and ``max``. Reducing reasoning effort @@ -1307,6 +1571,324 @@ class TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): """gRPC transport protocol.""" +class TelephonyBindingStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a telephony binding.""" + + ACTIVE = "active" + """The binding accepts new inbound calls.""" + SUSPENDED = "suspended" + """The binding remains configured but rejects new inbound calls.""" + + +class TelephonyCallDurationBasis(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The timestamp used as the basis for call duration.""" + + ANSWERED = "answered" + """Duration starts when the provider reports the call as answered.""" + RECEIVED = "received" + """Duration starts when the inbound webhook is received because no answered timestamp is + available.""" + + +class TelephonyCallJobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a durable outbound call job.""" + + ACCEPTED = "accepted" + """ACCEPTED.""" + WAITING_FOR_SCHEDULE = "waiting_for_schedule" + """WAITING_FOR_SCHEDULE.""" + QUEUED = "queued" + """QUEUED.""" + DISPATCHING = "dispatching" + """DISPATCHING.""" + IN_PROGRESS = "in_progress" + """IN_PROGRESS.""" + WAITING_FOR_RETRY = "waiting_for_retry" + """WAITING_FOR_RETRY.""" + CANCELLATION_REQUESTED = "cancellation_requested" + """CANCELLATION_REQUESTED.""" + COMPLETED = "completed" + """COMPLETED.""" + BLOCKED = "blocked" + """BLOCKED.""" + EXPIRED = "expired" + """EXPIRED.""" + FAILED = "failed" + """FAILED.""" + CANCELLED = "cancelled" + """CANCELLED.""" + + +class TelephonyCallLifecycleEventName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A provider-neutral lifecycle event name. Known values are stable; additional values may be + added over time. + """ + + WEBHOOK_RECEIVED = "telephony.webhook.received" + """The provider webhook was received.""" + WEBHOOK_VALIDATION = "telephony.webhook.validation" + """The provider webhook was validated.""" + BINDING_RESOLVE = "telephony.binding.resolve" + """The service attempted to resolve the agent binding.""" + PROVIDER_ANSWER = "telephony.provider.answer" + """The service requested or observed provider answer state.""" + MEDIA_CONNECT = "telephony.media.connect" + """The provider media channel changed connection state.""" + AGENT_SESSION_CONNECT = "telephony.agent_session.connect" + """The voice-agent session changed connection state.""" + FIRST_CALLER_AUDIO = "telephony.media.first_caller_audio" + """The first caller audio was observed.""" + FIRST_AGENT_AUDIO = "telephony.media.first_agent_audio" + """The first agent audio was observed.""" + CALL_TRANSFER = "telephony.call.transfer" + """A call transfer changed state.""" + CALL_HANGUP = "telephony.call.hangup" + """A call hang-up changed state.""" + CALL_DISCONNECT = "telephony.call.disconnect" + """The call disconnected.""" + + +class TelephonyCallLifecycleEventOutcome(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The outcome of one telephony lifecycle observation.""" + + OBSERVED = "observed" + """The event was observed without a success or failure result.""" + STARTED = "started" + """The operation started.""" + SUCCEEDED = "succeeded" + """The operation succeeded.""" + FAILED = "failed" + """The operation failed.""" + REJECTED = "rejected" + """The operation or call was rejected.""" + CANCELLED = "cancelled" + """The operation was cancelled.""" + + +class TelephonyCallLifecycleEventSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The component that supplied a telephony lifecycle observation.""" + + GATEWAY = "gateway" + """The Foundry telephony gateway supplied the observation.""" + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + """Microsoft Teams Phone Extension supplied the observation.""" + TWILIO = "twilio" + """Twilio supplied the observation.""" + VOICE_AGENT = "voice_agent" + """The voice-agent runtime supplied the observation.""" + + +class TelephonyCallPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The provider-neutral phase reached by an inbound telephony call.""" + + RECEIVED = "received" + """The provider webhook was received.""" + VALIDATED = "validated" + """The provider webhook was validated.""" + ADMITTED = "admitted" + """The call was admitted to a configured agent binding.""" + ANSWERING = "answering" + """The provider was asked to answer the call.""" + ANSWERED = "answered" + """The provider reported that the call was answered.""" + MEDIA_CONNECTED = "media_connected" + """The provider media channel was connected.""" + AGENT_SESSION_READY = "agent_session_ready" + """The voice-agent session was ready.""" + BRIDGING = "bridging" + """Media was actively bridged between the caller and the voice agent.""" + MANAGING = "managing" + """A mid-call management command was in progress.""" + COMPLETED = "completed" + """The call completed.""" + REJECTED = "rejected" + """The call was rejected before admission or answer.""" + FAILED = "failed" + """The call failed.""" + + +class TelephonyCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of an inbound telephony call.""" + + IN_PROGRESS = "in_progress" + """The call has started and has not reached a terminal state.""" + SUCCESS = "success" + """The call ended successfully.""" + FAILED = "failed" + """The call ended because of a provider or management failure.""" + + +class TelephonyCallTimestampSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The source of a telephony lifecycle timestamp.""" + + PROVIDER = "provider" + """The telephony provider supplied the timestamp.""" + GATEWAY = "gateway" + """The Foundry telephony gateway observed the event.""" + DERIVED = "derived" + """The service derived the timestamp from another observation.""" + + +class TelephonyCallTraceMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The mode used to expose a telephony call as a customer-facing Foundry trace.""" + + LIVE = "live" + """The trace was created while the voice-agent conversation was live.""" + POST_CALL = "post_call" + """The trace summarizes a validated, customer-owned call that ended before a live voice-agent + conversation was created.""" + + +class TelephonyCallTraceStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The availability status of a customer-facing telephony call trace.""" + + PENDING = "pending" + """Trace creation has not completed.""" + EMITTING = "emitting" + """Trace creation is in progress.""" + AVAILABLE = "available" + """The trace is available.""" + NOT_RECORDED = "not_recorded" + """Tracing was disabled or no trace listener recorded the call.""" + NOT_APPLICABLE = "not_applicable" + """The call was not eligible for a customer-facing trace.""" + FAILED = "failed" + """Trace creation failed.""" + + +class TelephonyCampaignConfigurationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The immutable-configuration lifecycle status of an outbound campaign.""" + + DRAFT = "draft" + """DRAFT.""" + IMPORTING = "importing" + """IMPORTING.""" + VALIDATING = "validating" + """VALIDATING.""" + PUBLISHING = "publishing" + """PUBLISHING.""" + PUBLISHED = "published" + """PUBLISHED.""" + PUBLISH_FAILED = "publish_failed" + """PUBLISH_FAILED.""" + + +class TelephonyCampaignDuplicateHandling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """How duplicate recipient keys in an import are handled.""" + + REJECT = "reject" + """Reject duplicate recipient keys.""" + KEEP_EACH = "keep_each" + """Keep each recipient entry, distinguishing duplicates by recipient item key.""" + MERGE = "merge" + """Merge entries with the same recipient key.""" + + +class TelephonyCampaignExecutionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The execution lifecycle status of a published outbound campaign.""" + + NONE = "none" + """NONE.""" + SCHEDULED = "scheduled" + """SCHEDULED.""" + RUNNING = "running" + """RUNNING.""" + PAUSED = "paused" + """PAUSED.""" + COMPLETED = "completed" + """COMPLETED.""" + FAILED = "failed" + """FAILED.""" + CANCELLED = "cancelled" + """CANCELLED.""" + + +class TelephonyCampaignRecipientImportFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A supported Dataset recipient file format.""" + + CSV = "csv" + """A comma-separated values file.""" + JSON = "json" + """A JSON file containing an array of recipient objects.""" + JSONL = "jsonl" + """A JSON Lines file containing one recipient object per line.""" + + +class TelephonyCampaignRecipientImportStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a campaign recipient import.""" + + RUNNING = "running" + """RUNNING.""" + SUCCEEDED = "succeeded" + """SUCCEEDED.""" + FAILED = "failed" + """FAILED.""" + + +class TelephonyCampaignScheduleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """When a published outbound campaign becomes eligible to dispatch calls.""" + + IMMEDIATE = "immediate" + """Calls are eligible immediately after publication.""" + SCHEDULED = "scheduled" + """Calls are eligible at the scheduled start instant.""" + + +class TelephonyOperationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of an outbound telephony operation.""" + + NOT_STARTED = "not_started" + """NOT_STARTED.""" + RUNNING = "running" + """RUNNING.""" + SUCCEEDED = "succeeded" + """SUCCEEDED.""" + FAILED = "failed" + """FAILED.""" + CANCELLED = "cancelled" + """CANCELLED.""" + UNKNOWN_STATUS = "unknown" + """UNKNOWN_STATUS.""" + + +class TelephonyOutboundDestinationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The type of destination for an outbound call.""" + + PHONE_NUMBER = "phone_number" + """An E.164 phone number.""" + + +class TelephonyOutboundRetryPolicyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The retry strategy for an outbound call.""" + + FIXED_INTERVAL = "fixed_interval" + """Retry after a fixed interval between attempts.""" + + +class TelephonyProvider(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A telephony provider supported by an agent binding. Known values are stable; additional values + may be added over time. + """ + + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + """Microsoft Teams Phone Extension.""" + TWILIO = "twilio" + """Twilio Programmable Voice.""" + + +class TelephonyTransferDestinationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The kind of telephony transfer destination. Known values are stable; additional values may be + added over time. + """ + + PSTN = "pstn" + """A public switched telephone network destination.""" + TEAMS = "teams" + """A Microsoft Teams user or resource-account destination.""" + SIP = "sip" + """A Session Initiation Protocol destination.""" + + class TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of TextResponseFormatConfigurationType.""" @@ -1355,6 +1937,17 @@ class ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """WEB_IQ_PREVIEW.""" +class ToolChoiceOptions(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Tool choice mode.""" + + NONE = "none" + """NONE.""" + AUTO = "auto" + """AUTO.""" + REQUIRED = "required" + """REQUIRED.""" + + class ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of ToolChoiceParamType.""" @@ -1506,3 +2099,295 @@ class VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): FIXED_RATIO = "FixedRatio" """FIXED_RATIO.""" + + +class VoiceAgentAnimationOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An animation output produced by a voice-agent session.""" + + BLENDSHAPES = "blendshapes" + """BLENDSHAPES.""" + VISEME_ID = "viseme_id" + """VISEME_ID.""" + + +class VoiceAgentAudioTimestampType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An output-audio timestamp kind supported by a voice agent.""" + + WORD = "word" + """Word-level timestamps.""" + + +class VoiceAgentAvatarOutputProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The transport used to deliver the avatar video stream.""" + + WEBRTC = "webrtc" + """WEBRTC.""" + WEBSOCKET = "websocket" + """WEBSOCKET.""" + + +class VoiceAgentAvatarType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The avatar type.""" + + VIDEO_AVATAR = "video_avatar" + """VIDEO_AVATAR.""" + PHOTO_AVATAR = "photo_avatar" + """PHOTO_AVATAR.""" + + +class VoiceAgentEchoCancellationReferenceSource( # pylint: disable=name-too-long + str, Enum, metaclass=CaseInsensitiveEnumMeta +): + """The source of reference audio used for echo cancellation.""" + + SERVER = "server" + """SERVER.""" + CLIENT = "client" + """CLIENT.""" + + +class VoiceAgentEndOfUtteranceDetectionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The semantic end-of-utterance detection model.""" + + SEMANTIC_DETECTION_V1 = "semantic_detection_v1" + """The default semantic detection model.""" + SEMANTIC_DETECTION_V1_EN = "semantic_detection_v1_en" + """The English-optimized semantic detection model.""" + SEMANTIC_DETECTION_V1_MULTILINGUAL = "semantic_detection_v1_multilingual" + """The multilingual semantic detection model.""" + SMART_END_OF_TURN_DETECTION = "smart_end_of_turn_detection" + """The smart end-of-turn detection model.""" + + +class VoiceAgentEndOfUtteranceThresholdLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The sensitivity threshold for semantic end-of-utterance detection.""" + + LOW = "low" + """The low sensitivity threshold.""" + MEDIUM = "medium" + """The medium sensitivity threshold.""" + HIGH = "high" + """The high sensitivity threshold.""" + DEFAULT = "default" + """The service-selected sensitivity threshold.""" + + +class VoiceAgentInputTranscriptionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The input-audio transcription model identifier. This is a model name, not a Foundry deployment + name. Mirrors the transcription models supported by the managed voice backend, covering the + OpenAI Realtime transcription models plus the Azure and MAI models. Additional values may be + added over time. + """ + + WHISPER1 = "whisper-1" + """OpenAI Whisper.""" + GPT_REALTIME_WHISPER = "gpt-realtime-whisper" + """OpenAI GPT Realtime Whisper.""" + GPT4_O_TRANSCRIBE = "gpt-4o-transcribe" + """OpenAI GPT-4o transcribe.""" + GPT4_O_MINI_TRANSCRIBE = "gpt-4o-mini-transcribe" + """OpenAI GPT-4o mini transcribe.""" + GPT4_O_TRANSCRIBE_DIARIZE = "gpt-4o-transcribe-diarize" + """OpenAI GPT-4o transcribe with speaker diarization.""" + GPT_TRANSCRIBE = "gpt-transcribe" + """OpenAI GPT Transcribe.""" + GPT_LIVE_TRANSCRIBE = "gpt-live-transcribe" + """OpenAI GPT Live Transcribe.""" + MAI_TRANSCRIBE = "mai-transcribe" + """MAI transcription.""" + AZURE_SPEECH = "azure-speech" + """Azure AI Speech to text.""" + + +class VoiceAgentInterimResponseTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A condition that may trigger an interim response.""" + + LATENCY = "latency" + """LATENCY.""" + TOOL = "tool" + """TOOL.""" + + +class VoiceAgentNoiseReductionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The input audio noise reduction mode.""" + + NEAR_FIELD = "near_field" + """NEAR_FIELD.""" + FAR_FIELD = "far_field" + """FAR_FIELD.""" + AZURE_DEEP_NOISE_SUPPRESSION = "azure_deep_noise_suppression" + """Azure deep noise suppression.""" + + +class VoiceAgentSessionIncludeOption(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Additional fields that a voice-agent session may include in service outputs.""" + + INPUT_AUDIO_TRANSCRIPTION_LOGPROBS = "item.input_audio_transcription.logprobs" + """INPUT_AUDIO_TRANSCRIPTION_LOGPROBS.""" + INPUT_AUDIO_TRANSCRIPTION_PHRASES = "item.input_audio_transcription.phrases" + """INPUT_AUDIO_TRANSCRIPTION_PHRASES.""" + FILE_SEARCH_CALL_RESULTS = "file_search_call.results" + """FILE_SEARCH_CALL_RESULTS.""" + + +class VoiceAgentSubagentAbortReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The reason a subagent consultation was aborted.""" + + UNKNOWN_TARGET = "unknown_target" + """The requested subagent was not configured for the voice agent.""" + TIMEOUT = "timeout" + """The subagent invocation exceeded its configured timeout.""" + CANCELLED = "cancelled" + """The consultation was cancelled because the voice session ended.""" + STOPPED_BY_USER = "stopped_by_user" + """The consultation was stopped at the user's request.""" + SUPERSEDED = "superseded" + """The consultation was replaced by a newer request.""" + FAILED = "failed" + """The consultation failed.""" + + +class VoiceAgentSystemToolName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A service-managed voice-session control action. Known values are stable; additional values may + be added over time. + """ + + END_CONVERSATION = "end_conversation" + """Ends the active conversation.""" + + +class VoiceAgentToolResponseScheduling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """When a tool invocation creates a follow-up response. Additional values may be added over time.""" + + SILENT = "silent" + """Do not create a follow-up response after the service-executed tool invocation completes.""" + WHEN_IDLE = "when_idle" + """Create a follow-up response when the conversation is idle.""" + INTERRUPT = "interrupt" + """Interrupt the active response and create a follow-up response.""" + SKIP_IF_BUSY = "skip_if_busy" + """Create a follow-up response only when no response is active.""" + + +class VoiceAgentTransport(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The transport used for a voice-agent connection.""" + + WEBSOCKET = "websocket" + """Signaling and audio are exchanged as JSON events over the WebSocket. This is the default.""" + WEBRTC = "webrtc" + """WebRTC: the WebSocket carries only SDP signaling; media and the data channel are peer-to-peer.""" + + +class VoiceAgentTurnDetectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The turn-detection strategy. Additional values may be added over time.""" + + SERVER_VAD = "server_vad" + """Server-side voice activity detection.""" + SEMANTIC_VAD = "semantic_vad" + """Semantic voice activity detection.""" + AZURE_SEMANTIC_VAD = "azure_semantic_vad" + """Azure semantic voice activity detection.""" + AZURE_SEMANTIC_VAD_EN = "azure_semantic_vad_en" + """English-optimized Azure semantic voice activity detection.""" + AZURE_SEMANTIC_VAD_MULTILINGUAL = "azure_semantic_vad_multilingual" + """Multilingual Azure semantic voice activity detection.""" + + +class VoiceAgentWebSocketSubprotocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The WebSocket subprotocol supported by a voice-agent connection.""" + + REALTIME = "realtime" + """REALTIME.""" + + +class VoiceAudioCodec(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An audio codec. Additional values may be added over time.""" + + PCM16 = "pcm16" + """16-bit pulse-code modulation.""" + PCMU = "pcmu" + """G.711 mu-law.""" + PCMA = "pcma" + """G.711 A-law.""" + + +class VoiceAudioContainerFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An audio container format. Additional values may be added over time.""" + + WAV = "wav" + """Waveform Audio File Format.""" + + +class VoiceAudioRole(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A voice-audio participant role. Additional values may be added over time.""" + + USER = "user" + """Audio produced by the user.""" + AGENT = "agent" + """Audio produced by the agent.""" + + +class VoiceConversationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a persisted voice conversation: + + * `in_progress`: the live session is active, or post-session persistence finalization is + pending. + * `completed`: finalization succeeded after normal or client close, `end_conversation`, a + max-duration `1001` + close, or a client or network disconnect that the service can still finalize. + * `failed`: a terminal service, bridge, storage, or unrecoverable transport failure prevented + finalization. + """ + + IN_PROGRESS = "in_progress" + """The live session is active, or post-session persistence finalization is still pending.""" + COMPLETED = "completed" + """Persistence finalization succeeded. This includes normal or client-initiated close, the + ``end_conversation`` system tool, a max-duration ``1001`` close, and client or network + disconnects that the service can still finalize.""" + FAILED = "failed" + """A terminal service, bridge, storage, or unrecoverable transport failure prevented persistence + finalization.""" + + +class VoiceModelType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """How the model backing a voice agent is served. This is independent of the architecture + (realtime or cascaded), which the service derives from the selected model. + """ + + MANAGED = "managed" + """The service hosts and manages the named model, for example ``gpt-realtime``.""" + SELF_DEPLOYED = "self_deployed" + """The service uses the customer's own Foundry deployment named by ``model``.""" + + +class VoiceOutputModality(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An output modality the agent may produce. ``animation`` and ``avatar`` are used when an avatar + is configured. + """ + + TEXT = "text" + """TEXT.""" + AUDIO = "audio" + """AUDIO.""" + ANIMATION = "animation" + """ANIMATION.""" + AVATAR = "avatar" + """AVATAR.""" + + +class VoiceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The voice implementation. Additional values may be added over time.""" + + OPENAI = "openai" + """An OpenAI voice.""" + AZURE_STANDARD = "azure-standard" + """An Azure standard voice.""" + AZURE_CUSTOM = "azure-custom" + """An Azure custom voice.""" + AZURE_PERSONAL = "azure-personal" + """An Azure personal voice.""" + AVATAR_VOICE_SYNC = "avatar-voice-sync" + """A voice synchronized with an avatar.""" + AZURE_REALTIME_NATIVE = "azure-realtime-native" + """An Azure native realtime voice.""" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py index 53167fbac63d..aa536dbc4f30 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py @@ -21,6 +21,7 @@ AgentOptimizationDatasetInputType, ContainerNetworkPolicyParamType, ContainerSkillType, + CreateTranscriptionResponseJsonUsageType, CredentialType, CustomToolParamFormatType, DataGenerationJobOutputType, @@ -40,6 +41,12 @@ MemoryStoreObjectType, OpenApiAuthType, PendingUploadType, + RealtimeAudioFormatsType, + RealtimeClientEventType, + RealtimeConversationItemMessageType, + RealtimeConversationItemType, + RealtimeMcpErrorType, + RealtimeServerEventType, RecurrenceType, RoutineActionType, RoutineDispatchPayloadType, @@ -48,6 +55,9 @@ ScheduleTaskType, TelemetryEndpointAuthType, TelemetryEndpointKind, + TelephonyOutboundRetryPolicyType, + TelephonyProvider, + TelephonyTransferDestinationKind, TextResponseFormatConfigurationType, ToolChoiceParamType, ToolType, @@ -55,6 +65,7 @@ TriggerType, VersionIndicatorType, VersionSelectorType, + VoiceAgentTurnDetectionType, ) if TYPE_CHECKING: @@ -939,9 +950,11 @@ class AgentDefinition(_Model): # pylint: disable=docstring-keyword-should-match """AgentDefinition. You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ExternalAgentDefinition, HostedAgentDefinition, PromptAgentDefinition, WorkflowAgentDefinition + ExternalAgentDefinition, HostedAgentDefinition, PromptAgentDefinition, VoiceAgentDefinition, + WorkflowAgentDefinition - :ivar kind: Required. Known values are: "prompt", "hosted", "workflow", and "external". + :ivar kind: Required. Known values are: "prompt", "hosted", "workflow", "external", and + "voice". :vartype kind: str or ~azure.ai.projects.models.AgentKind :ivar rai_config: Configuration for Responsible AI (RAI) content filtering and safety features. :vartype rai_config: ~azure.ai.projects.models.RaiConfig @@ -949,7 +962,7 @@ class AgentDefinition(_Model): # pylint: disable=docstring-keyword-should-match __mapping__: dict[str, _Model] = {} kind: str = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"prompt\", \"hosted\", \"workflow\", and \"external\".""" + """Required. Known values are: \"prompt\", \"hosted\", \"workflow\", \"external\", and \"voice\".""" rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Configuration for Responsible AI (RAI) content filtering and safety features.""" @@ -6106,6 +6119,290 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class CreateTelephonyBindingRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to create a telephony binding. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + CreateTeamsPhoneExtensionTelephonyBindingRequest, CreateTwilioTelephonyBindingRequest + + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: An optional display label for the binding. + :vartype label: str + """ + + __mapping__: dict[str, _Model] = {} + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional display label for the binding.""" + + @overload + def __init__( + self, + *, + provider: str, + connection: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTeamsPhoneExtensionTelephonyBindingRequest( + CreateTelephonyBindingRequest, discriminator="teams_phone_extension" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The request to create a Microsoft Teams Phone Extension binding. + + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: An optional display label for the binding. + :vartype label: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + connection: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class CreateTelephonyCallJobRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A request to create one durable direct outbound call job. + + :ivar destination: The phone destination to call. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyOutboundDestination + :ivar telephony_binding_id: The active agent telephony binding used to originate the call. + Required. + :vartype telephony_binding_id: str + :ivar purpose: An optional customer-declared purpose for placing the call. + :vartype purpose: str + :ivar structured_inputs: Structured input values available to the agent and greeting for this + call. Agent-declared inputs are validated against their schemas; omitted optional inputs may + use their Agent-defined default values, while omitted required inputs are rejected. Additional + inputs remain available as dynamic template variables. + :vartype structured_inputs: dict[str, any] + :ivar schedule: The optional execution window. + :vartype schedule: ~azure.ai.projects.models.TelephonyCallJobSchedule + :ivar retry_policy: The provider-attempt retry policy. Omit it for one attempt with no retry + delay. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicy + """ + + destination: "_models.TelephonyOutboundDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The phone destination to call. Required.""" + telephony_binding_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The active agent telephony binding used to originate the call. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for placing the call.""" + structured_inputs: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Structured input values available to the agent and greeting for this call. Agent-declared + inputs are validated against their schemas; omitted optional inputs may use their Agent-defined + default values, while omitted required inputs are rejected. Additional inputs remain available + as dynamic template variables.""" + schedule: Optional["_models.TelephonyCallJobSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The optional execution window.""" + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-attempt retry policy. Omit it for one attempt with no retry delay.""" + + @overload + def __init__( + self, + *, + destination: "_models.TelephonyOutboundDestination", + telephony_binding_id: str, + purpose: Optional[str] = None, + structured_inputs: Optional[dict[str, Any]] = None, + schedule: Optional["_models.TelephonyCallJobSchedule"] = None, + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTelephonyCampaignRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A request to create a draft outbound campaign. + + :ivar display_name: A customer-visible name for the campaign. Required. + :vartype display_name: str + :ivar telephony_binding_id: The active agent telephony binding used to originate campaign + calls. Required. + :vartype telephony_binding_id: str + :ivar purpose: An optional customer-declared purpose for campaign calls. + :vartype purpose: str + :ivar schedule: When the published campaign becomes eligible to dispatch calls. + :vartype schedule: ~azure.ai.projects.models.TelephonyCampaignSchedule + :ivar retry_policy: The provider-attempt retry policy inherited by every materialized call job. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicy + """ + + display_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A customer-visible name for the campaign. Required.""" + telephony_binding_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The active agent telephony binding used to originate campaign calls. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for campaign calls.""" + schedule: Optional["_models.TelephonyCampaignSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the published campaign becomes eligible to dispatch calls.""" + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-attempt retry policy inherited by every materialized call job.""" + + @overload + def __init__( + self, + *, + display_name: str, + telephony_binding_id: str, + purpose: Optional[str] = None, + schedule: Optional["_models.TelephonyCampaignSchedule"] = None, + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTranscriptionResponseJsonUsage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Token usage statistics for the request. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TranscriptTextUsageDuration, TranscriptTextUsageTokens + + :ivar type: Required. Known values are: "tokens" and "duration". + :vartype type: str or ~azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"tokens\" and \"duration\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTwilioTelephonyBindingRequest( + CreateTelephonyBindingRequest, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to create a Twilio binding. + + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: An optional display label for the binding. + :vartype label: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + connection: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + class Trigger(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Base model for Trigger of the schedule. @@ -9753,6 +10050,99 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.type: Literal["function"] = "function" +class GenerateVoiceAgentRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The inputs for generating a voice agent. Only ``kind`` and ``name`` are always required. The + authoring service expands these inputs into a full, editable ``VoiceAgentDefinition``, which is + then created through ``POST /agents``. The generated ``instructions`` and audio/voice settings + are stored as separate fields on the resulting agent definition, so the caller can edit or + override any of them afterward via standard agent versioning. + + :ivar kind: The agent kind. Always ``voice``. Required. VOICE. + :vartype kind: str or ~azure.ai.projects.models.VOICE + :ivar name: The unique name for the agent to create. Must be a non-empty DNS-like agent name. + Required. + :vartype name: str + :ivar model_type: Optional inference mode. When omitted, the authoring service uses + ``managed``. When supplied, use ``managed`` or ``self_deployed``. Known values are: "managed" + and "self_deployed". + :vartype model_type: str or ~azure.ai.projects.models.VoiceModelType + :ivar model: Optional model identifier. Required when ``model_type`` is ``self_deployed``; + optional when ``model_type`` is ``managed`` or omitted. The service never invents a customer + deployment name. + :vartype model: str + :ivar use_case: An optional authoring use case. An empty string is accepted. + :vartype use_case: str + :ivar goal: An optional natural-language description of what the agent should do. When + supplied, it seeds the generated instructions. + :vartype goal: str + :ivar description: An optional agent description. The authoring service resolves its fallback + when omitted. + :vartype description: str + :ivar tools: Optional tools carried through verbatim onto the generated agent (see + ``VoiceAgentTool``). + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar draft: (Preview) When ``true``, the generated voice agent is created as a draft — an + editable, unpublished version the caller can review and refine before publishing it via the + standard create/version path. The service defaults to ``false`` if a value is not specified by + the caller, in which case the agent is created and published normally. + :vartype draft: bool + """ + + kind: Literal[AgentKind.VOICE] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent kind. Always ``voice``. Required. VOICE.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique name for the agent to create. Must be a non-empty DNS-like agent name. Required.""" + model_type: Optional[Union[str, "_models.VoiceModelType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional inference mode. When omitted, the authoring service uses ``managed``. When supplied, + use ``managed`` or ``self_deployed``. Known values are: \"managed\" and \"self_deployed\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional model identifier. Required when ``model_type`` is ``self_deployed``; optional when + ``model_type`` is ``managed`` or omitted. The service never invents a customer deployment name.""" + use_case: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional authoring use case. An empty string is accepted.""" + goal: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional natural-language description of what the agent should do. When supplied, it seeds + the generated instructions.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional agent description. The authoring service resolves its fallback when omitted.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional tools carried through verbatim onto the generated agent (see ``VoiceAgentTool``).""" + draft: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """(Preview) When ``true``, the generated voice agent is created as a draft — an editable, + unpublished version the caller can review and refine before publishing it via the standard + create/version path. The service defaults to ``false`` if a value is not specified by the + caller, in which case the agent is created and published normally.""" + + @overload + def __init__( + self, + *, + kind: Literal[AgentKind.VOICE], + name: str, + model_type: Optional[Union[str, "_models.VoiceModelType"]] = None, + model: Optional[str] = None, + use_case: Optional[str] = None, + goal: Optional[str] = None, + description: Optional[str] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + draft: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class GitHubIssueRoutineTrigger( RoutineTrigger, discriminator="github_issue" ): # pylint: disable=docstring-keyword-should-match-keyword-only @@ -10278,6 +10668,59 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class ImportTelephonyCampaignRecipientsRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A request to import campaign recipients from a Dataset CSV, JSON array, or JSONL file. Imported + Agent-declared structured inputs follow the Agent definition's schema, required, and + default-value semantics. + + :ivar source: Required. + :vartype source: ~azure.ai.projects.models.TelephonyCampaignRecipientImportSource + :ivar mapping: Mappings from recipient properties to source fields or columns. Omit this + property or an individual entry to use same-named source fields. Destination and recipient-key + source fields are required. Optional source fields may be absent, except the recipient item key + when ``duplicate_handling`` is ``keep_each``. + :vartype mapping: ~azure.ai.projects.models.TelephonyCampaignRecipientMappingRequest + :ivar duplicate_handling: Known values are: "reject", "keep_each", and "merge". + :vartype duplicate_handling: str or + ~azure.ai.projects.models.TelephonyCampaignDuplicateHandling + """ + + source: "_models.TelephonyCampaignRecipientImportSource" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + mapping: Optional["_models.TelephonyCampaignRecipientMappingRequest"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Mappings from recipient properties to source fields or columns. Omit this property or an + individual entry to use same-named source fields. Destination and recipient-key source fields + are required. Optional source fields may be absent, except the recipient item key when + ``duplicate_handling`` is ``keep_each``.""" + duplicate_handling: Optional[Union[str, "_models.TelephonyCampaignDuplicateHandling"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"reject\", \"keep_each\", and \"merge\".""" + + @overload + def __init__( + self, + *, + source: "_models.TelephonyCampaignRecipientImportSource", + mapping: Optional["_models.TelephonyCampaignRecipientMappingRequest"] = None, + duplicate_handling: Optional[Union[str, "_models.TelephonyCampaignDuplicateHandling"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class InlineSkillParam( ContainerSkill, discriminator="inline" ): # pylint: disable=docstring-keyword-should-match-keyword-only @@ -10996,6 +11439,44 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class LogProbProperties(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A log probability object. + + :ivar token: The token that was used to generate the log probability. Required. + :vartype token: str + :ivar logprob: The log probability of the token. Required. + :vartype logprob: float + :ivar bytes: The bytes that were used to generate the log probability. Required. + :vartype bytes: list[int] + """ + + token: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The token that was used to generate the log probability. Required.""" + logprob: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The log probability of the token. Required.""" + bytes: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The bytes that were used to generate the log probability. Required.""" + + @overload + def __init__( + self, + *, + token: str, + logprob: float, + bytes: list[int], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class LoraConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Adapter-specific metadata for LoRA models. Drives serving engine configuration at deployment time. @@ -11126,20 +11607,73 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.type = IndexType.MANAGED_AZURE_SEARCH # type: ignore -class McpProtocolConfiguration(_Model): - """Configuration specific to the MCP protocol.""" +class MCPListToolsTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """MCP list tools tool. + :ivar name: The name of the tool. Required. + :vartype name: str + :ivar description: + :vartype description: str + :ivar input_schema: The JSON schema describing the tool's input. Required. + :vartype input_schema: ~azure.ai.projects.models.MCPListToolsToolInputSchema + :ivar annotations: + :vartype annotations: ~azure.ai.projects.models.MCPListToolsToolAnnotations + """ -class MCPTool(Tool, discriminator="mcp"): # pylint: disable=docstring-keyword-should-match-keyword-only - """MCP tool. + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_schema: "_models.MCPListToolsToolInputSchema" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The JSON schema describing the tool's input. Required.""" + annotations: Optional["_models.MCPListToolsToolAnnotations"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) - :ivar type: The type of the MCP tool. Always ``mcp``. Required. MCP. - :vartype type: str or ~azure.ai.projects.models.MCP - :ivar server_label: A label for this MCP server, used to identify it in tool calls. Required. - :vartype server_label: str - :ivar server_url: The URL for the MCP server. One of ``server_url``, ``connector_id``, or - ``tunnel_id`` must be provided. - :vartype server_url: str + @overload + def __init__( + self, + *, + name: str, + input_schema: "_models.MCPListToolsToolInputSchema", + description: Optional[str] = None, + annotations: Optional["_models.MCPListToolsToolAnnotations"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class MCPListToolsToolAnnotations(_Model): + """MCPListToolsToolAnnotations.""" + + +class MCPListToolsToolInputSchema(_Model): + """MCPListToolsToolInputSchema.""" + + +class McpProtocolConfiguration(_Model): + """Configuration specific to the MCP protocol.""" + + +class MCPTool(Tool, discriminator="mcp"): # pylint: disable=docstring-keyword-should-match-keyword-only + """MCP tool. + + :ivar type: The type of the MCP tool. Always ``mcp``. Required. MCP. + :vartype type: str or ~azure.ai.projects.models.MCP + :ivar server_label: A label for this MCP server, used to identify it in tool calls. Required. + :vartype server_label: str + :ivar server_url: The URL for the MCP server. One of ``server_url``, ``connector_id``, or + ``tunnel_id`` must be provided. + :vartype server_url: str :ivar connector_id: Identifier for service connectors, like those available in ChatGPT. One of ``server_url``, ``connector_id``, or ``tunnel_id`` must be provided. Learn more about service connectors `here `_. Currently supported @@ -12128,6 +12662,15 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class Metadata(_Model): + """Set of 16 key-value pairs that can be attached to an object. This can be useful for storing + additional information about the object in a structured format, and querying for objects via + API or the dashboard. Keys are strings with a maximum length of 64 characters. Values are + strings with a maximum length of 512 characters. + + """ + + class Microsoft365PermissionScopes(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """A set of delegated permission scopes requested from a single resource application. @@ -13523,6 +14066,36 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class PickPropertiesVoiceAgentAudioConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The template for picking properties. + + :ivar output: Output (agent speech) audio configuration. + :vartype output: ~azure.ai.projects.models.VoiceAgentAudioOutputConfig + """ + + output: Optional["_models.VoiceAgentAudioOutputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Output (agent speech) audio configuration.""" + + @overload + def __init__( + self, + *, + output: Optional["_models.VoiceAgentAudioOutputConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class ProceduralMemoryItem( MemoryItem, discriminator="procedural" ): # pylint: disable=docstring-keyword-should-match-keyword-only @@ -13974,7 +14547,7 @@ class ProtocolVersionRecord(_Model): # pylint: disable=docstring-keyword-should """A record mapping for a single protocol and its version. :ivar protocol: The protocol type. Required. Known values are: "activity", "responses", "a2a", - "mcp", "invocations", and "invocations_ws". + "mcp", "invocations", "voice", and "invocations_ws". :vartype protocol: str or ~azure.ai.projects.models.AgentEndpointProtocol :ivar version: The version string for the protocol, e.g. 'v0.1.1'. Required. :vartype version: str @@ -13984,7 +14557,7 @@ class ProtocolVersionRecord(_Model): # pylint: disable=docstring-keyword-should visibility=["read", "create", "update", "delete", "query"] ) """The protocol type. Required. Known values are: \"activity\", \"responses\", \"a2a\", \"mcp\", - \"invocations\", and \"invocations_ws\".""" + \"invocations\", \"voice\", and \"invocations_ws\".""" version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The version string for the protocol, e.g. 'v0.1.1'. Required.""" @@ -14007,21 +14580,240 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class TelephonyTransferDestination(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A destination for a telephony transfer target. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + PSTNTelephonyTransferDestination, SipTelephonyTransferDestination, + TeamsTelephonyTransferDestination + + :ivar kind: The telephony transfer destination type. Required. Known values are: "pstn", + "teams", and "sip". + :vartype kind: str or ~azure.ai.projects.models.TelephonyTransferDestinationKind + """ + + __mapping__: dict[str, _Model] = {} + kind: str = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) + """The telephony transfer destination type. Required. Known values are: \"pstn\", \"teams\", and + \"sip\".""" + + @overload + def __init__( + self, + *, + kind: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class PSTNTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="pstn" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A PSTN destination for a telephony transfer target. + + :ivar kind: The PSTN destination type. Required. A public switched telephone network + destination. + :vartype kind: str or ~azure.ai.projects.models.PSTN + :ivar value: The E.164 phone number to call. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.PSTN] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The PSTN destination type. Required. A public switched telephone network destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The E.164 phone number to call. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.PSTN # type: ignore + + +class PublishTelephonyCampaignRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A request to publish a validated outbound campaign draft. + + :ivar validation_id: Required. + :vartype validation_id: str + """ + + validation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + validation_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class RaiConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Configuration for Responsible AI (RAI) content filtering and safety features. :ivar rai_policy_name: The name of the RAI policy to apply. Required. :vartype rai_policy_name: str + :ivar invocations_moderation: Author-declared configuration telling the platform where + user/agent text lives in the agent-defined invocations request/response bodies, so + content-safety guardrails can extract and moderate it. Optional; a rai_config without it leaves + the invocations path without content-safety moderation. + :vartype invocations_moderation: ~azure.ai.projects.models.RaiInvocationModeration """ rai_policy_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The name of the RAI policy to apply. Required.""" + invocations_moderation: Optional["_models.RaiInvocationModeration"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Author-declared configuration telling the platform where user/agent text lives in the + agent-defined invocations request/response bodies, so content-safety guardrails can extract and + moderate it. Optional; a rai_config without it leaves the invocations path without + content-safety moderation.""" @overload def __init__( self, *, rai_policy_name: str, + invocations_moderation: Optional["_models.RaiInvocationModeration"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RaiInvocationModeration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Declares where request/response text lives so content-safety guardrails can extract it. + + :ivar input_content_type: How the REQUEST body is parsed. When omitted, the service defaults to + ``json``. Known values are: "json" and "text". + :vartype input_content_type: str or ~azure.ai.projects.models.RaiInvocationContentType + :ivar output_content_type: How the RESPONSE body is parsed. When omitted, the service defaults + to ``json``. Known values are: "json" and "text". + :vartype output_content_type: str or ~azure.ai.projects.models.RaiInvocationContentType + :ivar response_mode: Author-declared response shape; drives which output gate runs and which + fields are required. Required. Known values are: "non_streaming", "streaming", and "both". + :vartype response_mode: str or ~azure.ai.projects.models.RaiInvocationMode + :ivar input_paths: Path(s) to user text in the REQUEST body. Required when input_content_type + is ``json``. + :vartype input_paths: list[str] + :ivar output_paths: Path(s) to agent text in a NON-STREAMING response body. Required when + response_mode is non_streaming/both and output_content_type is ``json``. + :vartype output_paths: list[str] + :ivar stream_selectors: One SSE event->field selector per event type carrying text. Required + when response_mode is streaming/both and output_content_type is ``json``. + :vartype stream_selectors: list[~azure.ai.projects.models.RaiSseTextSelector] + """ + + input_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the REQUEST body is parsed. When omitted, the service defaults to ``json``. Known values + are: \"json\" and \"text\".""" + output_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the RESPONSE body is parsed. When omitted, the service defaults to ``json``. Known values + are: \"json\" and \"text\".""" + response_mode: Union[str, "_models.RaiInvocationMode"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Author-declared response shape; drives which output gate runs and which fields are required. + Required. Known values are: \"non_streaming\", \"streaming\", and \"both\".""" + input_paths: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Path(s) to user text in the REQUEST body. Required when input_content_type is ``json``.""" + output_paths: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Path(s) to agent text in a NON-STREAMING response body. Required when response_mode is + non_streaming/both and output_content_type is ``json``.""" + stream_selectors: Optional[list["_models.RaiSseTextSelector"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """One SSE event->field selector per event type carrying text. Required when response_mode is + streaming/both and output_content_type is ``json``.""" + + @overload + def __init__( + self, + *, + response_mode: Union[str, "_models.RaiInvocationMode"], + input_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = None, + output_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = None, + input_paths: Optional[list[str]] = None, + output_paths: Optional[list[str]] = None, + stream_selectors: Optional[list["_models.RaiSseTextSelector"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RaiSseTextSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An SSE event-type to text-field selector for streaming invocation output. + + :ivar event_type: The SSE event ``type`` value that carries text. Required. + :vartype event_type: str + :ivar text_field: The field on a matched event holding the text delta. When omitted, the + service defaults to ``delta``. + :vartype text_field: str + """ + + event_type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The SSE event ``type`` value that carries text. Required.""" + text_field: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The field on a matched event holding the text delta. When omitted, the service defaults to + ``delta``.""" + + @overload + def __init__( + self, + *, + event_type: str, + text_field: Optional[str] = None, ) -> None: ... @overload @@ -14083,57 +14875,25 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class Reasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Reasoning. +class RealtimeAudioFormats(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeAudioFormats. - :ivar mode: Controls the reasoning execution mode for the request. When returned on a response, - this is the effective execution mode. Known values are: "standard" and "pro". - :vartype mode: str or ~azure.ai.projects.models.ReasoningModeEnum - :ivar effort: Known values are: "none", "minimal", "low", "medium", "high", "xhigh", and "max". - :vartype effort: str or ~azure.ai.projects.models.ReasoningEffort - :ivar summary: Is one of the following types: Literal["auto"], Literal["concise"], - Literal["detailed"] - :vartype summary: str or str or str - :ivar context: Is one of the following types: Literal["auto"], Literal["current_turn"], - Literal["all_turns"] - :vartype context: str or str or str - :ivar generate_summary: Is one of the following types: Literal["auto"], Literal["concise"], - Literal["detailed"] - :vartype generate_summary: str or str or str + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeAudioFormatsAudioPcm, RealtimeAudioFormatsAudioPcma, RealtimeAudioFormatsAudioPcmu + + :ivar type: Required. Known values are: "audio/pcm", "audio/pcmu", and "audio/pcma". + :vartype type: str or ~azure.ai.projects.models.RealtimeAudioFormatsType """ - mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Controls the reasoning execution mode for the request. When returned on a response, this is the - effective execution mode. Known values are: \"standard\" and \"pro\".""" - effort: Optional[Union[str, "_models.ReasoningEffort"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Known values are: \"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", and \"max\".""" - summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" - context: Optional[Literal["auto", "current_turn", "all_turns"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"current_turn\"], - Literal[\"all_turns\"]""" - generate_summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"audio/pcm\", \"audio/pcmu\", and \"audio/pcma\".""" @overload def __init__( self, *, - mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = None, - effort: Optional[Union[str, "_models.ReasoningEffort"]] = None, - summary: Optional[Literal["auto", "concise", "detailed"]] = None, - context: Optional[Literal["auto", "current_turn", "all_turns"]] = None, - generate_summary: Optional[Literal["auto", "concise", "detailed"]] = None, + type: str, ) -> None: ... @overload @@ -14147,51 +14907,27 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class RecurrenceTrigger( - Trigger, discriminator="Recurrence" +class RealtimeAudioFormatsAudioPcm( + RealtimeAudioFormats, discriminator="audio/pcm" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """Recurrence based trigger. + """RealtimeAudioFormatsAudioPcm. - :ivar type: Type of the trigger. Required. Recurrence based trigger. - :vartype type: str or ~azure.ai.projects.models.RECURRENCE - :ivar start_time: Start time for the recurrence schedule in ISO 8601 format. - :vartype start_time: ~datetime.datetime - :ivar end_time: End time for the recurrence schedule in ISO 8601 format. - :vartype end_time: ~datetime.datetime - :ivar time_zone: Time zone for the recurrence schedule. Defaults to ``UTC``. - :vartype time_zone: str - :ivar interval: Interval for the recurrence schedule. Required. - :vartype interval: int - :ivar schedule: Recurrence schedule for the recurrence trigger. Required. - :vartype schedule: ~azure.ai.projects.models.RecurrenceSchedule + :ivar type: Required. AUDIO_PCM. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCM + :ivar rate: Default value is 24000. + :vartype rate: int """ - type: Literal[TriggerType.RECURRENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Type of the trigger. Required. Recurrence based trigger.""" - start_time: Optional[datetime.datetime] = rest_field( - name="startTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """Start time for the recurrence schedule in ISO 8601 format.""" - end_time: Optional[datetime.datetime] = rest_field( - name="endTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """End time for the recurrence schedule in ISO 8601 format.""" - time_zone: Optional[str] = rest_field(name="timeZone", visibility=["read", "create", "update", "delete", "query"]) - """Time zone for the recurrence schedule. Defaults to ``UTC``.""" - interval: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Interval for the recurrence schedule. Required.""" - schedule: "_models.RecurrenceSchedule" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Recurrence schedule for the recurrence trigger. Required.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCM.""" + rate: Optional[Literal[24000]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Default value is 24000.""" @overload def __init__( self, *, - interval: int, - schedule: "_models.RecurrenceSchedule", - start_time: Optional[datetime.datetime] = None, - end_time: Optional[datetime.datetime] = None, - time_zone: Optional[str] = None, + rate: Optional[Literal[24000]] = None, ) -> None: ... @overload @@ -14203,88 +14939,22 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TriggerType.RECURRENCE # type: ignore + self.type = RealtimeAudioFormatsType.AUDIO_PCM # type: ignore -class RedTeam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Red team details. +class RealtimeAudioFormatsAudioPcma(RealtimeAudioFormats, discriminator="audio/pcma"): + """RealtimeAudioFormatsAudioPcma. - :ivar name: Identifier of the red team run. Required. - :vartype name: str - :ivar display_name: Name of the red-team run. - :vartype display_name: str - :ivar num_turns: Number of simulation rounds. - :vartype num_turns: int - :ivar attack_strategies: List of attack strategies or nested lists of attack strategies. - :vartype attack_strategies: list[str or ~azure.ai.projects.models.AttackStrategy] - :ivar simulation_only: Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs - conversation not evaluation result. The service defaults to ``false`` if a value is not - specified by the caller. - :vartype simulation_only: bool - :ivar risk_categories: List of risk categories to generate attack objectives for. - :vartype risk_categories: list[str or ~azure.ai.projects.models.RiskCategory] - :ivar application_scenario: Application scenario for the red team operation, to generate - scenario specific attacks. - :vartype application_scenario: str - :ivar tags: Red team's tags. Unlike properties, tags are fully mutable. - :vartype tags: dict[str, str] - :ivar properties: Red team's properties. Unlike tags, properties are add-only. Once added, a - property cannot be removed. - :vartype properties: dict[str, str] - :ivar status: Status of the red-team. It is set by service and is read-only. - :vartype status: str - :ivar target: Target configuration for the red-team run. Required. - :vartype target: ~azure.ai.projects.models.RedTeamTargetConfig + :ivar type: Required. AUDIO_PCMA. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCMA """ - name: str = rest_field(name="id", visibility=["read"]) - """Identifier of the red team run. Required.""" - display_name: Optional[str] = rest_field( - name="displayName", visibility=["read", "create", "update", "delete", "query"] - ) - """Name of the red-team run.""" - num_turns: Optional[int] = rest_field(name="numTurns", visibility=["read", "create", "update", "delete", "query"]) - """Number of simulation rounds.""" - attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = rest_field( - name="attackStrategies", visibility=["read", "create", "update", "delete", "query"] - ) - """List of attack strategies or nested lists of attack strategies.""" - simulation_only: Optional[bool] = rest_field( - name="simulationOnly", visibility=["read", "create", "update", "delete", "query"] - ) - """Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs conversation not - evaluation result. The service defaults to ``false`` if a value is not specified by the caller.""" - risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = rest_field( - name="riskCategories", visibility=["read", "create", "update", "delete", "query"] - ) - """List of risk categories to generate attack objectives for.""" - application_scenario: Optional[str] = rest_field( - name="applicationScenario", visibility=["read", "create", "update", "delete", "query"] - ) - """Application scenario for the red team operation, to generate scenario specific attacks.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Red team's tags. Unlike properties, tags are fully mutable.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Red team's properties. Unlike tags, properties are add-only. Once added, a property cannot be - removed.""" - status: Optional[str] = rest_field(visibility=["read"]) - """Status of the red-team. It is set by service and is read-only.""" - target: "_models.RedTeamTargetConfig" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Target configuration for the red-team run. Required.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCMA.""" @overload def __init__( self, - *, - target: "_models.RedTeamTargetConfig", - display_name: Optional[str] = None, - num_turns: Optional[int] = None, - attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = None, - simulation_only: Optional[bool] = None, - risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = None, - application_scenario: Optional[str] = None, - tags: Optional[dict[str, str]] = None, - properties: Optional[dict[str, str]] = None, ) -> None: ... @overload @@ -14296,35 +14966,22 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeAudioFormatsType.AUDIO_PCMA # type: ignore -class ReminderPreviewToolboxTool( - ToolboxTool, discriminator="reminder_preview" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A reminder tool stored in a toolbox. +class RealtimeAudioFormatsAudioPcmu(RealtimeAudioFormats, discriminator="audio/pcmu"): + """RealtimeAudioFormatsAudioPcmu. - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: Required. REMINDER_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.REMINDER_PREVIEW + :ivar type: Required. AUDIO_PCMU. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCMU """ - type: Literal[ToolboxToolType.REMINDER_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. REMINDER_PREVIEW.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMU] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCMU.""" @overload def __init__( self, - *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, ) -> None: ... @overload @@ -14336,33 +14993,98 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.REMINDER_PREVIEW # type: ignore - + self.type = RealtimeAudioFormatsType.AUDIO_PCMU # type: ignore -class ResponsesProtocolConfiguration(_Model): - """Configuration specific to the responses protocol.""" +class RealtimeClientEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A realtime client event. -class ResponseUsageInputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """ResponseUsageInputTokensDetails. + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeClientEventConversationItemCreate, RealtimeClientEventConversationItemDelete, + RealtimeClientEventConversationItemRetrieve, RealtimeClientEventConversationItemTruncate, + RealtimeClientEventInputAudioBufferAppend, RealtimeClientEventInputAudioBufferClear, + RealtimeClientEventInputAudioBufferCommit, RealtimeClientEventOutputAudioBufferClear, + RealtimeClientEventResponseCancel, RealtimeClientEventResponseCreate, + VoiceAgentClientEventRtcCallSdpCreate, VoiceAgentClientEventSessionAvatarConnect - :ivar cached_tokens: Required. - :vartype cached_tokens: int - :ivar cache_write_tokens: Required. - :vartype cache_write_tokens: int + :ivar type: Required. Known values are: "conversation.item.create", "conversation.item.delete", + "conversation.item.retrieve", "conversation.item.truncate", "input_audio_buffer.append", + "input_audio_buffer.clear", "output_audio_buffer.clear", "input_audio_buffer.commit", + "response.cancel", "response.create", "session.update", "session.avatar.connect", and + "rtc.call.sdp.create". + :vartype type: str or ~azure.ai.projects.models.RealtimeClientEventType """ - cached_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" - cache_write_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"conversation.item.create\", \"conversation.item.delete\", + \"conversation.item.retrieve\", \"conversation.item.truncate\", \"input_audio_buffer.append\", + \"input_audio_buffer.clear\", \"output_audio_buffer.clear\", \"input_audio_buffer.commit\", + \"response.cancel\", \"response.create\", \"session.update\", \"session.avatar.connect\", and + \"rtc.call.sdp.create\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeClientEventConversationItemCreate( + RealtimeClientEvent, discriminator="conversation.item.create" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Add a new Item to the Conversation's context, including messages, function calls, and function + call responses. This event can be used both to populate a "history" of the conversation and to + add new items mid-stream, but has the current limitation that it cannot populate assistant + audio messages. If successful, the server will respond with a ``conversation.item.created`` + event, otherwise an ``error`` event will be sent. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.create``. Required. + CONVERSATION_ITEM_CREATE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_CREATE + :ivar previous_item_id: The ID of the preceding item after which the new item will be inserted. + If not set, the new item will be appended to the end of the conversation. If set to ``root``, + the new item will be added to the beginning of the conversation. If set to an existing ID, it + allows an item to be inserted mid-conversation. If the ID cannot be found, an error will be + returned and the item will not be added. + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.create``. Required. CONVERSATION_ITEM_CREATE.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the preceding item after which the new item will be inserted. If not set, the new + item will be appended to the end of the conversation. If set to ``root``, the new item will be + added to the beginning of the conversation. If set to an existing ID, it allows an item to be + inserted mid-conversation. If the ID cannot be found, an error will be returned and the item + will not be added.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Required.""" @overload def __init__( self, *, - cached_tokens: int, - cache_write_tokens: int, + item: "_models.RealtimeConversationItem", + event_id: Optional[str] = None, + previous_item_id: Optional[str] = None, ) -> None: ... @overload @@ -14374,23 +15096,38 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_CREATE # type: ignore -class ResponseUsageOutputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """ResponseUsageOutputTokensDetails. +class RealtimeClientEventConversationItemDelete( + RealtimeClientEvent, discriminator="conversation.item.delete" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event when you want to remove any item from the conversation history. The server will + respond with a ``conversation.item.deleted`` event, unless the item does not exist in the + conversation history, in which case the server will respond with an error. - :ivar reasoning_tokens: Required. - :vartype reasoning_tokens: int + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.delete``. Required. + CONVERSATION_ITEM_DELETE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DELETE + :ivar item_id: The ID of the item to delete. Required. + :vartype item_id: str """ - reasoning_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_DELETE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.delete``. Required. CONVERSATION_ITEM_DELETE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to delete. Required.""" @overload def __init__( self, *, - reasoning_tokens: int, + item_id: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14402,59 +15139,40 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_DELETE # type: ignore -class Routine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A routine definition returned by the service. +class RealtimeClientEventConversationItemRetrieve( + RealtimeClientEvent, discriminator="conversation.item.retrieve" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event when you want to retrieve the server's representation of a specific item in the + conversation history. This is useful, for example, to inspect user audio after noise + cancellation and VAD. The server will respond with a ``conversation.item.retrieved`` event, + unless the item does not exist in the conversation history, in which case the server will + respond with an error. - :ivar name: The routine name. - :vartype name: str - :ivar description: A human-readable description of the routine. - :vartype description: str - :ivar enabled: Whether the routine is enabled. Required. - :vartype enabled: bool - :ivar triggers: The triggers configured for the routine. - :vartype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :ivar action: The action executed when the routine fires. - :vartype action: ~azure.ai.projects.models.RoutineAction - :ivar created_at: The time when the routine was created. - :vartype created_at: ~datetime.datetime - :ivar updated_at: The time when the routine was last updated. - :vartype updated_at: ~datetime.datetime + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.retrieve``. Required. + CONVERSATION_ITEM_RETRIEVE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_RETRIEVE + :ivar item_id: The ID of the item to retrieve. Required. + :vartype item_id: str """ - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The routine name.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the routine.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether the routine is enabled. Required.""" - triggers: Optional[dict[str, "_models.RoutineTrigger"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The triggers configured for the routine.""" - action: Optional["_models.RoutineAction"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The action executed when the routine fires.""" - created_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The time when the routine was created.""" - updated_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The time when the routine was last updated.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.retrieve``. Required. CONVERSATION_ITEM_RETRIEVE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to retrieve. Required.""" @overload def __init__( self, *, - enabled: bool, - name: Optional[str] = None, - description: Optional[str] = None, - triggers: Optional[dict[str, "_models.RoutineTrigger"]] = None, - action: Optional["_models.RoutineAction"] = None, - created_at: Optional[datetime.datetime] = None, - updated_at: Optional[datetime.datetime] = None, + item_id: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14466,29 +15184,109 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE # type: ignore -class RoutineAuthorization(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Optional authorization configuration for a routine dispatch. +class RealtimeClientEventConversationItemTruncate( + RealtimeClientEvent, discriminator="conversation.item.truncate" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to truncate a previous assistant message’s audio. The server will produce audio + faster than realtime, so this event is useful when the user interrupts to truncate audio that + has already been sent to the client but not yet played. This will synchronize the server's + understanding of the audio with the client's playback. Truncating audio will delete the + server-side text transcript to ensure there is not text in the context that hasn't been heard + by the user. If successful, the server will respond with a ``conversation.item.truncated`` + event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.truncate``. Required. + CONVERSATION_ITEM_TRUNCATE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_TRUNCATE + :ivar item_id: The ID of the assistant message item to truncate. Only assistant message items + can be truncated. Required. + :vartype item_id: str + :ivar content_index: The index of the content part to truncate. Set this to ``0``. Required. + :vartype content_index: int + :ivar audio_end_ms: Inclusive duration up to which audio is truncated, in milliseconds. If the + audio_end_ms is greater than the actual audio duration, the server will respond with an error. + Required. + :vartype audio_end_ms: int + """ - :ivar identity: The identity used when dispatching the routine. Defaults to agent when omitted; - set to creator only when the customer opts in to creator identity dispatch. Known values are: - "agent" and "creator". - :vartype identity: str or ~azure.ai.projects.models.RoutineDispatchIdentity + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.truncate``. Required. CONVERSATION_ITEM_TRUNCATE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the assistant message item to truncate. Only assistant message items can be + truncated. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part to truncate. Set this to ``0``. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Inclusive duration up to which audio is truncated, in milliseconds. If the audio_end_ms is + greater than the actual audio duration, the server will respond with an error. Required.""" + + @overload + def __init__( + self, + *, + item_id: str, + content_index: int, + audio_end_ms: int, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE # type: ignore + + +class RealtimeClientEventInputAudioBufferAppend( + RealtimeClientEvent, discriminator="input_audio_buffer.append" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to append audio bytes to the input audio buffer. The audio buffer is temporary + storage you can write to and later commit. A "commit" will create a new user message item in + the conversation history from the buffer content and clear the buffer. Input audio + transcription (if enabled) will be generated when the buffer is committed. If VAD is enabled + the audio buffer is used to detect speech and the server will decide when to commit. When + Server VAD is disabled, you must commit the audio buffer manually. Input audio noise reduction + operates on writes to the audio buffer. The client may choose how much audio to place in each + event up to a maximum of 15 MiB, for example streaming smaller chunks from the client may allow + the VAD to be more responsive. Unlike most other client events, the server will not send a + confirmation response to this event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.append``. Required. + INPUT_AUDIO_BUFFER_APPEND. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_APPEND + :ivar audio: Base64-encoded audio bytes. This must be in the format specified by the + ``input_audio_format`` field in the session configuration. Required. + :vartype audio: str """ - identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The identity used when dispatching the routine. Defaults to agent when omitted; set to creator - only when the customer opts in to creator identity dispatch. Known values are: \"agent\" and - \"creator\".""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.append``. Required. INPUT_AUDIO_BUFFER_APPEND.""" + audio: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Base64-encoded audio bytes. This must be in the format specified by the ``input_audio_format`` + field in the session configuration. Required.""" @overload def __init__( self, *, - identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = None, + audio: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14500,164 +15298,10039 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND # type: ignore -class RoutineRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single routine run returned from the run history API. +class RealtimeClientEventInputAudioBufferClear( + RealtimeClientEvent, discriminator="input_audio_buffer.clear" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Send this event to clear the audio bytes in the buffer. The server will respond with an + ``input_audio_buffer.cleared`` event. - :ivar id: The unique run identifier for the routine attempt. Required. - :vartype id: str - :ivar status: The run status. Is one of the following types: str - :vartype status: str - :ivar phase: The AgentExtensions lifecycle phase for the routine attempt. Known values are: - "queued", "dispatching", "completed", and "failed". - :vartype phase: str or ~azure.ai.projects.models.RoutineRunPhase - :ivar trigger_type: The trigger type that produced the routine attempt. Known values are: - "custom", "github_issue", "schedule", and "timer". - :vartype trigger_type: str or ~azure.ai.projects.models.RoutineTriggerType - :ivar trigger_name: The configured trigger name that produced the routine attempt. - :vartype trigger_name: str - :ivar trigger_event_payload: The event payload captured from the event that triggered the - routine attempt, when available. - :vartype trigger_event_payload: dict[str, any] - :ivar attempt_source: The source path that created the routine attempt. Known values are: - "event_fire", "manual_dispatch", "queued_dispatch", "schedule_delivery", and "timer_delivery". - :vartype attempt_source: str or ~azure.ai.projects.models.RoutineAttemptSource - :ivar action_type: The action type dispatched for the routine attempt. Known values are: - "invoke_agent_responses_api" and "invoke_agent_invocations_api". - :vartype action_type: str or ~azure.ai.projects.models.RoutineActionType - :ivar agent_id: The project-scoped agent identifier recorded for the routine attempt. - :vartype agent_id: str - :ivar agent_endpoint_id: The legacy endpoint-scoped agent identifier recorded for the routine - attempt. - :vartype agent_endpoint_id: str - :ivar conversation_id: The conversation identifier used by a responses API dispatch. - :vartype conversation_id: str - :ivar session_id: The hosted-agent session identifier used by an invocations API dispatch. - :vartype session_id: str - :ivar triggered_at: The logical trigger time recorded for the routine attempt. - :vartype triggered_at: ~datetime.datetime - :ivar scheduled_fire_at: The scheduled fire time recorded for timer and schedule deliveries. - :vartype scheduled_fire_at: ~datetime.datetime - :ivar started_at: The time when the underlying run started. - :vartype started_at: ~datetime.datetime - :ivar ended_at: The time when the underlying run reached a terminal state. - :vartype ended_at: ~datetime.datetime - :ivar dispatch_id: The dispatch identifier associated with the routine attempt. - :vartype dispatch_id: str - :ivar action_correlation_id: The downstream action correlation identifier, when available. - :vartype action_correlation_id: str - :ivar response_id: The downstream response or invocation identifier, when available. + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.clear``. Required. + INPUT_AUDIO_BUFFER_CLEAR. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_CLEAR + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.clear``. Required. INPUT_AUDIO_BUFFER_CLEAR.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR # type: ignore + + +class RealtimeClientEventInputAudioBufferCommit( + RealtimeClientEvent, discriminator="input_audio_buffer.commit" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to commit the user input audio buffer, which will create a new user message + item in the conversation. This event will produce an error if the input audio buffer is empty. + When in Server VAD mode, the client does not need to send this event, the server will commit + the audio buffer automatically. Committing the input audio buffer will trigger input audio + transcription (if enabled in session configuration), but it will not create a response from + the model. The server will respond with an ``input_audio_buffer.committed`` event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.commit``. Required. + INPUT_AUDIO_BUFFER_COMMIT. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_COMMIT + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.commit``. Required. INPUT_AUDIO_BUFFER_COMMIT.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT # type: ignore + + +class RealtimeClientEventOutputAudioBufferClear( + RealtimeClientEvent, discriminator="output_audio_buffer.clear" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """**WebRTC/SIP Only:** Emit to cut off the current audio response. This will trigger the server + to stop generating audio and emit a ``output_audio_buffer.cleared`` event. This event should be + preceded by a ``response.cancel`` client event to stop the generation of the current response. + `Learn more + `_. + + :ivar event_id: The unique ID of the client event used for error handling. + :vartype event_id: str + :ivar type: The event type, must be ``output_audio_buffer.clear``. Required. + OUTPUT_AUDIO_BUFFER_CLEAR. + :vartype type: str or ~azure.ai.projects.models.OUTPUT_AUDIO_BUFFER_CLEAR + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the client event used for error handling.""" + type: Literal[RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``output_audio_buffer.clear``. Required. OUTPUT_AUDIO_BUFFER_CLEAR.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR # type: ignore + + +class RealtimeClientEventResponseCancel( + RealtimeClientEvent, discriminator="response.cancel" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Send this event to cancel an in-progress response. The server will respond with a + ``response.done`` event with a status of ``response.status=cancelled``. If there is no response + to cancel, the server will respond with an error. It's safe to call ``response.cancel`` even if + no response is in progress, an error will be returned the session will remain unaffected. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``response.cancel``. Required. RESPONSE_CANCEL. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CANCEL + :ivar response_id: A specific response ID to cancel - if not provided, will cancel an + in-progress response in the default conversation. :vartype response_id: str - :ivar task_id: The workspace task identifier linked to the routine attempt, when available. - :vartype task_id: str - :ivar error_status_code: The downstream error status code captured for a failed attempt, when - available. - :vartype error_status_code: int - :ivar error_type: The fully qualified error type captured for a failed attempt, when available. - :vartype error_type: str - :ivar error_message: The truncated failure message captured for a failed attempt, when - available. - :vartype error_message: str """ - id: str = rest_field(visibility=["read"]) - """The unique run identifier for the routine attempt. Required.""" - status: Optional["_unions.RoutineRunStatus"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The run status. Is one of the following types: str""" - phase: Optional[Union[str, "_models.RoutineRunPhase"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The AgentExtensions lifecycle phase for the routine attempt. Known values are: \"queued\", - \"dispatching\", \"completed\", and \"failed\".""" - trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The trigger type that produced the routine attempt. Known values are: \"custom\", - \"github_issue\", \"schedule\", and \"timer\".""" - trigger_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The configured trigger name that produced the routine attempt.""" - trigger_event_payload: Optional[dict[str, Any]] = rest_field( + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.RESPONSE_CANCEL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.cancel``. Required. RESPONSE_CANCEL.""" + response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A specific response ID to cancel - if not provided, will cancel an in-progress response in the + default conversation.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + response_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.RESPONSE_CANCEL # type: ignore + + +class RealtimeClientEventResponseCreate( + RealtimeClientEvent, discriminator="response.create" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """This event instructs the server to create a Response, which means triggering model inference. + When in Server VAD mode, the server will create Responses automatically. A Response will + include at least one Item, and may have two, in which case the second will be a function call. + These Items will be appended to the conversation history by default. The server will respond + with a ``response.created`` event, events for Items and content created, and finally a + ``response.done`` event to indicate the Response is complete. The ``response.create`` event + includes inference configuration like ``instructions`` and ``tools``. If these are set, they + will override the Session's configuration for this Response only. Responses can be created + out-of-band of the default Conversation, meaning that they can have arbitrary input, and it's + possible to disable writing the output to the Conversation. Only one Response can write to the + default Conversation at a time, but otherwise multiple Responses can be created in parallel. + The ``metadata`` field is a good way to disambiguate multiple simultaneous Responses. Clients + can set ``conversation`` to ``none`` to create a Response that does not write to the default + Conversation. Arbitrary input can be provided with the ``input`` field, which is an array + accepting raw Items and references to existing Items. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``response.create``. Required. RESPONSE_CREATE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CREATE + :ivar response: + :vartype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.RESPONSE_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.create``. Required. RESPONSE_CREATE.""" + response: Optional["_models.VoiceAgentResponseCreateParams"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The event payload captured from the event that triggered the routine attempt, when available.""" - attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = rest_field( + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + response: Optional["_models.VoiceAgentResponseCreateParams"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.RESPONSE_CREATE # type: ignore + + +class RealtimeConversationItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single item within a Realtime conversation. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeConversationItemFunctionCall, RealtimeConversationItemFunctionCallOutput, + RealtimeMCPApprovalRequest, RealtimeMCPApprovalResponse, RealtimeMCPToolCall, + RealtimeMCPListTools, RealtimeConversationItemMessage + + :ivar type: Required. Known values are: "function_call", "function_call_output", + "mcp_approval_response", "mcp_list_tools", "mcp_call", "mcp_approval_request", and "message". + :vartype type: str or ~azure.ai.projects.models.RealtimeConversationItemType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"function_call\", \"function_call_output\", + \"mcp_approval_response\", \"mcp_list_tools\", \"mcp_call\", \"mcp_approval_request\", and + \"message\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemFunctionCall( + RealtimeConversationItem, discriminator="function_call" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime function call item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``function_call``. Required. FUNCTION_CALL. + :vartype type: str or ~azure.ai.projects.models.FUNCTION_CALL + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar call_id: The ID of the function call. + :vartype call_id: str + :ivar name: The name of the function being called. Required. + :vartype name: str + :ivar arguments: The arguments of the function call. This is a JSON-encoded string representing + the arguments passed to the function, for example ``{"arg1": "value1", "arg2": 42}``. Required. + :vartype arguments: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + type: Literal[RealtimeConversationItemType.FUNCTION_CALL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``function_call``. Required. FUNCTION_CALL.""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The source path that created the routine attempt. Known values are: \"event_fire\", - \"manual_dispatch\", \"queued_dispatch\", \"schedule_delivery\", and \"timer_delivery\".""" - action_type: Optional[Union[str, "_models.RoutineActionType"]] = rest_field( + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function being called. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The arguments of the function call. This is a JSON-encoded string representing the arguments + passed to the function, for example ``{\"arg1\": \"value1\", \"arg2\": 42}``. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + name: str, + arguments: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + call_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.FUNCTION_CALL # type: ignore + + +class RealtimeConversationItemFunctionCallOutput( + RealtimeConversationItem, discriminator="function_call_output" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Realtime function call output item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``function_call_output``. Required. + FUNCTION_CALL_OUTPUT. + :vartype type: str or ~azure.ai.projects.models.FUNCTION_CALL_OUTPUT + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar call_id: The ID of the function call this output is for. Required. + :vartype call_id: str + :ivar output: The output of the function call, this is free text and can contain any + information or simply be empty. Required. + :vartype output: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + :ivar name: The name of the function that was called. A Foundry extension: OpenAI's + function_call_output does not carry the function name, only ``call_id``. + :vartype name: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + type: Literal[RealtimeConversationItemType.FUNCTION_CALL_OUTPUT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``function_call_output``. Required. FUNCTION_CALL_OUTPUT.""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The action type dispatched for the routine attempt. Known values are: - \"invoke_agent_responses_api\" and \"invoke_agent_invocations_api\".""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The project-scoped agent identifier recorded for the routine attempt.""" - agent_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The legacy endpoint-scoped agent identifier recorded for the routine attempt.""" - conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The conversation identifier used by a responses API dispatch.""" - session_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The hosted-agent session identifier used by an invocations API dispatch.""" - triggered_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The logical trigger time recorded for the routine attempt.""" - scheduled_fire_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The scheduled fire time recorded for timer and schedule deliveries.""" - started_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The time when the underlying run started.""" - ended_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call this output is for. Required.""" + output: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The output of the function call, this is free text and can contain any information or simply be + empty. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function that was called. A Foundry extension: OpenAI's function_call_output + does not carry the function name, only ``call_id``.""" + + @overload + def __init__( + self, + *, + call_id: str, + output: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + name: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.FUNCTION_CALL_OUTPUT # type: ignore + + +class RealtimeConversationItemMessage( + RealtimeConversationItem, discriminator="message" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessage. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeConversationItemMessageAssistant, RealtimeConversationItemMessageSystem, + RealtimeConversationItemMessageUser + + :ivar role: Required. Known values are: "system", "user", and "assistant". + :vartype role: str or ~azure.ai.projects.models.RealtimeConversationItemMessageType + :ivar type: Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + """ + + __mapping__: dict[str, _Model] = {} + role: str = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"system\", \"user\", and \"assistant\".""" + type: Literal[RealtimeConversationItemType.MESSAGE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. MESSAGE.""" + + @overload + def __init__( + self, + *, + role: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MESSAGE # type: ignore + + +class RealtimeConversationItemMessageAssistant( + RealtimeConversationItemMessage, discriminator="assistant" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime assistant message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``assistant``. Required. ASSISTANT. + :vartype role: str or ~azure.ai.projects.models.ASSISTANT + :ivar content: The content of the message. Required. + :vartype content: + list[~azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.ASSISTANT] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``assistant``. Required. ASSISTANT.""" + content: list["_models.RealtimeConversationItemMessageAssistantContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageAssistantContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.ASSISTANT # type: ignore + + +class RealtimeConversationItemMessageAssistantContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageAssistantContent. + + :ivar type: Is either a Literal["output_text"] type or a Literal["output_audio"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["output_text", "output_audio"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a Literal[\"output_text\"] type or a Literal[\"output_audio\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["output_text", "output_audio"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemMessageSystem( + RealtimeConversationItemMessage, discriminator="system" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime system message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``system``. Required. SYSTEM. + :vartype role: str or ~azure.ai.projects.models.SYSTEM + :ivar content: The content of the message. Required. + :vartype content: list[~azure.ai.projects.models.RealtimeConversationItemMessageSystemContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.SYSTEM] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``system``. Required. SYSTEM.""" + content: list["_models.RealtimeConversationItemMessageSystemContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageSystemContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.SYSTEM # type: ignore + + +class RealtimeConversationItemMessageSystemContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageSystemContent. + + :ivar type: Default value is "input_text". + :vartype type: str + :ivar text: + :vartype text: str + """ + + type: Optional[Literal["input_text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Default value is \"input_text\".""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["input_text"]] = None, + text: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemMessageUser( + RealtimeConversationItemMessage, discriminator="user" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime user message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``user``. Required. USER. + :vartype role: str or ~azure.ai.projects.models.USER + :ivar content: The content of the message. Required. + :vartype content: list[~azure.ai.projects.models.RealtimeConversationItemMessageUserContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.USER] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``user``. Required. USER.""" + content: list["_models.RealtimeConversationItemMessageUserContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageUserContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.USER # type: ignore + + +class RealtimeConversationItemMessageUserContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageUserContent. + + :ivar type: Is one of the following types: Literal["input_text"], Literal["input_audio"], + Literal["input_image"] + :vartype type: str or str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar image_url: + :vartype image_url: str + :ivar detail: Is one of the following types: Literal["auto"], Literal["low"], Literal["high"] + :vartype detail: str or str or str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["input_text", "input_audio", "input_image"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"input_text\"], Literal[\"input_audio\"], + Literal[\"input_image\"]""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + detail: Optional[Literal["auto", "low", "high"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"low\"], Literal[\"high\"]""" + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["input_text", "input_audio", "input_image"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + image_url: Optional[str] = None, + detail: Optional[Literal["auto", "low", "high"]] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeFunctionTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Function tool. + + :ivar type: The type of the tool, i.e. ``function``. Default value is "function". + :vartype type: str + :ivar name: The name of the function. + :vartype name: str + :ivar description: The description of the function, including guidance on when and how to call + it, and guidance about what to tell the user when calling (if anything). + :vartype description: str + :ivar parameters: Parameters of the function in JSON Schema. + :vartype parameters: ~azure.ai.projects.models.RealtimeFunctionToolParameters + """ + + type: Optional[Literal["function"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The type of the tool, i.e. ``function``. Default value is \"function\".""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The description of the function, including guidance on when and how to call it, and guidance + about what to tell the user when calling (if anything).""" + parameters: Optional["_models.RealtimeFunctionToolParameters"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Parameters of the function in JSON Schema.""" + + @overload + def __init__( + self, + *, + type: Optional[Literal["function"]] = None, + name: Optional[str] = None, + description: Optional[str] = None, + parameters: Optional["_models.RealtimeFunctionToolParameters"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeFunctionToolParameters(_Model): + """RealtimeFunctionToolParameters.""" + + +class RealtimeMCPApprovalRequest( + RealtimeConversationItem, discriminator="mcp_approval_request" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP approval request. + + :ivar type: The type of the item. Always ``mcp_approval_request``. Required. + MCP_APPROVAL_REQUEST. + :vartype type: str or ~azure.ai.projects.models.MCP_APPROVAL_REQUEST + :ivar id: The unique ID of the approval request. Required. + :vartype id: str + :ivar server_label: The label of the MCP server making the request. Required. + :vartype server_label: str + :ivar name: The name of the tool to run. Required. + :vartype name: str + :ivar arguments: A JSON string of arguments for the tool. Required. + :vartype arguments: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_REQUEST] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_approval_request``. Required. MCP_APPROVAL_REQUEST.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the approval request. Required.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server making the request. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool to run. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A JSON string of arguments for the tool. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + server_label: str, + name: str, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_APPROVAL_REQUEST # type: ignore + + +class RealtimeMCPApprovalResponse( + RealtimeConversationItem, discriminator="mcp_approval_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP approval response. + + :ivar type: The type of the item. Always ``mcp_approval_response``. Required. + MCP_APPROVAL_RESPONSE. + :vartype type: str or ~azure.ai.projects.models.MCP_APPROVAL_RESPONSE + :ivar id: The unique ID of the approval response. Required. + :vartype id: str + :ivar approval_request_id: The ID of the approval request being answered. Required. + :vartype approval_request_id: str + :ivar approve: Whether the request was approved. Required. + :vartype approve: bool + :ivar reason: + :vartype reason: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_RESPONSE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_approval_response``. Required. MCP_APPROVAL_RESPONSE.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the approval response. Required.""" + approval_request_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the approval request being answered. Required.""" + approve: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the request was approved. Required.""" + reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + approval_request_id: str, + approve: bool, + reason: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_APPROVAL_RESPONSE # type: ignore + + +class RealtimeMCPError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeMCPError. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeMCPHTTPError, RealtimeMCPProtocolError, RealtimeMCPToolExecutionError + + :ivar type: Required. Known values are: "protocol_error", "tool_execution_error", and + "http_error". + :vartype type: str or ~azure.ai.projects.models.RealtimeMcpErrorType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"protocol_error\", \"tool_execution_error\", and \"http_error\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeMCPHTTPError( + RealtimeMCPError, discriminator="http_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP HTTP error. + + :ivar type: Required. HTTP_ERROR. + :vartype type: str or ~azure.ai.projects.models.HTTP_ERROR + :ivar code: Required. + :vartype code: int + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.HTTP_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. HTTP_ERROR.""" + code: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + code: int, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.HTTP_ERROR # type: ignore + + +class RealtimeMCPListTools( + RealtimeConversationItem, discriminator="mcp_list_tools" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP list tools. + + :ivar type: The type of the item. Always ``mcp_list_tools``. Required. MCP_LIST_TOOLS. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS + :ivar id: The unique ID of the list. + :vartype id: str + :ivar server_label: The label of the MCP server. Required. + :vartype server_label: str + :ivar tools: The tools available on the server. Required. + :vartype tools: list[~azure.ai.projects.models.MCPListToolsTool] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_LIST_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_list_tools``. Required. MCP_LIST_TOOLS.""" + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the list.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server. Required.""" + tools: list["_models.MCPListToolsTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The tools available on the server. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + server_label: str, + tools: list["_models.MCPListToolsTool"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_LIST_TOOLS # type: ignore + + +class RealtimeMCPProtocolError( + RealtimeMCPError, discriminator="protocol_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP protocol error. + + :ivar type: Required. PROTOCOL_ERROR. + :vartype type: str or ~azure.ai.projects.models.PROTOCOL_ERROR + :ivar code: Required. + :vartype code: int + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.PROTOCOL_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. PROTOCOL_ERROR.""" + code: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + code: int, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.PROTOCOL_ERROR # type: ignore + + +class RealtimeMCPToolCall( + RealtimeConversationItem, discriminator="mcp_call" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP tool call. + + :ivar type: The type of the item. Always ``mcp_call``. Required. MCP_CALL. + :vartype type: str or ~azure.ai.projects.models.MCP_CALL + :ivar id: The unique ID of the tool call. Required. + :vartype id: str + :ivar server_label: The label of the MCP server running the tool. Required. + :vartype server_label: str + :ivar name: The name of the tool that was run. Required. + :vartype name: str + :ivar arguments: A JSON string of the arguments passed to the tool. Required. + :vartype arguments: str + :ivar approval_request_id: + :vartype approval_request_id: str + :ivar output: + :vartype output: str + :ivar error: + :vartype error: ~azure.ai.projects.models.RealtimeMCPError + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_CALL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_call``. Required. MCP_CALL.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the tool call. Required.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server running the tool. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool that was run. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A JSON string of the arguments passed to the tool. Required.""" + approval_request_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + error: Optional["_models.RealtimeMCPError"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + server_label: str, + name: str, + arguments: str, + approval_request_id: Optional[str] = None, + output: Optional[str] = None, + error: Optional["_models.RealtimeMCPError"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_CALL # type: ignore + + +class RealtimeMCPToolExecutionError( + RealtimeMCPError, discriminator="tool_execution_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP tool execution error. + + :ivar type: Required. TOOL_EXECUTION_ERROR. + :vartype type: str or ~azure.ai.projects.models.TOOL_EXECUTION_ERROR + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.TOOL_EXECUTION_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. TOOL_EXECUTION_ERROR.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.TOOL_EXECUTION_ERROR # type: ignore + + +class RealtimeReasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime reasoning configuration. + + :ivar effort: Known values are: "minimal", "low", "medium", "high", and "xhigh". + :vartype effort: str or ~azure.ai.projects.models.RealtimeReasoningEffort + """ + + effort: Optional[Union[str, "_models.RealtimeReasoningEffort"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"minimal\", \"low\", \"medium\", \"high\", and \"xhigh\".""" + + @overload + def __init__( + self, + *, + effort: Optional[Union[str, "_models.RealtimeReasoningEffort"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseStatusDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseStatusDetails. + + :ivar type: Is one of the following types: Literal["completed"], Literal["cancelled"], + Literal["failed"], Literal["incomplete"] + :vartype type: str or str or str or str + :ivar reason: Is one of the following types: Literal["turn_detected"], + Literal["client_cancelled"], Literal["max_output_tokens"], Literal["content_filter"] + :vartype reason: str or str or str or str + :ivar error: + :vartype error: ~azure.ai.projects.models.RealtimeResponseStatusDetailsError + """ + + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"completed\"], Literal[\"cancelled\"], + Literal[\"failed\"], Literal[\"incomplete\"]""" + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"turn_detected\"], Literal[\"client_cancelled\"], + Literal[\"max_output_tokens\"], Literal[\"content_filter\"]""" + error: Optional["_models.RealtimeResponseStatusDetailsError"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] = None, + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] = None, + error: Optional["_models.RealtimeResponseStatusDetailsError"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseStatusDetailsError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseStatusDetailsError. + + :ivar type: + :vartype type: str + :ivar code: + :vartype code: str + """ + + type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[str] = None, + code: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsage. + + :ivar total_tokens: + :vartype total_tokens: int + :ivar input_tokens: + :vartype input_tokens: int + :ivar output_tokens: + :vartype output_tokens: int + :ivar input_token_details: + :vartype input_token_details: ~azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails + :ivar output_token_details: + :vartype output_token_details: + ~azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails + """ + + total_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_token_details: Optional["_models.RealtimeResponseUsageInputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + output_token_details: Optional["_models.RealtimeResponseUsageOutputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + total_tokens: Optional[int] = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + input_token_details: Optional["_models.RealtimeResponseUsageInputTokenDetails"] = None, + output_token_details: Optional["_models.RealtimeResponseUsageOutputTokenDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageInputTokenDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageInputTokenDetails. + + :ivar cached_tokens: + :vartype cached_tokens: int + :ivar text_tokens: + :vartype text_tokens: int + :ivar image_tokens: + :vartype image_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + :ivar cached_tokens_details: + :vartype cached_tokens_details: + ~azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails + """ + + cached_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + cached_tokens_details: Optional["_models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + cached_tokens: Optional[int] = None, + text_tokens: Optional[int] = None, + image_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + cached_tokens_details: Optional["_models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageInputTokenDetailsCachedTokensDetails( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageInputTokenDetailsCachedTokensDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar image_tokens: + :vartype image_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + image_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageOutputTokenDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageOutputTokenDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A realtime server event. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeServerEventConversationItemAdded, RealtimeServerEventConversationItemCreated, + RealtimeServerEventConversationItemDeleted, RealtimeServerEventConversationItemDone, + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + RealtimeServerEventConversationItemRetrieved, RealtimeServerEventConversationItemTruncated, + RealtimeServerEventInputAudioBufferCleared, RealtimeServerEventInputAudioBufferCommitted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventInputAudioBufferSpeechStopped, + RealtimeServerEventInputAudioBufferTimeoutTriggered, RealtimeServerEventMCPListToolsCompleted, + RealtimeServerEventMCPListToolsFailed, RealtimeServerEventMCPListToolsInProgress, + RealtimeServerEventOutputAudioBufferCleared, RealtimeServerEventRateLimitsUpdated, + VoiceAgentServerEventResponseAnimationBlendshapesDelta, + VoiceAgentServerEventResponseAnimationBlendshapesDone, + VoiceAgentServerEventResponseAnimationVisemeDelta, + VoiceAgentServerEventResponseAnimationVisemeDone, + VoiceAgentServerEventResponseAudioTimestampDelta, + VoiceAgentServerEventResponseAudioTimestampDone, RealtimeServerEventResponseContentPartAdded, + RealtimeServerEventResponseContentPartDone, RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, RealtimeServerEventResponseFunctionCallArgumentsDelta, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseMCPCallCompleted, RealtimeServerEventResponseMCPCallFailed, + RealtimeServerEventResponseMCPCallInProgress, RealtimeServerEventResponseMCPCallArgumentsDelta, + RealtimeServerEventResponseMCPCallArgumentsDone, RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioDone, RealtimeServerEventResponseAudioTranscriptDelta, + RealtimeServerEventResponseAudioTranscriptDone, RealtimeServerEventResponseOutputItemAdded, + RealtimeServerEventResponseOutputItemDone, RealtimeServerEventResponseTextDelta, + RealtimeServerEventResponseTextDone, VoiceAgentServerEventResponseVideoDelta, + VoiceAgentServerEventRtcCallError, VoiceAgentServerEventRtcCallSdpCreated, + VoiceAgentServerEventSessionAvatarConnecting, VoiceAgentServerEventSessionAvatarSwitchToIdle, + VoiceAgentServerEventSessionAvatarSwitchToSpeaking, RealtimeServerEventSessionCreated, + VoiceAgentServerEventSessionSubagentAborted, VoiceAgentServerEventSessionSubagentCompleted, + VoiceAgentServerEventSessionSubagentStarted, RealtimeServerEventSessionUpdated, + VoiceAgentServerEventWarning + + :ivar type: Required. Known values are: "conversation.created", "conversation.item.created", + "conversation.item.deleted", "conversation.item.input_audio_transcription.completed", + "conversation.item.input_audio_transcription.delta", + "conversation.item.input_audio_transcription.failed", "conversation.item.retrieved", + "conversation.item.truncated", "error", "input_audio_buffer.cleared", + "input_audio_buffer.committed", "input_audio_buffer.dtmf_event_received", + "input_audio_buffer.speech_started", "input_audio_buffer.speech_stopped", + "rate_limits.updated", "response.output_audio.delta", "response.output_audio.done", + "response.output_audio_transcript.delta", "response.output_audio_transcript.done", + "response.content_part.added", "response.content_part.done", "response.created", + "response.done", "response.function_call_arguments.delta", + "response.function_call_arguments.done", "response.output_item.added", + "response.output_item.done", "response.output_text.delta", "response.output_text.done", + "session.created", "session.updated", "output_audio_buffer.started", + "output_audio_buffer.stopped", "output_audio_buffer.cleared", "conversation.item.added", + "conversation.item.done", "input_audio_buffer.timeout_triggered", + "conversation.item.input_audio_transcription.segment", "mcp_list_tools.in_progress", + "mcp_list_tools.completed", "mcp_list_tools.failed", "response.mcp_call_arguments.delta", + "response.mcp_call_arguments.done", "response.mcp_call.in_progress", + "response.mcp_call.completed", "response.mcp_call.failed", "warning", + "session.subagent.started", "session.subagent.completed", "session.subagent.aborted", + "session.avatar.connecting", "session.avatar.switch_to_speaking", + "session.avatar.switch_to_idle", "rtc.call.sdp.created", "rtc.call.error", + "response.audio_timestamp.delta", "response.audio_timestamp.done", + "response.animation_blendshapes.delta", "response.animation_blendshapes.done", + "response.animation_viseme.delta", "response.animation_viseme.done", and + "response.video.delta". + :vartype type: str or ~azure.ai.projects.models.RealtimeServerEventType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"conversation.created\", \"conversation.item.created\", + \"conversation.item.deleted\", \"conversation.item.input_audio_transcription.completed\", + \"conversation.item.input_audio_transcription.delta\", + \"conversation.item.input_audio_transcription.failed\", \"conversation.item.retrieved\", + \"conversation.item.truncated\", \"error\", \"input_audio_buffer.cleared\", + \"input_audio_buffer.committed\", \"input_audio_buffer.dtmf_event_received\", + \"input_audio_buffer.speech_started\", \"input_audio_buffer.speech_stopped\", + \"rate_limits.updated\", \"response.output_audio.delta\", \"response.output_audio.done\", + \"response.output_audio_transcript.delta\", \"response.output_audio_transcript.done\", + \"response.content_part.added\", \"response.content_part.done\", \"response.created\", + \"response.done\", \"response.function_call_arguments.delta\", + \"response.function_call_arguments.done\", \"response.output_item.added\", + \"response.output_item.done\", \"response.output_text.delta\", \"response.output_text.done\", + \"session.created\", \"session.updated\", \"output_audio_buffer.started\", + \"output_audio_buffer.stopped\", \"output_audio_buffer.cleared\", \"conversation.item.added\", + \"conversation.item.done\", \"input_audio_buffer.timeout_triggered\", + \"conversation.item.input_audio_transcription.segment\", \"mcp_list_tools.in_progress\", + \"mcp_list_tools.completed\", \"mcp_list_tools.failed\", \"response.mcp_call_arguments.delta\", + \"response.mcp_call_arguments.done\", \"response.mcp_call.in_progress\", + \"response.mcp_call.completed\", \"response.mcp_call.failed\", \"warning\", + \"session.subagent.started\", \"session.subagent.completed\", \"session.subagent.aborted\", + \"session.avatar.connecting\", \"session.avatar.switch_to_speaking\", + \"session.avatar.switch_to_idle\", \"rtc.call.sdp.created\", \"rtc.call.error\", + \"response.audio_timestamp.delta\", \"response.audio_timestamp.done\", + \"response.animation_blendshapes.delta\", \"response.animation_blendshapes.done\", + \"response.animation_viseme.delta\", \"response.animation_viseme.done\", and + \"response.video.delta\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventConversationItemAdded( + RealtimeServerEvent, discriminator="conversation.item.added" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Sent by the server when an Item is added to the default Conversation. This can happen in + several cases: + + * When the client sends a `conversation.item.create` event. + * When the input audio buffer is committed. In this case the item will be a user message + containing the audio from the buffer. + * When the model is generating a Response. In this case the `conversation.item.added` event + will be sent when the model starts generating a specific Item, and thus it will not yet have + any content (and `status` will be `in_progress`). + + The event will include the full content of the Item (except when model is generating a + Response) except for audio data, which can be retrieved separately with a + `conversation.item.retrieve` event if necessary. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.added``. Required. + CONVERSATION_ITEM_ADDED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_ADDED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.added``. Required. CONVERSATION_ITEM_ADDED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_ADDED # type: ignore + + +class RealtimeServerEventConversationItemCreated( + RealtimeServerEvent, discriminator="conversation.item.created" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a conversation item is created. There are several scenarios that produce this + event: + + * The server is generating a Response, which if successful will produce + either one or two Items, which will be of type `message` + (role `assistant`) or type `function_call`. + * The input audio buffer has been committed, either by the client or the + server (in `server_vad` mode). The server will take the content of the + input audio buffer and add it to a new user message Item. + * The client has sent a `conversation.item.create` event to add a new Item + to the Conversation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.created``. Required. + CONVERSATION_ITEM_CREATED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_CREATED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.created``. Required. CONVERSATION_ITEM_CREATED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_CREATED # type: ignore + + +class RealtimeServerEventConversationItemDeleted( + RealtimeServerEvent, discriminator="conversation.item.deleted" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an item in the conversation is deleted by the client with a + ``conversation.item.delete`` event. This event is used to synchronize the server's + understanding of the conversation history with the client's view. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.deleted``. Required. + CONVERSATION_ITEM_DELETED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DELETED + :ivar item_id: The ID of the item that was deleted. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DELETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.deleted``. Required. CONVERSATION_ITEM_DELETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item that was deleted. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_DELETED # type: ignore + + +class RealtimeServerEventConversationItemDone( + RealtimeServerEvent, discriminator="conversation.item.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a conversation item is finalized. The event will include the full content of the + Item except for audio data, which can be retrieved separately with a + ``conversation.item.retrieve`` event if needed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.done``. Required. + CONVERSATION_ITEM_DONE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DONE + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.done``. Required. CONVERSATION_ITEM_DONE.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_DONE # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionCompleted( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """This event is the output of audio transcription for user audio written to the user audio + buffer. Transcription begins when the input audio buffer is committed by the client or server + (when VAD is enabled). Transcription runs asynchronously with Response creation, so this event + may come before or after the Response events. Realtime API models accept audio natively, and + thus input transcription is a separate process run on a separate ASR (Automatic Speech + Recognition) model. The transcript may diverge somewhat from the model's interpretation, and + should be treated as a rough guide. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.completed``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED + :ivar item_id: The ID of the item containing the audio that is being transcribed. Required. + :vartype item_id: str + :ivar content_index: The index of the content part containing the audio. Required. + :vartype content_index: int + :ivar transcript: The transcribed text. Required. + :vartype transcript: str + :ivar languages: The languages detected in the audio. Returned by ``gpt-transcribe``. An empty + array indicates that no language could be reliably detected. + :vartype languages: list[~azure.ai.projects.models.TranscriptionLanguage] + :ivar logprobs: + :vartype logprobs: list[~azure.ai.projects.models.LogProbProperties] + :ivar usage: Usage statistics for the transcription, this is billed according to the ASR + model's pricing rather than the realtime model's pricing. Required. Is either a + TranscriptTextUsageTokens type or a TranscriptTextUsageDuration type. + :vartype usage: ~azure.ai.projects.models.TranscriptTextUsageTokens or + ~azure.ai.projects.models.TranscriptTextUsageDuration + :ivar phrases: Phrase-level transcription timing and confidence details. + :vartype phrases: list[~azure.ai.projects.models.VoiceAgentTranscriptionPhrase] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.completed``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the audio that is being transcribed. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part containing the audio. Required.""" + transcript: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed text. Required.""" + languages: Optional[list["_models.TranscriptionLanguage"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The languages detected in the audio. Returned by ``gpt-transcribe``. An empty array indicates + that no language could be reliably detected.""" + logprobs: Optional[list["_models.LogProbProperties"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + usage: Union["_models.TranscriptTextUsageTokens", "_models.TranscriptTextUsageDuration"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the transcription, this is billed according to the ASR model's pricing + rather than the realtime model's pricing. Required. Is either a TranscriptTextUsageTokens type + or a TranscriptTextUsageDuration type.""" + phrases: Optional[list["_models.VoiceAgentTranscriptionPhrase"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Phrase-level transcription timing and confidence details.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + transcript: str, + usage: Union["_models.TranscriptTextUsageTokens", "_models.TranscriptTextUsageDuration"], + languages: Optional[list["_models.TranscriptionLanguage"]] = None, + logprobs: Optional[list["_models.LogProbProperties"]] = None, + phrases: Optional[list["_models.VoiceAgentTranscriptionPhrase"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionDelta( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the text value of an input audio transcription content part is updated with + incremental transcription results. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.delta``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA + :ivar item_id: The ID of the item containing the audio that is being transcribed. Required. + :vartype item_id: str + :ivar content_index: The index of the content part in the item's content array. + :vartype content_index: int + :ivar delta: The text delta. + :vartype delta: str + :ivar logprobs: + :vartype logprobs: list[~azure.ai.projects.models.LogProbProperties] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.delta``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the audio that is being transcribed. Required.""" + content_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array.""" + delta: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text delta.""" + logprobs: Optional[list["_models.LogProbProperties"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: Optional[int] = None, + delta: Optional[str] = None, + logprobs: Optional[list["_models.LogProbProperties"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionFailed( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.failed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when input audio transcription is configured, and a transcription request for a user + message failed. These events are separate from other ``error`` events so that the client can + identify the related Item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.failed``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED + :ivar item_id: The ID of the user message item. Required. + :vartype item_id: str + :ivar content_index: The index of the content part containing the audio. Required. + :vartype content_index: int + :ivar error: Details of the transcription error. Required. + :vartype error: + ~azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.failed``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part containing the audio. Required.""" + error: "_models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details of the transcription error. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + error: "_models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionFailedError( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventConversationItemInputAudioTranscriptionFailedError. + + :ivar type: + :vartype type: str + :ivar code: + :vartype code: str + :ivar message: + :vartype message: str + :ivar param: + :vartype param: str + """ + + type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[str] = None, + code: Optional[str] = None, + message: Optional[str] = None, + param: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventConversationItemInputAudioTranscriptionSegment( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.segment" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an input audio transcription segment is identified for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.segment``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT + :ivar item_id: The ID of the item containing the input audio content. Required. + :vartype item_id: str + :ivar content_index: The index of the input audio content part within the item. Required. + :vartype content_index: int + :ivar text: The text for this segment. Required. + :vartype text: str + :ivar id: The segment identifier. Required. + :vartype id: str + :ivar speaker: The detected speaker label for this segment. Required. + :vartype speaker: str + :ivar start: Start time of the segment in seconds. Required. + :vartype start: float + :ivar end: End time of the segment in seconds. Required. + :vartype end: float + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.segment``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the input audio content. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the input audio content part within the item. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text for this segment. Required.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The segment identifier. Required.""" + speaker: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The detected speaker label for this segment. Required.""" + start: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Start time of the segment in seconds. Required.""" + end: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """End time of the segment in seconds. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + text: str, + id: str, # pylint: disable=redefined-builtin + speaker: str, + start: float, + end: float, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT # type: ignore + + +class RealtimeServerEventConversationItemRetrieved( + RealtimeServerEvent, discriminator="conversation.item.retrieved" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a conversation item is retrieved with ``conversation.item.retrieve``. This is + provided as a way to fetch the server's representation of an item, for example to get access to + the post-processed audio data after noise cancellation and VAD. It includes the full content of + the Item, including audio data. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.retrieved``. Required. + CONVERSATION_ITEM_RETRIEVED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_RETRIEVED + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.retrieved``. Required. CONVERSATION_ITEM_RETRIEVED.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED # type: ignore + + +class RealtimeServerEventConversationItemTruncated( + RealtimeServerEvent, discriminator="conversation.item.truncated" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an earlier assistant audio message item is truncated by the client with a + ``conversation.item.truncate`` event. This event is used to synchronize the server's + understanding of the audio with the client's playback. This action will truncate the audio and + remove the server-side text transcript to ensure there is no text in the context that hasn't + been heard by the user. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.truncated``. Required. + CONVERSATION_ITEM_TRUNCATED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_TRUNCATED + :ivar item_id: The ID of the assistant message item that was truncated. Required. + :vartype item_id: str + :ivar content_index: The index of the content part that was truncated. Required. + :vartype content_index: int + :ivar audio_end_ms: The duration up to which the audio was truncated, in milliseconds. + Required. + :vartype audio_end_ms: int + :ivar item: The assistant message after truncation, when the service returns the updated item. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.truncated``. Required. CONVERSATION_ITEM_TRUNCATED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the assistant message item that was truncated. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part that was truncated. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The duration up to which the audio was truncated, in milliseconds. Required.""" + item: Optional["_models.RealtimeConversationItem"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The assistant message after truncation, when the service returns the updated item.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + audio_end_ms: int, + item: Optional["_models.RealtimeConversationItem"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED # type: ignore + + +class RealtimeServerEventError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when an error occurs, which could be a client problem or a server problem. Most errors + are recoverable and the session will stay open, we recommend to implementors to monitor and log + error messages by default. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``error``. Required. Default value is "error". + :vartype type: str + :ivar error: Details of the error. Required. + :vartype error: ~azure.ai.projects.models.RealtimeServerEventErrorError + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal["error"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The event type, must be ``error``. Required. Default value is \"error\".""" + error: "_models.RealtimeServerEventErrorError" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details of the error. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + error: "_models.RealtimeServerEventErrorError", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type: Literal["error"] = "error" + + +class RealtimeServerEventErrorError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeServerEventErrorError. + + :ivar type: Required. + :vartype type: str + :ivar code: + :vartype code: str + :ivar message: Required. + :vartype message: str + :ivar param: + :vartype param: str + :ivar event_id: + :vartype event_id: str + """ + + type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: str, + message: str, + code: Optional[str] = None, + param: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventInputAudioBufferCleared( + RealtimeServerEvent, discriminator="input_audio_buffer.cleared" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the input audio buffer is cleared by the client with a + ``input_audio_buffer.clear`` event. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.cleared``. Required. + INPUT_AUDIO_BUFFER_CLEARED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_CLEARED + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.cleared``. Required. INPUT_AUDIO_BUFFER_CLEARED.""" + + @overload + def __init__( + self, + *, + event_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED # type: ignore + + +class RealtimeServerEventInputAudioBufferCommitted( + RealtimeServerEvent, discriminator="input_audio_buffer.committed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an input audio buffer is committed, either by the client or automatically in + server VAD mode. The ``item_id`` property is the ID of the user message item that will be + created, thus a ``conversation.item.created`` event will also be sent to the client. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.committed``. Required. + INPUT_AUDIO_BUFFER_COMMITTED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_COMMITTED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item_id: The ID of the user message item that will be created. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.committed``. Required. + INPUT_AUDIO_BUFFER_COMMITTED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED # type: ignore + + +class RealtimeServerEventInputAudioBufferSpeechStarted( + RealtimeServerEvent, discriminator="input_audio_buffer.speech_started" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Sent by the server when in ``server_vad`` mode to indicate that speech has been detected in the + audio buffer. This can happen any time audio is added to the buffer (unless speech is already + detected). The client may want to use this event to interrupt audio playback or provide visual + feedback to the user. The client should expect to receive a + ``input_audio_buffer.speech_stopped`` event when speech stops. The ``item_id`` property is the + ID of the user message item that will be created when speech stops and will also be included in + the ``input_audio_buffer.speech_stopped`` event (unless the client manually commits the audio + buffer during VAD activation). + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.speech_started``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STARTED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_SPEECH_STARTED + :ivar audio_start_ms: Milliseconds from the start of all audio written to the buffer during the + session when speech was first detected. This will correspond to the beginning of audio sent to + the model, and thus includes the ``prefix_padding_ms`` configured in the Session. Required. + :vartype audio_start_ms: int + :ivar item_id: The ID of the user message item that will be created when speech stops. + Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.speech_started``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STARTED.""" + audio_start_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Milliseconds from the start of all audio written to the buffer during the session when speech + was first detected. This will correspond to the beginning of audio sent to the model, and thus + includes the ``prefix_padding_ms`` configured in the Session. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created when speech stops. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_start_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED # type: ignore + + +class RealtimeServerEventInputAudioBufferSpeechStopped( + RealtimeServerEvent, discriminator="input_audio_buffer.speech_stopped" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned in ``server_vad`` mode when the server detects the end of speech in the audio buffer. + The server will also send an ``conversation.item.created`` event with the user message item + that is created from the audio buffer. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.speech_stopped``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STOPPED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_SPEECH_STOPPED + :ivar audio_end_ms: Milliseconds since the session started when speech stopped. This will + correspond to the end of audio sent to the model, and thus includes the + ``min_silence_duration_ms`` configured in the Session. Required. + :vartype audio_end_ms: int + :ivar item_id: The ID of the user message item that will be created. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.speech_stopped``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STOPPED.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Milliseconds since the session started when speech stopped. This will correspond to the end of + audio sent to the model, and thus includes the ``min_silence_duration_ms`` configured in the + Session. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_end_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED # type: ignore + + +class RealtimeServerEventInputAudioBufferTimeoutTriggered( + RealtimeServerEvent, discriminator="input_audio_buffer.timeout_triggered" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the Server VAD timeout is triggered for the input audio buffer. This is + configured with ``idle_timeout_ms`` in the ``turn_detection`` settings of the session, and it + indicates that there hasn't been any speech detected for the configured duration. The + ``audio_start_ms`` and ``audio_end_ms`` fields indicate the segment of audio after the last + model response up to the triggering time, as an offset from the beginning of audio written to + the input audio buffer. This means it demarcates the segment of audio that was silent and the + difference between the start and end values will roughly match the configured timeout. The + empty audio will be committed to the conversation as an ``input_audio`` item (there will be a + ``input_audio_buffer.committed`` event) and a model response will be generated. There may be + speech that didn't trigger VAD but is still detected by the model, so the model may respond + with something relevant to the conversation or a prompt to continue speaking. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.timeout_triggered``. Required. + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED + :ivar audio_start_ms: Millisecond offset of audio written to the input audio buffer that was + after the playback time of the last model response. Required. + :vartype audio_start_ms: int + :ivar audio_end_ms: Millisecond offset of audio written to the input audio buffer at the time + the timeout was triggered. Required. + :vartype audio_end_ms: int + :ivar item_id: The ID of the item associated with this segment. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.timeout_triggered``. Required. + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED.""" + audio_start_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Millisecond offset of audio written to the input audio buffer that was after the playback time + of the last model response. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Millisecond offset of audio written to the input audio buffer at the time the timeout was + triggered. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item associated with this segment. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_start_ms: int, + audio_end_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED # type: ignore + + +class RealtimeServerEventMCPListToolsCompleted( + RealtimeServerEvent, discriminator="mcp_list_tools.completed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools has completed for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.completed``. Required. + MCP_LIST_TOOLS_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_COMPLETED + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.completed``. Required. MCP_LIST_TOOLS_COMPLETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED # type: ignore + + +class RealtimeServerEventMCPListToolsFailed( + RealtimeServerEvent, discriminator="mcp_list_tools.failed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools has failed for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.failed``. Required. MCP_LIST_TOOLS_FAILED. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_FAILED + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.failed``. Required. MCP_LIST_TOOLS_FAILED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_FAILED # type: ignore + + +class RealtimeServerEventMCPListToolsInProgress( + RealtimeServerEvent, discriminator="mcp_list_tools.in_progress" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools is in progress for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.in_progress``. Required. + MCP_LIST_TOOLS_IN_PROGRESS. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_IN_PROGRESS + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.in_progress``. Required. MCP_LIST_TOOLS_IN_PROGRESS.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS # type: ignore + + +class RealtimeServerEventOutputAudioBufferCleared( + RealtimeServerEvent, discriminator="output_audio_buffer.cleared" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """**WebRTC/SIP Only:** Emitted when the output audio buffer is cleared. This happens either in + VAD mode when the user has interrupted (``input_audio_buffer.speech_started``), or when the + client has emitted the ``output_audio_buffer.clear`` event to manually cut off the current + audio response. `Learn more + `_. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``output_audio_buffer.cleared``. Required. + OUTPUT_AUDIO_BUFFER_CLEARED. + :vartype type: str or ~azure.ai.projects.models.OUTPUT_AUDIO_BUFFER_CLEARED + :ivar response_id: The unique ID of the response that produced the audio. Required. + :vartype response_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``output_audio_buffer.cleared``. Required. OUTPUT_AUDIO_BUFFER_CLEARED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the response that produced the audio. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED # type: ignore + + +class RealtimeServerEventRateLimitsUpdated( + RealtimeServerEvent, discriminator="rate_limits.updated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Emitted at the beginning of a Response to indicate the updated rate limits. When a Response is + created some tokens will be "reserved" for the output tokens, the rate limits shown here + reflect that reservation, which is then adjusted accordingly once the Response is completed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``rate_limits.updated``. Required. RATE_LIMITS_UPDATED. + :vartype type: str or ~azure.ai.projects.models.RATE_LIMITS_UPDATED + :ivar rate_limits: List of rate limit information. Required. + :vartype rate_limits: + list[~azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RATE_LIMITS_UPDATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``rate_limits.updated``. Required. RATE_LIMITS_UPDATED.""" + rate_limits: list["_models.RealtimeServerEventRateLimitsUpdatedRateLimits"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """List of rate limit information. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + rate_limits: list["_models.RealtimeServerEventRateLimitsUpdatedRateLimits"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RATE_LIMITS_UPDATED # type: ignore + + +class RealtimeServerEventRateLimitsUpdatedRateLimits( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventRateLimitsUpdatedRateLimits. + + :ivar name: Is either a Literal["requests"] type or a Literal["tokens"] type. + :vartype name: str or str + :ivar limit: + :vartype limit: int + :ivar remaining: + :vartype remaining: int + :ivar reset_seconds: + :vartype reset_seconds: float + """ + + name: Optional[Literal["requests", "tokens"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a Literal[\"requests\"] type or a Literal[\"tokens\"] type.""" + limit: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + remaining: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + reset_seconds: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + name: Optional[Literal["requests", "tokens"]] = None, + limit: Optional[int] = None, + remaining: Optional[int] = None, + reset_seconds: Optional[float] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseAudioDelta( + RealtimeServerEvent, discriminator="response.output_audio.delta" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the model-generated audio is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio.delta``. Required. + RESPONSE_OUTPUT_AUDIO_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: Base64-encoded audio data delta. Required. + :vartype delta: bytes + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio.delta``. Required. RESPONSE_OUTPUT_AUDIO_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64") + """Base64-encoded audio data delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: bytes, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA # type: ignore + + +class RealtimeServerEventResponseAudioDone( + RealtimeServerEvent, discriminator="response.output_audio.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the model-generated audio is done. Also emitted when a Response is interrupted, + incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio.done``. Required. + RESPONSE_OUTPUT_AUDIO_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio.done``. Required. RESPONSE_OUTPUT_AUDIO_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE # type: ignore + + +class RealtimeServerEventResponseAudioTranscriptDelta( + RealtimeServerEvent, discriminator="response.output_audio_transcript.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated transcription of audio output is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio_transcript.delta``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: The transcript delta. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio_transcript.delta``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcript delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA # type: ignore + + +class RealtimeServerEventResponseAudioTranscriptDone( + RealtimeServerEvent, discriminator="response.output_audio_transcript.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated transcription of audio output is done streaming. Also emitted + when a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio_transcript.done``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar transcript: The final transcript of the audio. Required. + :vartype transcript: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio_transcript.done``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + transcript: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final transcript of the audio. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + transcript: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE # type: ignore + + +class RealtimeServerEventResponseContentPartAdded( + RealtimeServerEvent, discriminator="response.content_part.added" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a new content part is added to an assistant message item during response + generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.content_part.added``. Required. + RESPONSE_CONTENT_PART_ADDED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CONTENT_PART_ADDED + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item to which the content part was added. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar part: The content part that was added. Required. + :vartype part: ~azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.content_part.added``. Required. RESPONSE_CONTENT_PART_ADDED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to which the content part was added. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + part: "_models.RealtimeServerEventResponseContentPartAddedPart" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content part that was added. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + part: "_models.RealtimeServerEventResponseContentPartAddedPart", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED # type: ignore + + +class RealtimeServerEventResponseContentPartAddedPart( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventResponseContentPartAddedPart. + + :ivar type: Is either a Literal["audio"] type or a Literal["text"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["audio", "text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Is either a Literal[\"audio\"] type or a Literal[\"text\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["audio", "text"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseContentPartDone( + RealtimeServerEvent, discriminator="response.content_part.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a content part is done streaming in an assistant message item. Also emitted when + a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.content_part.done``. Required. + RESPONSE_CONTENT_PART_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CONTENT_PART_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar part: The content part that is done. Required. + :vartype part: ~azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.content_part.done``. Required. RESPONSE_CONTENT_PART_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + part: "_models.RealtimeServerEventResponseContentPartDonePart" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content part that is done. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + part: "_models.RealtimeServerEventResponseContentPartDonePart", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE # type: ignore + + +class RealtimeServerEventResponseContentPartDonePart( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventResponseContentPartDonePart. + + :ivar type: Is either a Literal["audio"] type or a Literal["text"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + :ivar format: The audio format, when this is an audio content part. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + """ + + type: Optional[Literal["audio", "text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Is either a Literal[\"audio\"] type or a Literal[\"text\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio format, when this is an audio content part.""" + + @overload + def __init__( + self, + *, + type: Optional[Literal["audio", "text"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseCreated( + RealtimeServerEvent, discriminator="response.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a new Response is created. The first event of response creation, where the + response is in an initial state of ``in_progress``. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.created``. Required. RESPONSE_CREATED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CREATED + :ivar response: Required. + :vartype response: ~azure.ai.projects.models.VoiceAgentRealtimeResponse + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.created``. Required. RESPONSE_CREATED.""" + response: "_models.VoiceAgentRealtimeResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response: "_models.VoiceAgentRealtimeResponse", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CREATED # type: ignore + + +class RealtimeServerEventResponseDone( + RealtimeServerEvent, discriminator="response.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a Response is done streaming. Always emitted, no matter the final state. The + Response object included in the ``response.done`` event will include all output Items in the + Response but will omit the raw audio data. Clients should check the ``status`` field of the + Response to determine if it was successful (``completed``) or if there was another outcome: + ``cancelled``, ``failed``, or ``incomplete``. A response will contain all output items that + were generated during the response, excluding any audio content. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.done``. Required. RESPONSE_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_DONE + :ivar response: Required. + :vartype response: ~azure.ai.projects.models.VoiceAgentRealtimeResponse + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.done``. Required. RESPONSE_DONE.""" + response: "_models.VoiceAgentRealtimeResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response: "_models.VoiceAgentRealtimeResponse", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_DONE # type: ignore + + +class RealtimeServerEventResponseFunctionCallArgumentsDelta( + RealtimeServerEvent, discriminator="response.function_call_arguments.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated function call arguments are updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.function_call_arguments.delta``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the function call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar call_id: The ID of the function call. Required. + :vartype call_id: str + :ivar delta: The arguments delta as a JSON string. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.function_call_arguments.delta``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The arguments delta as a JSON string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + call_id: str, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA # type: ignore + + +class RealtimeServerEventResponseFunctionCallArgumentsDone( + RealtimeServerEvent, discriminator="response.function_call_arguments.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated function call arguments are done streaming. Also emitted when + a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.function_call_arguments.done``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the function call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar call_id: The ID of the function call. Required. + :vartype call_id: str + :ivar name: The name of the function that was called. Required. + :vartype name: str + :ivar arguments: The final arguments as a JSON string. Required. + :vartype arguments: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.function_call_arguments.done``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function that was called. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final arguments as a JSON string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + call_id: str, + name: str, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE # type: ignore + + +class RealtimeServerEventResponseMCPCallArgumentsDelta( + RealtimeServerEvent, discriminator="response.mcp_call_arguments.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when MCP tool call arguments are updated during response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call_arguments.delta``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_ARGUMENTS_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar delta: The JSON-encoded arguments delta. Required. + :vartype delta: str + :ivar obfuscation: + :vartype obfuscation: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call_arguments.delta``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON-encoded arguments delta. Required.""" + obfuscation: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + delta: str, + obfuscation: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA # type: ignore + + +class RealtimeServerEventResponseMCPCallArgumentsDone( + RealtimeServerEvent, discriminator="response.mcp_call_arguments.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when MCP tool call arguments are finalized during response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call_arguments.done``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_ARGUMENTS_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar arguments: The final JSON-encoded arguments string. Required. + :vartype arguments: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call_arguments.done``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final JSON-encoded arguments string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE # type: ignore + + +class RealtimeServerEventResponseMCPCallCompleted( + RealtimeServerEvent, discriminator="response.mcp_call.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has completed successfully. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.completed``. Required. + RESPONSE_MCP_CALL_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_COMPLETED + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.completed``. Required. RESPONSE_MCP_CALL_COMPLETED.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED # type: ignore + + +class RealtimeServerEventResponseMCPCallFailed( + RealtimeServerEvent, discriminator="response.mcp_call.failed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has failed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.failed``. Required. + RESPONSE_MCP_CALL_FAILED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_FAILED + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.failed``. Required. RESPONSE_MCP_CALL_FAILED.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED # type: ignore + + +class RealtimeServerEventResponseMCPCallInProgress( + RealtimeServerEvent, discriminator="response.mcp_call.in_progress" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has started and is in progress. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.in_progress``. Required. + RESPONSE_MCP_CALL_IN_PROGRESS. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_IN_PROGRESS + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.in_progress``. Required. + RESPONSE_MCP_CALL_IN_PROGRESS.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS # type: ignore + + +class RealtimeServerEventResponseOutputItemAdded( + RealtimeServerEvent, discriminator="response.output_item.added" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a new Item is created during Response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_item.added``. Required. + RESPONSE_OUTPUT_ITEM_ADDED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_ITEM_ADDED + :ivar response_id: The ID of the Response to which the item belongs. Required. + :vartype response_id: str + :ivar output_index: The index of the output item in the Response. Required. + :vartype output_index: int + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_item.added``. Required. RESPONSE_OUTPUT_ITEM_ADDED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the Response to which the item belongs. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the Response. Required.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + output_index: int, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED # type: ignore + + +class RealtimeServerEventResponseOutputItemDone( + RealtimeServerEvent, discriminator="response.output_item.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an Item is done streaming. Also emitted when a Response is interrupted, + incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_item.done``. Required. + RESPONSE_OUTPUT_ITEM_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_ITEM_DONE + :ivar response_id: The ID of the Response to which the item belongs. Required. + :vartype response_id: str + :ivar output_index: The index of the output item in the Response. Required. + :vartype output_index: int + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_item.done``. Required. RESPONSE_OUTPUT_ITEM_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the Response to which the item belongs. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the Response. Required.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + output_index: int, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE # type: ignore + + +class RealtimeServerEventResponseTextDelta( + RealtimeServerEvent, discriminator="response.output_text.delta" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the text value of an "output_text" content part is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_text.delta``. Required. + RESPONSE_OUTPUT_TEXT_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_TEXT_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: The text delta. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_text.delta``. Required. RESPONSE_OUTPUT_TEXT_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA # type: ignore + + +class RealtimeServerEventResponseTextDone( + RealtimeServerEvent, discriminator="response.output_text.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the text value of an "output_text" content part is done streaming. Also emitted + when a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_text.done``. Required. + RESPONSE_OUTPUT_TEXT_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_TEXT_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar text: The final text content. Required. + :vartype text: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_text.done``. Required. RESPONSE_OUTPUT_TEXT_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final text content. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + text: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE # type: ignore + + +class RealtimeServerEventSessionCreated( + RealtimeServerEvent, discriminator="session.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a Session is created. Emitted automatically when a new connection is established + as the first server event. This event will contain the default Session configuration. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``session.created``. Required. SESSION_CREATED. + :vartype type: str or ~azure.ai.projects.models.SESSION_CREATED + :ivar session: The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionResponseConfig + :ivar conversation_id: The session-scoped conversation id. When present, responses attached to + the session conversation use the same value in ``response.created`` and ``response.done``. + :vartype conversation_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.SESSION_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``session.created``. Required. SESSION_CREATED.""" + session: "_models.VoiceAgentSessionResponseConfig" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session-scoped conversation id. When present, responses attached to the session + conversation use the same value in ``response.created`` and ``response.done``.""" + + @overload + def __init__( + self, + *, + event_id: str, + session: "_models.VoiceAgentSessionResponseConfig", + conversation_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_CREATED # type: ignore + + +class RealtimeServerEventSessionUpdated( + RealtimeServerEvent, discriminator="session.updated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a session is updated with a ``session.update`` event, unless there is an error. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``session.updated``. Required. SESSION_UPDATED. + :vartype type: str or ~azure.ai.projects.models.SESSION_UPDATED + :ivar session: The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionResponseConfig + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.SESSION_UPDATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``session.updated``. Required. SESSION_UPDATED.""" + session: "_models.VoiceAgentSessionResponseConfig" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig""" + + @overload + def __init__( + self, + *, + event_id: str, + session: "_models.VoiceAgentSessionResponseConfig", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_UPDATED # type: ignore + + +class Reasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Reasoning. + + :ivar mode: Controls the reasoning execution mode for the request. When returned on a response, + this is the effective execution mode. Known values are: "standard" and "pro". + :vartype mode: str or ~azure.ai.projects.models.ReasoningModeEnum + :ivar effort: Known values are: "none", "minimal", "low", "medium", "high", "xhigh", and "max". + :vartype effort: str or ~azure.ai.projects.models.ReasoningEffort + :ivar summary: Is one of the following types: Literal["auto"], Literal["concise"], + Literal["detailed"] + :vartype summary: str or str or str + :ivar context: Is one of the following types: Literal["auto"], Literal["current_turn"], + Literal["all_turns"] + :vartype context: str or str or str + :ivar generate_summary: Is one of the following types: Literal["auto"], Literal["concise"], + Literal["detailed"] + :vartype generate_summary: str or str or str + """ + + mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls the reasoning execution mode for the request. When returned on a response, this is the + effective execution mode. Known values are: \"standard\" and \"pro\".""" + effort: Optional[Union[str, "_models.ReasoningEffort"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", and \"max\".""" + summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + context: Optional[Literal["auto", "current_turn", "all_turns"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"current_turn\"], + Literal[\"all_turns\"]""" + generate_summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + + @overload + def __init__( + self, + *, + mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = None, + effort: Optional[Union[str, "_models.ReasoningEffort"]] = None, + summary: Optional[Literal["auto", "concise", "detailed"]] = None, + context: Optional[Literal["auto", "current_turn", "all_turns"]] = None, + generate_summary: Optional[Literal["auto", "concise", "detailed"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RecurrenceTrigger( + Trigger, discriminator="Recurrence" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Recurrence based trigger. + + :ivar type: Type of the trigger. Required. Recurrence based trigger. + :vartype type: str or ~azure.ai.projects.models.RECURRENCE + :ivar start_time: Start time for the recurrence schedule in ISO 8601 format. + :vartype start_time: ~datetime.datetime + :ivar end_time: End time for the recurrence schedule in ISO 8601 format. + :vartype end_time: ~datetime.datetime + :ivar time_zone: Time zone for the recurrence schedule. Defaults to ``UTC``. + :vartype time_zone: str + :ivar interval: Interval for the recurrence schedule. Required. + :vartype interval: int + :ivar schedule: Recurrence schedule for the recurrence trigger. Required. + :vartype schedule: ~azure.ai.projects.models.RecurrenceSchedule + """ + + type: Literal[TriggerType.RECURRENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Type of the trigger. Required. Recurrence based trigger.""" + start_time: Optional[datetime.datetime] = rest_field( + name="startTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """Start time for the recurrence schedule in ISO 8601 format.""" + end_time: Optional[datetime.datetime] = rest_field( + name="endTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """End time for the recurrence schedule in ISO 8601 format.""" + time_zone: Optional[str] = rest_field(name="timeZone", visibility=["read", "create", "update", "delete", "query"]) + """Time zone for the recurrence schedule. Defaults to ``UTC``.""" + interval: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Interval for the recurrence schedule. Required.""" + schedule: "_models.RecurrenceSchedule" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Recurrence schedule for the recurrence trigger. Required.""" + + @overload + def __init__( + self, + *, + interval: int, + schedule: "_models.RecurrenceSchedule", + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, + time_zone: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TriggerType.RECURRENCE # type: ignore + + +class RedTeam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Red team details. + + :ivar name: Identifier of the red team run. Required. + :vartype name: str + :ivar display_name: Name of the red-team run. + :vartype display_name: str + :ivar num_turns: Number of simulation rounds. + :vartype num_turns: int + :ivar attack_strategies: List of attack strategies or nested lists of attack strategies. + :vartype attack_strategies: list[str or ~azure.ai.projects.models.AttackStrategy] + :ivar simulation_only: Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs + conversation not evaluation result. The service defaults to ``false`` if a value is not + specified by the caller. + :vartype simulation_only: bool + :ivar risk_categories: List of risk categories to generate attack objectives for. + :vartype risk_categories: list[str or ~azure.ai.projects.models.RiskCategory] + :ivar application_scenario: Application scenario for the red team operation, to generate + scenario specific attacks. + :vartype application_scenario: str + :ivar tags: Red team's tags. Unlike properties, tags are fully mutable. + :vartype tags: dict[str, str] + :ivar properties: Red team's properties. Unlike tags, properties are add-only. Once added, a + property cannot be removed. + :vartype properties: dict[str, str] + :ivar status: Status of the red-team. It is set by service and is read-only. + :vartype status: str + :ivar target: Target configuration for the red-team run. Required. + :vartype target: ~azure.ai.projects.models.RedTeamTargetConfig + """ + + name: str = rest_field(name="id", visibility=["read"]) + """Identifier of the red team run. Required.""" + display_name: Optional[str] = rest_field( + name="displayName", visibility=["read", "create", "update", "delete", "query"] + ) + """Name of the red-team run.""" + num_turns: Optional[int] = rest_field(name="numTurns", visibility=["read", "create", "update", "delete", "query"]) + """Number of simulation rounds.""" + attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = rest_field( + name="attackStrategies", visibility=["read", "create", "update", "delete", "query"] + ) + """List of attack strategies or nested lists of attack strategies.""" + simulation_only: Optional[bool] = rest_field( + name="simulationOnly", visibility=["read", "create", "update", "delete", "query"] + ) + """Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs conversation not + evaluation result. The service defaults to ``false`` if a value is not specified by the caller.""" + risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = rest_field( + name="riskCategories", visibility=["read", "create", "update", "delete", "query"] + ) + """List of risk categories to generate attack objectives for.""" + application_scenario: Optional[str] = rest_field( + name="applicationScenario", visibility=["read", "create", "update", "delete", "query"] + ) + """Application scenario for the red team operation, to generate scenario specific attacks.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Red team's tags. Unlike properties, tags are fully mutable.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Red team's properties. Unlike tags, properties are add-only. Once added, a property cannot be + removed.""" + status: Optional[str] = rest_field(visibility=["read"]) + """Status of the red-team. It is set by service and is read-only.""" + target: "_models.RedTeamTargetConfig" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Target configuration for the red-team run. Required.""" + + @overload + def __init__( + self, + *, + target: "_models.RedTeamTargetConfig", + display_name: Optional[str] = None, + num_turns: Optional[int] = None, + attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = None, + simulation_only: Optional[bool] = None, + risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = None, + application_scenario: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ReminderPreviewToolboxTool( + ToolboxTool, discriminator="reminder_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reminder tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: Required. REMINDER_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.REMINDER_PREVIEW + """ + + type: Literal[ToolboxToolType.REMINDER_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. REMINDER_PREVIEW.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.REMINDER_PREVIEW # type: ignore + + +class ResponsesProtocolConfiguration(_Model): + """Configuration specific to the responses protocol.""" + + +class ResponseUsageInputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """ResponseUsageInputTokensDetails. + + :ivar cached_tokens: Required. + :vartype cached_tokens: int + :ivar cache_write_tokens: Required. + :vartype cache_write_tokens: int + """ + + cached_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + cache_write_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + cached_tokens: int, + cache_write_tokens: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ResponseUsageOutputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """ResponseUsageOutputTokensDetails. + + :ivar reasoning_tokens: Required. + :vartype reasoning_tokens: int + """ + + reasoning_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + reasoning_tokens: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class Routine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A routine definition returned by the service. + + :ivar name: The routine name. + :vartype name: str + :ivar description: A human-readable description of the routine. + :vartype description: str + :ivar enabled: Whether the routine is enabled. Required. + :vartype enabled: bool + :ivar triggers: The triggers configured for the routine. + :vartype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :ivar action: The action executed when the routine fires. + :vartype action: ~azure.ai.projects.models.RoutineAction + :ivar created_at: The time when the routine was created. + :vartype created_at: ~datetime.datetime + :ivar updated_at: The time when the routine was last updated. + :vartype updated_at: ~datetime.datetime + """ + + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The routine name.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the routine.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the routine is enabled. Required.""" + triggers: Optional[dict[str, "_models.RoutineTrigger"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The triggers configured for the routine.""" + action: Optional["_models.RoutineAction"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The action executed when the routine fires.""" + created_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the routine was created.""" + updated_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the routine was last updated.""" + + @overload + def __init__( + self, + *, + enabled: bool, + name: Optional[str] = None, + description: Optional[str] = None, + triggers: Optional[dict[str, "_models.RoutineTrigger"]] = None, + action: Optional["_models.RoutineAction"] = None, + created_at: Optional[datetime.datetime] = None, + updated_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoutineAuthorization(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Optional authorization configuration for a routine dispatch. + + :ivar identity: The identity used when dispatching the routine. Defaults to agent when omitted; + set to creator only when the customer opts in to creator identity dispatch. Known values are: + "agent" and "creator". + :vartype identity: str or ~azure.ai.projects.models.RoutineDispatchIdentity + """ + + identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The identity used when dispatching the routine. Defaults to agent when omitted; set to creator + only when the customer opts in to creator identity dispatch. Known values are: \"agent\" and + \"creator\".""" + + @overload + def __init__( + self, + *, + identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoutineRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single routine run returned from the run history API. + + :ivar id: The unique run identifier for the routine attempt. Required. + :vartype id: str + :ivar status: The run status. Is one of the following types: str + :vartype status: str + :ivar phase: The AgentExtensions lifecycle phase for the routine attempt. Known values are: + "queued", "dispatching", "completed", and "failed". + :vartype phase: str or ~azure.ai.projects.models.RoutineRunPhase + :ivar trigger_type: The trigger type that produced the routine attempt. Known values are: + "custom", "github_issue", "schedule", and "timer". + :vartype trigger_type: str or ~azure.ai.projects.models.RoutineTriggerType + :ivar trigger_name: The configured trigger name that produced the routine attempt. + :vartype trigger_name: str + :ivar trigger_event_payload: The event payload captured from the event that triggered the + routine attempt, when available. + :vartype trigger_event_payload: dict[str, any] + :ivar attempt_source: The source path that created the routine attempt. Known values are: + "event_fire", "manual_dispatch", "queued_dispatch", "schedule_delivery", and "timer_delivery". + :vartype attempt_source: str or ~azure.ai.projects.models.RoutineAttemptSource + :ivar action_type: The action type dispatched for the routine attempt. Known values are: + "invoke_agent_responses_api" and "invoke_agent_invocations_api". + :vartype action_type: str or ~azure.ai.projects.models.RoutineActionType + :ivar agent_id: The project-scoped agent identifier recorded for the routine attempt. + :vartype agent_id: str + :ivar agent_endpoint_id: The legacy endpoint-scoped agent identifier recorded for the routine + attempt. + :vartype agent_endpoint_id: str + :ivar conversation_id: The conversation identifier used by a responses API dispatch. + :vartype conversation_id: str + :ivar session_id: The hosted-agent session identifier used by an invocations API dispatch. + :vartype session_id: str + :ivar triggered_at: The logical trigger time recorded for the routine attempt. + :vartype triggered_at: ~datetime.datetime + :ivar scheduled_fire_at: The scheduled fire time recorded for timer and schedule deliveries. + :vartype scheduled_fire_at: ~datetime.datetime + :ivar started_at: The time when the underlying run started. + :vartype started_at: ~datetime.datetime + :ivar ended_at: The time when the underlying run reached a terminal state. + :vartype ended_at: ~datetime.datetime + :ivar dispatch_id: The dispatch identifier associated with the routine attempt. + :vartype dispatch_id: str + :ivar action_correlation_id: The downstream action correlation identifier, when available. + :vartype action_correlation_id: str + :ivar response_id: The downstream response or invocation identifier, when available. + :vartype response_id: str + :ivar task_id: The workspace task identifier linked to the routine attempt, when available. + :vartype task_id: str + :ivar error_status_code: The downstream error status code captured for a failed attempt, when + available. + :vartype error_status_code: int + :ivar error_type: The fully qualified error type captured for a failed attempt, when available. + :vartype error_type: str + :ivar error_message: The truncated failure message captured for a failed attempt, when + available. + :vartype error_message: str + """ + + id: str = rest_field(visibility=["read"]) + """The unique run identifier for the routine attempt. Required.""" + status: Optional["_unions.RoutineRunStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The run status. Is one of the following types: str""" + phase: Optional[Union[str, "_models.RoutineRunPhase"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The AgentExtensions lifecycle phase for the routine attempt. Known values are: \"queued\", + \"dispatching\", \"completed\", and \"failed\".""" + trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The trigger type that produced the routine attempt. Known values are: \"custom\", + \"github_issue\", \"schedule\", and \"timer\".""" + trigger_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The configured trigger name that produced the routine attempt.""" + trigger_event_payload: Optional[dict[str, Any]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The event payload captured from the event that triggered the routine attempt, when available.""" + attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The source path that created the routine attempt. Known values are: \"event_fire\", + \"manual_dispatch\", \"queued_dispatch\", \"schedule_delivery\", and \"timer_delivery\".""" + action_type: Optional[Union[str, "_models.RoutineActionType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The action type dispatched for the routine attempt. Known values are: + \"invoke_agent_responses_api\" and \"invoke_agent_invocations_api\".""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The project-scoped agent identifier recorded for the routine attempt.""" + agent_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The legacy endpoint-scoped agent identifier recorded for the routine attempt.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The conversation identifier used by a responses API dispatch.""" + session_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The hosted-agent session identifier used by an invocations API dispatch.""" + triggered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The logical trigger time recorded for the routine attempt.""" + scheduled_fire_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The scheduled fire time recorded for timer and schedule deliveries.""" + started_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the underlying run started.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the underlying run reached a terminal state.""" + dispatch_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The dispatch identifier associated with the routine attempt.""" + action_correlation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream action correlation identifier, when available.""" + response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream response or invocation identifier, when available.""" + task_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The workspace task identifier linked to the routine attempt, when available.""" + error_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream error status code captured for a failed attempt, when available.""" + error_type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The fully qualified error type captured for a failed attempt, when available.""" + error_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The truncated failure message captured for a failed attempt, when available.""" + + @overload + def __init__( + self, + *, + status: Optional["_unions.RoutineRunStatus"] = None, + phase: Optional[Union[str, "_models.RoutineRunPhase"]] = None, + trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = None, + trigger_name: Optional[str] = None, + trigger_event_payload: Optional[dict[str, Any]] = None, + attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = None, + action_type: Optional[Union[str, "_models.RoutineActionType"]] = None, + agent_id: Optional[str] = None, + agent_endpoint_id: Optional[str] = None, + conversation_id: Optional[str] = None, + session_id: Optional[str] = None, + triggered_at: Optional[datetime.datetime] = None, + scheduled_fire_at: Optional[datetime.datetime] = None, + started_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + dispatch_id: Optional[str] = None, + action_correlation_id: Optional[str] = None, + response_id: Optional[str] = None, + task_id: Optional[str] = None, + error_status_code: Optional[int] = None, + error_type: Optional[str] = None, + error_message: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RubricBasedEvaluatorDefinition( + EvaluatorDefinition, discriminator="rubric" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Rubric-based evaluator definition — stores dimensions produced by the generate API. Used for + both quality and safety evaluators. + + :ivar init_parameters: The JSON schema (Draft 2020-12) for the evaluator's input parameters. + This includes parameters like type, properties, required. + :vartype init_parameters: dict[str, any] + :ivar data_schema: The JSON schema (Draft 2020-12) for the evaluator's input data. This + includes parameters like type, properties, required. + :vartype data_schema: dict[str, any] + :ivar metrics: List of output metrics produced by this evaluator. + :vartype metrics: dict[str, ~azure.ai.projects.models.EvaluatorMetric] + :ivar type: Required. Rubric-based evaluator definition. Stores dimensions (the scoring + blueprint) for both quality and safety evaluators. Can be created via the generate API or + manually via createVersion. + :vartype type: str or ~azure.ai.projects.models.RUBRIC + :ivar dimensions: The set of dimensions — the scoring blueprint used by the LLM judge. Quality + evaluators include a non-editable residual dimension with id 'general_quality' + (always_applicable: true); safety evaluators include 'general_policy_compliance'. Both use the + same Dimension structure. Required. + :vartype dimensions: list[~azure.ai.projects.models.Dimension] + :ivar pass_threshold: Pass/fail threshold for the aggregate rubric score, on the same + normalized 0.0-1.0 scale as the emitted ``score``. When the runtime weighted average meets or + exceeds this value, the result is ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted + average of 3.0). The 'any dimension scored 1 → fail' rule still applies regardless of this + threshold. + :vartype pass_threshold: float + """ + + type: Literal[EvaluatorDefinitionType.RUBRIC] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Rubric-based evaluator definition. Stores dimensions (the scoring blueprint) for both + quality and safety evaluators. Can be created via the generate API or manually via + createVersion.""" + dimensions: list["_models.Dimension"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The set of dimensions — the scoring blueprint used by the LLM judge. Quality evaluators include + a non-editable residual dimension with id 'general_quality' (always_applicable: true); safety + evaluators include 'general_policy_compliance'. Both use the same Dimension structure. + Required.""" + pass_threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Pass/fail threshold for the aggregate rubric score, on the same normalized 0.0-1.0 scale as the + emitted ``score``. When the runtime weighted average meets or exceeds this value, the result is + ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted average of 3.0). The 'any dimension + scored 1 → fail' rule still applies regardless of this threshold.""" + + @overload + def __init__( + self, + *, + dimensions: list["_models.Dimension"], + init_parameters: Optional[dict[str, Any]] = None, + data_schema: Optional[dict[str, Any]] = None, + metrics: Optional[dict[str, "_models.EvaluatorMetric"]] = None, + pass_threshold: Optional[float] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = EvaluatorDefinitionType.RUBRIC # type: ignore + + +class RubricGenerationInputQualityWarning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A non-fatal advisory produced during rubric evaluator generation when resolved inputs are + technically valid but likely too weak to produce a high-quality rubric. Read-only; + service-generated. Persisted with the terminal EvaluatorGenerationJob. + + :ivar code: Stable searchable machine-readable warning code. Required. Known values are: + "empty_prompt", "short_prompt", "empty_agent_instructions", "short_agent_instructions", + "empty_dataset_content", "short_dataset_content", "low_trace_count", and + "insufficient_total_input". + :vartype code: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningCode + :ivar severity: Advisory severity. Initial values: ``warning``. Required. "warning" + :vartype severity: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity + :ivar message: Human-readable message suitable for direct SDK/CLI/UI display. Must not include + raw prompt, instruction, dataset, or trace text. Required. + :vartype message: str + :ivar source: Which source category the warning applies to. ``aggregate`` is used only for + cross-source warnings. Required. Known values are: "prompt", "agent", "dataset", and + "aggregate". + :vartype source: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSource + :ivar source_index: Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the + warning applies to a specific source. Omitted for aggregate warnings and for warnings not tied + to one source. + :vartype source_index: int + """ + + code: Union[str, "_models.RubricGenerationInputQualityWarningCode"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Stable searchable machine-readable warning code. Required. Known values are: \"empty_prompt\", + \"short_prompt\", \"empty_agent_instructions\", \"short_agent_instructions\", + \"empty_dataset_content\", \"short_dataset_content\", \"low_trace_count\", and + \"insufficient_total_input\".""" + severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Advisory severity. Initial values: ``warning``. Required. \"warning\"""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Human-readable message suitable for direct SDK/CLI/UI display. Must not include raw prompt, + instruction, dataset, or trace text. Required.""" + source: Union[str, "_models.RubricGenerationInputQualityWarningSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Which source category the warning applies to. ``aggregate`` is used only for cross-source + warnings. Required. Known values are: \"prompt\", \"agent\", \"dataset\", and \"aggregate\".""" + source_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the warning applies to a + specific source. Omitted for aggregate warnings and for warnings not tied to one source.""" + + @overload + def __init__( + self, + *, + code: Union[str, "_models.RubricGenerationInputQualityWarningCode"], + severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"], + message: str, + source: Union[str, "_models.RubricGenerationInputQualityWarningSource"], + source_index: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SASCredentials(BaseCredentials, discriminator="SAS"): + """Shared Access Signature (SAS) credential definition. + + :ivar type: The credential type. Required. Shared Access Signature (SAS) credential. + :vartype type: str or ~azure.ai.projects.models.SAS + :ivar sas_token: SAS token. + :vartype sas_token: str + """ + + type: Literal[CredentialType.SAS] = rest_discriminator(name="type", visibility=["read"]) # type: ignore + """The credential type. Required. Shared Access Signature (SAS) credential.""" + sas_token: Optional[str] = rest_field(name="SAS", visibility=["read"]) + """SAS token.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CredentialType.SAS # type: ignore + + +class Schedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Schedule model. + + :ivar schedule_id: Identifier of the schedule. Required. + :vartype schedule_id: str + :ivar display_name: Name of the schedule. + :vartype display_name: str + :ivar description: Description of the schedule. + :vartype description: str + :ivar enabled: Enabled status of the schedule. Required. + :vartype enabled: bool + :ivar provisioning_status: Provisioning status of the schedule. Known values are: "Creating", + "Updating", "Deleting", "Succeeded", and "Failed". + :vartype provisioning_status: str or ~azure.ai.projects.models.ScheduleProvisioningStatus + :ivar trigger: Trigger for the schedule. Required. + :vartype trigger: ~azure.ai.projects.models.Trigger + :ivar task: Task for the schedule. Required. + :vartype task: ~azure.ai.projects.models.ScheduleTask + :ivar tags: Schedule's tags. Unlike properties, tags are fully mutable. + :vartype tags: dict[str, str] + :ivar properties: Schedule's properties. Unlike tags, properties are add-only. Once added, a + property cannot be removed. + :vartype properties: dict[str, str] + :ivar system_data: System metadata for the resource. Required. + :vartype system_data: dict[str, str] + """ + + schedule_id: str = rest_field(name="id", visibility=["read"]) + """Identifier of the schedule. Required.""" + display_name: Optional[str] = rest_field( + name="displayName", visibility=["read", "create", "update", "delete", "query"] + ) + """Name of the schedule.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the schedule.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Enabled status of the schedule. Required.""" + provisioning_status: Optional[Union[str, "_models.ScheduleProvisioningStatus"]] = rest_field( + name="provisioningStatus", visibility=["read"] + ) + """Provisioning status of the schedule. Known values are: \"Creating\", \"Updating\", + \"Deleting\", \"Succeeded\", and \"Failed\".""" + trigger: "_models.Trigger" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Trigger for the schedule. Required.""" + task: "_models.ScheduleTask" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Task for the schedule. Required.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Schedule's tags. Unlike properties, tags are fully mutable.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Schedule's properties. Unlike tags, properties are add-only. Once added, a property cannot be + removed.""" + system_data: dict[str, str] = rest_field(name="systemData", visibility=["read"]) + """System metadata for the resource. Required.""" + + @overload + def __init__( + self, + *, + enabled: bool, + trigger: "_models.Trigger", + task: "_models.ScheduleTask", + display_name: Optional[str] = None, + description: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ScheduleRoutineTrigger( + RoutineTrigger, discriminator="schedule" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A recurring cron-based routine trigger. + + :ivar type: The trigger type. Required. A recurring cron-based trigger. + :vartype type: str or ~azure.ai.projects.models.SCHEDULE + :ivar cron_expression: A 5-field cron expression. The service enforces a minimum interval of + five minutes by default. Required. + :vartype cron_expression: str + :ivar time_zone: An IANA or Windows time zone identifier for the schedule. Required. + :vartype time_zone: str + """ + + type: Literal[RoutineTriggerType.SCHEDULE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The trigger type. Required. A recurring cron-based trigger.""" + cron_expression: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A 5-field cron expression. The service enforces a minimum interval of five minutes by default. + Required.""" + time_zone: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An IANA or Windows time zone identifier for the schedule. Required.""" + + @overload + def __init__( + self, + *, + cron_expression: str, + time_zone: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RoutineTriggerType.SCHEDULE # type: ignore + + +class ScheduleRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Schedule run model. + + :ivar run_id: Identifier of the schedule run. Required. + :vartype run_id: str + :ivar schedule_id: Identifier of the schedule. Required. + :vartype schedule_id: str + :ivar success: Trigger success status of the schedule run. Required. + :vartype success: bool + :ivar trigger_time: Trigger time of the schedule run. + :vartype trigger_time: ~datetime.datetime + :ivar error: Error information for the schedule run. + :vartype error: str + :ivar properties: Properties of the schedule run. Required. + :vartype properties: dict[str, str] + """ + + run_id: str = rest_field(name="id", visibility=["read"]) + """Identifier of the schedule run. Required.""" + schedule_id: str = rest_field(name="scheduleId", visibility=["read", "create", "update", "delete", "query"]) + """Identifier of the schedule. Required.""" + success: bool = rest_field(visibility=["read"]) + """Trigger success status of the schedule run. Required.""" + trigger_time: Optional[datetime.datetime] = rest_field( + name="triggerTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """Trigger time of the schedule run.""" + error: Optional[str] = rest_field(visibility=["read"]) + """Error information for the schedule run.""" + properties: dict[str, str] = rest_field(visibility=["read"]) + """Properties of the schedule run. Required.""" + + @overload + def __init__( + self, + *, + schedule_id: str, + trigger_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionConfiguration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Session defaults applied to sessions created for a hosted agent version. + + :ivar idle_timeout_seconds: The idle duration, in seconds, before a session's sandbox is + suspended. Optional — when unset, the server default of 900 seconds is used. Must be between + 120 and 3600 seconds (inclusive). + :vartype idle_timeout_seconds: ~datetime.timedelta + """ + + idle_timeout_seconds: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The idle duration, in seconds, before a session's sandbox is suspended. Optional — when unset, + the server default of 900 seconds is used. Must be between 120 and 3600 seconds (inclusive).""" + + @overload + def __init__( + self, + *, + idle_timeout_seconds: Optional[datetime.timedelta] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionDirectoryEntry(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single entry in a directory listing. + + :ivar name: The name of the file or directory. Required. + :vartype name: str + :ivar size: The size in bytes (0 for directories). Required. + :vartype size: int + :ivar is_directory: Whether this entry is a directory. Required. + :vartype is_directory: bool + :ivar modified_time: The Unix timestamp (in seconds) when the file was last modified. Required. + :vartype modified_time: ~datetime.datetime + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the file or directory. Required.""" + size: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The size in bytes (0 for directories). Required.""" + is_directory: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether this entry is a directory. Required.""" + modified_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) when the file was last modified. Required.""" + + @overload + def __init__( + self, + *, + name: str, + size: int, + is_directory: bool, + modified_time: datetime.datetime, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionFileWriteResult(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Response from uploading a file to a session sandbox. + + :ivar path: The path where the file was written, relative to the session home directory. + Required. + :vartype path: str + :ivar bytes_written: Number of bytes written. Required. + :vartype bytes_written: int + """ + + path: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The path where the file was written, relative to the session home directory. Required.""" + bytes_written: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of bytes written. Required.""" + + @overload + def __init__( + self, + *, + path: str, + bytes_written: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionLogEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single Server-Sent Event frame emitted by the hosted agent session log stream. + + Each frame contains an ``event`` field identifying the event type and a ``data`` + field carrying the payload as plain text. Although the current ``data`` payload + is JSON-formatted, its schema is not contractual — additional keys may appear + and the format may change over time. Clients should treat ``data`` as an + opaque string and optionally attempt JSON parsing. + + New event types may be added in the future. Clients should gracefully + ignore unrecognized event types. + + Wire format: + + .. code-block:: + + event: log + data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting server on port 18080"} + + event: log + data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + + :ivar event: The SSE event type. Currently ``log``, but additional event types may be added in + the future. Clients should ignore unrecognized event types. Required. "log" + :vartype event: str or ~azure.ai.projects.models.SessionLogEventType + :ivar data: The event payload as plain text. Currently JSON-formatted but the schema is not + contractual and may change. Required. + :vartype data: str + """ + + event: Union[str, "_models.SessionLogEventType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The SSE event type. Currently ``log``, but additional event types may be added in the future. + Clients should ignore unrecognized event types. Required. \"log\"""" + data: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The event payload as plain text. Currently JSON-formatted but the schema is not contractual and + may change. Required.""" + + @overload + def __init__( + self, + *, + event: Union[str, "_models.SessionLogEventType"], + data: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SharepointGroundingToolParameters(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The sharepoint grounding tool parameters. + + :ivar project_connections: The project connections attached to this tool. There can be a + maximum of 1 connection resource attached to the tool. + :vartype project_connections: list[~azure.ai.projects.models.ToolProjectConnection] + """ + + project_connections: Optional[list["_models.ToolProjectConnection"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The project connections attached to this tool. There can be a maximum of 1 connection resource + attached to the tool.""" + + @overload + def __init__( + self, + *, + project_connections: Optional[list["_models.ToolProjectConnection"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SharepointPreviewTool( + Tool, discriminator="sharepoint_grounding_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The input definition information for a sharepoint tool as used to configure an agent. + + :ivar type: The object type, which is always 'sharepoint_grounding_preview'. Required. + SHAREPOINT_GROUNDING_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.SHAREPOINT_GROUNDING_PREVIEW + :ivar sharepoint_grounding_preview: The sharepoint grounding tool parameters. Required. + :vartype sharepoint_grounding_preview: + ~azure.ai.projects.models.SharepointGroundingToolParameters + """ + + type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The object type, which is always 'sharepoint_grounding_preview'. Required. + SHAREPOINT_GROUNDING_PREVIEW.""" + sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sharepoint grounding tool parameters. Required.""" + + @overload + def __init__( + self, + *, + sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolType.SHAREPOINT_GROUNDING_PREVIEW # type: ignore + + +class ShellToolboxTool( + ToolboxTool, discriminator="shell" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A shell tool stored in a toolbox. This model is additive to toolbox configuration and does not + modify the OpenAI tool contract or existing toolbox tool definitions. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``shell``. Required. SHELL. + :vartype type: str or ~azure.ai.projects.models.SHELL + :ivar allowed_callers: + :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] + :ivar environment: The environment in which shell commands are executed. Specify an + automatically provisioned container or an existing container. Required. + :vartype environment: ~azure.ai.projects.models.ToolboxShellEnvironment + """ + + type: Literal[ToolboxToolType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``shell``. Required. SHELL.""" + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + environment: "_models.ToolboxShellEnvironment" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The environment in which shell commands are executed. Specify an automatically provisioned + container or an existing container. Required.""" + + @overload + def __init__( + self, + *, + environment: "_models.ToolboxShellEnvironment", + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.SHELL # type: ignore + + +class SimpleQnADataGenerationJobOptions( + DataGenerationJobOptions, discriminator="simple_qna" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a data generation job with SimpleQnA type. + + :ivar max_samples: Maximum number of samples to generate. Required. + :vartype max_samples: int + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is SimpleQnA for this model. Required. Simple + question and answers between user and agent. + :vartype type: str or ~azure.ai.projects.models.SIMPLE_QNA + :ivar question_types: The question types to generate. Used only for fine-tuning scenarios. + :vartype question_types: list[str or ~azure.ai.projects.models.SimpleQnAFineTuningQuestionType] + """ + + type: Literal[DataGenerationJobType.SIMPLE_QNA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is SimpleQnA for this model. Required. Simple question and + answers between user and agent.""" + question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The question types to generate. Used only for fine-tuning scenarios.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.SIMPLE_QNA # type: ignore + + +class SimulationSeedDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="simulation_seed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a task generation data generation job. Use with multiturn evaluation scenarios + and with prompt, file, or agent sources. Generated dataset rows include fields such as ``id``, + ``category``, ``test_case_description``, and ``desired_num_turns``. + + :ivar max_samples: Maximum number of samples to generate. Required. + :vartype max_samples: int + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is SimulationSeed for this model. Required. + Simulation seed for evaluation scenarios. + :vartype type: str or ~azure.ai.projects.models.SIMULATION_SEED + """ + + type: Literal[DataGenerationJobType.SIMULATION_SEED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is SimulationSeed for this model. Required. Simulation seed + for evaluation scenarios.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.SIMULATION_SEED # type: ignore + + +class SipTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="sip" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A SIP destination for a telephony transfer target. + + :ivar kind: The SIP destination type. Required. A Session Initiation Protocol destination. + :vartype kind: str or ~azure.ai.projects.models.SIP + :ivar value: The SIP or SIPS URI to call. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.SIP] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The SIP destination type. Required. A Session Initiation Protocol destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The SIP or SIPS URI to call. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.SIP # type: ignore + + +class SkillDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A skill resource. + + :ivar id: The unique identifier of the skill. Required. + :vartype id: str + :ivar name: The unique name of the skill. Required. + :vartype name: str + :ivar description: A human-readable description of the skill. Required. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the skill was created. Required. + :vartype created_at: ~datetime.datetime + :ivar default_version: The default version for the skill. Can be changed via updateSkill. + Required. + :vartype default_version: str + :ivar latest_version: The latest version for the skill. Required. + :vartype latest_version: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the skill. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique name of the skill. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the skill. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the skill was created. Required.""" + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default version for the skill. Can be changed via updateSkill. Required.""" + latest_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The latest version for the skill. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + description: str, + created_at: datetime.datetime, + default_version: str, + latest_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SkillInlineContent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Inline content for defining a simple skill without uploading files. Follows the agentskills.io + SKILL.md specification. + + :ivar description: A human-readable description of what the skill does and when to use it. + Required. + :vartype description: str + :ivar instructions: The skill instructions in markdown format. This is the body content of the + SKILL.md file. Required. + :vartype instructions: str + :ivar license: License name or reference to a bundled license file. + :vartype license: str + :ivar compatibility: Environment requirements or compatibility notes for the skill. + :vartype compatibility: str + :ivar metadata: Arbitrary key-value metadata for additional properties. + :vartype metadata: dict[str, str] + :ivar allowed_tools: List of pre-approved tools the skill may use. Experimental. + :vartype allowed_tools: list[str] + """ + + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of what the skill does and when to use it. Required.""" + instructions: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The skill instructions in markdown format. This is the body content of the SKILL.md file. + Required.""" + license: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """License name or reference to a bundled license file.""" + compatibility: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Environment requirements or compatibility notes for the skill.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Arbitrary key-value metadata for additional properties.""" + allowed_tools: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """List of pre-approved tools the skill may use. Experimental.""" + + @overload + def __init__( + self, + *, + description: str, + instructions: str, + license: Optional[str] = None, + compatibility: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + allowed_tools: Optional[list[str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SkillReferenceParam( + ContainerSkill, discriminator="skill_reference" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """SkillReferenceParam. + + :ivar type: References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE. + :vartype type: str or ~azure.ai.projects.models.SKILL_REFERENCE + :ivar skill_id: The ID of the referenced skill. Required. + :vartype skill_id: str + :ivar version: Optional skill version. Use a positive integer or 'latest'. Omit for default. + :vartype version: str + """ + + type: Literal[ContainerSkillType.SKILL_REFERENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE.""" + skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the referenced skill. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional skill version. Use a positive integer or 'latest'. Omit for default.""" + + @overload + def __init__( + self, + *, + skill_id: str, + version: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ContainerSkillType.SKILL_REFERENCE # type: ignore + + +class SkillVersion(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A specific version of a skill. + + :ivar id: The unique identifier of the skill version. Required. + :vartype id: str + :ivar skill_id: The identifier of the parent skill. Required. + :vartype skill_id: str + :ivar name: The name of the skill version. Required. + :vartype name: str + :ivar version: The version identifier. Skill versions are immutable. Required. + :vartype version: str + :ivar description: A human-readable description of the skill version. Required. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the skill version was created. Required. + :vartype created_at: ~datetime.datetime + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the skill version. Required.""" + skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the parent skill. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the skill version. Required.""" + version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier. Skill versions are immutable. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the skill version. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the skill version was created. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + skill_id: str, + name: str, + version: str, + description: str, + created_at: datetime.datetime, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolChoiceParam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """How the model should select which tool (or tools) to use when generating a response. See the + ``tools`` parameter to see how to specify which tools the model can call. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolChoiceAllowed, SpecificApplyPatchParam, ToolChoiceCodeInterpreter, ToolChoiceComputer, + ToolChoiceComputerUse, ToolChoiceComputerUsePreview, ToolChoiceCustom, ToolChoiceFileSearch, + ToolChoiceFunction, ToolChoiceImageGeneration, ToolChoiceMCP, + SpecificProgrammaticToolCallingParam, SpecificFunctionShellParam, ToolChoiceWebSearchPreview, + ToolChoiceWebSearchPreview20250311 + + :ivar type: Required. Known values are: "allowed_tools", "function", "mcp", "custom", + "programmatic_tool_calling", "apply_patch", "shell", "file_search", "web_search_preview", + "computer_use_preview", "web_search_preview_2025_03_11", "image_generation", + "code_interpreter", "computer", and "computer_use". + :vartype type: str or ~azure.ai.projects.models.ToolChoiceParamType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"allowed_tools\", \"function\", \"mcp\", \"custom\", + \"programmatic_tool_calling\", \"apply_patch\", \"shell\", \"file_search\", + \"web_search_preview\", \"computer_use_preview\", \"web_search_preview_2025_03_11\", + \"image_generation\", \"code_interpreter\", \"computer\", and \"computer_use\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SpecificApplyPatchParam(ToolChoiceParam, discriminator="apply_patch"): + """Specific apply patch tool choice. + + :ivar type: The tool to call. Always ``apply_patch``. Required. APPLY_PATCH. + :vartype type: str or ~azure.ai.projects.models.APPLY_PATCH + """ + + type: Literal[ToolChoiceParamType.APPLY_PATCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``apply_patch``. Required. APPLY_PATCH.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.APPLY_PATCH # type: ignore + + +class SpecificFunctionShellParam(ToolChoiceParam, discriminator="shell"): + """Specific shell tool choice. + + :ivar type: The tool to call. Always ``shell``. Required. SHELL. + :vartype type: str or ~azure.ai.projects.models.SHELL + """ + + type: Literal[ToolChoiceParamType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``shell``. Required. SHELL.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.SHELL # type: ignore + + +class SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator="programmatic_tool_calling"): + """SpecificProgrammaticToolCallingParam. + + :ivar type: The tool to call. Always ``programmatic_tool_calling``. Required. + PROGRAMMATIC_TOOL_CALLING. + :vartype type: str or ~azure.ai.projects.models.PROGRAMMATIC_TOOL_CALLING + """ + + type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``programmatic_tool_calling``. Required. PROGRAMMATIC_TOOL_CALLING.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING # type: ignore + + +class StructuredInputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An structured input that can participate in prompt template substitutions and tool argument + binding. + + :ivar description: A human-readable description of the input. + :vartype description: str + :ivar default_value: The default value for the input if no run-time value is provided. + :vartype default_value: any + :ivar schema: The JSON schema for the structured input (optional). + :vartype schema: dict[str, any] + :ivar required: Whether the input property is required when the agent is invoked. The service + defaults to ``false`` if a value is not specified by the caller. + :vartype required: bool + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the input.""" + default_value: Optional[Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default value for the input if no run-time value is provided.""" + schema: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON schema for the structured input (optional).""" + required: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the input property is required when the agent is invoked. The service defaults to + ``false`` if a value is not specified by the caller.""" + + @overload + def __init__( + self, + *, + description: Optional[str] = None, + default_value: Optional[Any] = None, + schema: Optional[dict[str, Any]] = None, + required: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class StructuredOutputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A structured output that can be produced by the agent. + + :ivar name: The name of the structured output. Required. + :vartype name: str + :ivar description: A description of the output to emit. Used by the model to determine when to + emit the output. Required. + :vartype description: str + :ivar schema: The JSON schema for the structured output. Required. + :vartype schema: dict[str, any] + :ivar strict: Whether to enforce strict validation. Default ``true``. Required. + :vartype strict: bool + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the structured output. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of the output to emit. Used by the model to determine when to emit the output. + Required.""" + schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON schema for the structured output. Required.""" + strict: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether to enforce strict validation. Default ``true``. Required.""" + + @overload + def __init__( + self, + *, + name: str, + description: str, + schema: dict[str, Any], + strict: bool, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TaxonomyCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Taxonomy category definition. + + :ivar id: Unique identifier of the taxonomy category. Required. + :vartype id: str + :ivar name: Name of the taxonomy category. Required. + :vartype name: str + :ivar description: Description of the taxonomy category. + :vartype description: str + :ivar risk_category: Risk category associated with this taxonomy category. Required. Known + values are: "HateUnfairness", "Violence", "Sexual", "SelfHarm", "ProtectedMaterial", + "CodeVulnerability", "UngroundedAttributes", "ProhibitedActions", "SensitiveDataLeakage", and + "TaskAdherence". + :vartype risk_category: str or ~azure.ai.projects.models.RiskCategory + :ivar sub_categories: List of taxonomy sub categories. Required. + :vartype sub_categories: list[~azure.ai.projects.models.TaxonomySubCategory] + :ivar properties: Additional properties for the taxonomy category. + :vartype properties: dict[str, str] + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Unique identifier of the taxonomy category. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Name of the taxonomy category. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the taxonomy category.""" + risk_category: Union[str, "_models.RiskCategory"] = rest_field( + name="riskCategory", visibility=["read", "create", "update", "delete", "query"] + ) + """Risk category associated with this taxonomy category. Required. Known values are: + \"HateUnfairness\", \"Violence\", \"Sexual\", \"SelfHarm\", \"ProtectedMaterial\", + \"CodeVulnerability\", \"UngroundedAttributes\", \"ProhibitedActions\", + \"SensitiveDataLeakage\", and \"TaskAdherence\".""" + sub_categories: list["_models.TaxonomySubCategory"] = rest_field( + name="subCategories", visibility=["read", "create", "update", "delete", "query"] + ) + """List of taxonomy sub categories. Required.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional properties for the taxonomy category.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + risk_category: Union[str, "_models.RiskCategory"], + sub_categories: list["_models.TaxonomySubCategory"], + description: Optional[str] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TaxonomySubCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Taxonomy sub-category definition. + + :ivar id: Unique identifier of the taxonomy sub-category. Required. + :vartype id: str + :ivar name: Name of the taxonomy sub-category. Required. + :vartype name: str + :ivar description: Description of the taxonomy sub-category. + :vartype description: str + :ivar enabled: List of taxonomy items under this sub-category. Required. + :vartype enabled: bool + :ivar properties: Additional properties for the taxonomy sub-category. + :vartype properties: dict[str, str] + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Unique identifier of the taxonomy sub-category. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Name of the taxonomy sub-category. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the taxonomy sub-category.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """List of taxonomy items under this sub-category. Required.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional properties for the taxonomy sub-category.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + enabled: bool, + description: Optional[str] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyBinding(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A telephony binding owned by a voice agent. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TeamsPhoneExtensionTelephonyBinding, TwilioTelephonyBinding + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + """ + + __mapping__: dict[str, _Model] = {} + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated binding identifier. Required.""" + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display label for the binding.""" + status: Union[str, "_models.TelephonyBindingStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status. Required. Known values are: \"active\" and \"suspended\".""" + incoming_call_url: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated webhook URL to configure with the telephony provider. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: str, + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TeamsPhoneExtensionTelephonyBinding( + TelephonyBinding, discriminator="teams_phone_extension" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Microsoft Teams Phone Extension binding owned by a voice agent. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class TelephonyBindingListItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A telephony binding returned in a list, including its entity tag. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TeamsPhoneExtensionTelephonyBindingListItem, TwilioTelephonyBindingListItem + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + """ + + __mapping__: dict[str, _Model] = {} + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated binding identifier. Required.""" + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display label for the binding.""" + status: Union[str, "_models.TelephonyBindingStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status. Required. Known values are: \"active\" and \"suspended\".""" + incoming_call_url: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated webhook URL to configure with the telephony provider. Required.""" + etag: str = rest_field(visibility=["read"]) + """The entity tag to send in the ``If-Match`` header when updating or deleting this binding. + Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: str, + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TeamsPhoneExtensionTelephonyBindingListItem( + TelephonyBindingListItem, discriminator="teams_phone_extension" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """A Microsoft Teams Phone Extension binding returned in a list, including its entity tag. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class TeamsTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="teams" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Microsoft Teams destination for a telephony transfer target. + + :ivar kind: The Microsoft Teams destination type. Required. A Microsoft Teams user or + resource-account destination. + :vartype kind: str or ~azure.ai.projects.models.TEAMS + :ivar value: The Microsoft Teams user or resource-account identifier. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.TEAMS] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams destination type. Required. A Microsoft Teams user or resource-account + destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams user or resource-account identifier. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.TEAMS # type: ignore + + +class TelemetryConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Customer-supplied telemetry configuration for exporting container logs, traces, and metrics. + + :ivar endpoints: Customer-supplied telemetry export endpoint configurations. Required. + :vartype endpoints: list[~azure.ai.projects.models.TelemetryEndpoint] + """ + + endpoints: list["_models.TelemetryEndpoint"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Customer-supplied telemetry export endpoint configurations. Required.""" + + @overload + def __init__( + self, + *, + endpoints: list["_models.TelemetryEndpoint"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallJob(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A durable direct or campaign-created outbound call intent. + + :ivar destination: The phone destination to call. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyOutboundDestination + :ivar telephony_binding_id: The active agent telephony binding used to originate the call. + Required. + :vartype telephony_binding_id: str + :ivar purpose: An optional customer-declared purpose for placing the call. + :vartype purpose: str + :ivar structured_inputs: Structured input values available to the agent and greeting for this + call. Agent-declared inputs are validated against their schemas; omitted optional inputs may + use their Agent-defined default values, while omitted required inputs are rejected. Additional + inputs remain available as dynamic template variables. + :vartype structured_inputs: dict[str, any] + :ivar schedule: The optional execution window. + :vartype schedule: ~azure.ai.projects.models.TelephonyCallJobSchedule + :ivar id: The service-generated call-job identifier. Required. + :vartype id: str + :ivar object: The object type. Always ``telephony.call_job``. Required. Default value is + "telephony.call_job". + :vartype object: str + :ivar agent_name: The name of the voice agent used at execution time. Required. + :vartype agent_name: str + :ivar status: The current call-job lifecycle status. Required. Known values are: "accepted", + "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", + "cancellation_requested", "completed", "blocked", "expired", "failed", and "cancelled". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallJobStatus + :ivar cancellation: The recorded cancellation request, when cancellation was requested. + :vartype cancellation: ~azure.ai.projects.models.TelephonyCallJobCancellation + :ivar retry_policy: The frozen provider-attempt retry policy. Required. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicyResponse + :ivar attempt_count: The number of provider attempts created so far. Required. + :vartype attempt_count: int + :ivar next_attempt_at: The Unix timestamp in seconds at which the next retry becomes eligible. + :vartype next_attempt_at: ~datetime.datetime + :ivar terminal_reason: The stable reason for the terminal status, when available. + :vartype terminal_reason: str + :ivar revision: The monotonically increasing optimistic-concurrency revision. Required. + :vartype revision: int + :ivar created_at: The Unix timestamp in seconds when the call job was created. Required. + :vartype created_at: ~datetime.datetime + :ivar updated_at: The Unix timestamp in seconds when the call job was last updated. Required. + :vartype updated_at: ~datetime.datetime + """ + + destination: "_models.TelephonyOutboundDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The phone destination to call. Required.""" + telephony_binding_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The active agent telephony binding used to originate the call. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for placing the call.""" + structured_inputs: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Structured input values available to the agent and greeting for this call. Agent-declared + inputs are validated against their schemas; omitted optional inputs may use their Agent-defined + default values, while omitted required inputs are rejected. Additional inputs remain available + as dynamic template variables.""" + schedule: Optional["_models.TelephonyCallJobSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The optional execution window.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call-job identifier. Required.""" + object: Literal["telephony.call_job"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``telephony.call_job``. Required. Default value is + \"telephony.call_job\".""" + agent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the voice agent used at execution time. Required.""" + status: Union[str, "_models.TelephonyCallJobStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The current call-job lifecycle status. Required. Known values are: \"accepted\", + \"waiting_for_schedule\", \"queued\", \"dispatching\", \"in_progress\", \"waiting_for_retry\", + \"cancellation_requested\", \"completed\", \"blocked\", \"expired\", \"failed\", and + \"cancelled\".""" + cancellation: Optional["_models.TelephonyCallJobCancellation"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The recorded cancellation request, when cancellation was requested.""" + retry_policy: "_models.TelephonyOutboundRetryPolicyResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The frozen provider-attempt retry policy. Required.""" + attempt_count: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of provider attempts created so far. Required.""" + next_attempt_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds at which the next retry becomes eligible.""" + terminal_reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The stable reason for the terminal status, when available.""" + revision: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The monotonically increasing optimistic-concurrency revision. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when the call job was created. Required.""" + updated_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when the call job was last updated. Required.""" + + @overload + def __init__( + self, + *, + destination: "_models.TelephonyOutboundDestination", + telephony_binding_id: str, + id: str, # pylint: disable=redefined-builtin + agent_name: str, + status: Union[str, "_models.TelephonyCallJobStatus"], + retry_policy: "_models.TelephonyOutboundRetryPolicyResponse", + attempt_count: int, + revision: int, + created_at: datetime.datetime, + updated_at: datetime.datetime, + purpose: Optional[str] = None, + structured_inputs: Optional[dict[str, Any]] = None, + schedule: Optional["_models.TelephonyCallJobSchedule"] = None, + cancellation: Optional["_models.TelephonyCallJobCancellation"] = None, + next_attempt_at: Optional[datetime.datetime] = None, + terminal_reason: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.object: Literal["telephony.call_job"] = "telephony.call_job" + + +class TelephonyCallJobCancellation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A cancellation request recorded for an outbound call job. + + :ivar requested_by: The authenticated principal that requested cancellation. Required. + :vartype requested_by: str + :ivar mode: The cancellation mode applied to the call job. Required. + :vartype mode: str + :ivar requested_at: The Unix timestamp in seconds when cancellation was requested. Required. + :vartype requested_at: ~datetime.datetime + :ivar revision: The call-job revision at which cancellation was recorded. Required. + :vartype revision: int + """ + + requested_by: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The authenticated principal that requested cancellation. Required.""" + mode: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The cancellation mode applied to the call job. Required.""" + requested_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when cancellation was requested. Required.""" + revision: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The call-job revision at which cancellation was recorded. Required.""" + + @overload + def __init__( + self, + *, + requested_by: str, + mode: str, + requested_at: datetime.datetime, + revision: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallJobSchedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The optional execution window for a direct outbound call. + + :ivar not_before: The earliest instant at which dispatch may begin. + :vartype not_before: ~datetime.datetime + :ivar expires_at: The instant after which the call job expires without dispatch. + :vartype expires_at: ~datetime.datetime + """ + + not_before: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The earliest instant at which dispatch may begin.""" + expires_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The instant after which the call job expires without dispatch.""" + + @overload + def __init__( + self, + *, + not_before: Optional[datetime.datetime] = None, + expires_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallLifecycleEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A bounded durable observation in the lifecycle of one telephony call. + + :ivar sequence: The service-assigned order of the event within the call record. Required. + :vartype sequence: int + :ivar name: The stable provider-neutral event name. Required. Known values are: + "telephony.webhook.received", "telephony.webhook.validation", "telephony.binding.resolve", + "telephony.provider.answer", "telephony.media.connect", "telephony.agent_session.connect", + "telephony.media.first_caller_audio", "telephony.media.first_agent_audio", + "telephony.call.transfer", "telephony.call.hangup", and "telephony.call.disconnect". + :vartype name: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventName + :ivar source: The component that supplied the observation. Required. Known values are: + "gateway", "teams_phone_extension", "twilio", and "voice_agent". + :vartype source: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventSource + :ivar outcome: The outcome of the observed lifecycle operation. Required. Known values are: + "observed", "started", "succeeded", "failed", "rejected", and "cancelled". + :vartype outcome: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventOutcome + :ivar observed_at: The Unix timestamp (in seconds) for when the service observed the event. + Required. + :vartype observed_at: ~datetime.datetime + :ivar occurred_at: The Unix timestamp (in seconds) for when the event occurred according to the + provider. + :vartype occurred_at: ~datetime.datetime + :ivar timestamp_source: The source of the event timestamp. Required. Known values are: + "provider", "gateway", and "derived". + :vartype timestamp_source: str or ~azure.ai.projects.models.TelephonyCallTimestampSource + :ivar reason: A stable service-generated reason associated with the event. + :vartype reason: str + :ivar provider_event_id: The provider event identifier used for idempotency, when supplied. + :vartype provider_event_id: str + :ivar provider_sequence: The provider event sequence, when supplied. + :vartype provider_sequence: int + :ivar provider_status_code: The provider status code associated with the event. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the event. + :vartype provider_sub_code: int + """ + + sequence: int = rest_field(visibility=["read"]) + """The service-assigned order of the event within the call record. Required.""" + name: Union[str, "_models.TelephonyCallLifecycleEventName"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The stable provider-neutral event name. Required. Known values are: + \"telephony.webhook.received\", \"telephony.webhook.validation\", + \"telephony.binding.resolve\", \"telephony.provider.answer\", \"telephony.media.connect\", + \"telephony.agent_session.connect\", \"telephony.media.first_caller_audio\", + \"telephony.media.first_agent_audio\", \"telephony.call.transfer\", \"telephony.call.hangup\", + and \"telephony.call.disconnect\".""" + source: Union[str, "_models.TelephonyCallLifecycleEventSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The component that supplied the observation. Required. Known values are: \"gateway\", + \"teams_phone_extension\", \"twilio\", and \"voice_agent\".""" + outcome: Union[str, "_models.TelephonyCallLifecycleEventOutcome"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The outcome of the observed lifecycle operation. Required. Known values are: \"observed\", + \"started\", \"succeeded\", \"failed\", \"rejected\", and \"cancelled\".""" + observed_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the service observed the event. Required.""" + occurred_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the event occurred according to the provider.""" + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The source of the event timestamp. Required. Known values are: \"provider\", \"gateway\", and + \"derived\".""" + reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A stable service-generated reason associated with the event.""" + provider_event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider event identifier used for idempotency, when supplied.""" + provider_sequence: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider event sequence, when supplied.""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the event.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the event.""" + + @overload + def __init__( + self, + *, + name: Union[str, "_models.TelephonyCallLifecycleEventName"], + source: Union[str, "_models.TelephonyCallLifecycleEventSource"], + outcome: Union[str, "_models.TelephonyCallLifecycleEventOutcome"], + observed_at: datetime.datetime, + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"], + occurred_at: Optional[datetime.datetime] = None, + reason: Optional[str] = None, + provider_event_id: Optional[str] = None, + provider_sequence: Optional[int] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallRecord(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Detailed diagnostics for a durable inbound call to a voice agent. + + :ivar id: The service-generated call identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar provider_call_id: The provider-assigned call identifier, when available. + :vartype provider_call_id: str + :ivar caller_number: The caller's phone number, when supplied by the provider. + :vartype caller_number: str + :ivar provider_number: The Teams Phone Extension or Twilio number that received the call. + :vartype provider_number: str + :ivar status: The lifecycle status of the call. Required. Known values are: "in_progress", + "success", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :ivar phase: The provider-neutral lifecycle phase reached by the call. Required. Known values + are: "received", "validated", "admitted", "answering", "answered", "media_connected", + "agent_session_ready", "bridging", "managing", "completed", "rejected", and "failed". + :vartype phase: str or ~azure.ai.projects.models.TelephonyCallPhase + :ivar started_at: The Unix timestamp (in seconds) for when the inbound webhook was received. + Required. + :vartype started_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported the call as + answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call ended. + :vartype ended_at: ~datetime.datetime + :ivar duration_ms: The call duration. + :vartype duration_ms: ~datetime.timedelta + :ivar end_reason: The service-generated reason that the call ended. + :vartype end_reason: str + :ivar provider_status_code: The provider status code associated with the terminal result. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the terminal result. + :vartype provider_sub_code: int + :ivar provider_message: The provider message associated with the terminal result. + :vartype provider_message: str + :ivar timing: Detailed provider-neutral call timing. Required. + :vartype timing: ~azure.ai.projects.models.TelephonyCallTiming + :ivar trace: Correlation to the customer-facing Foundry trace. + :vartype trace: ~azure.ai.projects.models.TelephonyCallTrace + :ivar events: The lifecycle timeline. Required. + :vartype events: list[~azure.ai.projects.models.TelephonyCallLifecycleEvent] + :ivar events_truncated: Whether older lifecycle events were omitted from the timeline. + Required. + :vartype events_truncated: bool + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call identifier. Required.""" + provider: Union[str, "_models.TelephonyProvider"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + provider_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider-assigned call identifier, when available.""" + caller_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller's phone number, when supplied by the provider.""" + provider_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Teams Phone Extension or Twilio number that received the call.""" + status: Union[str, "_models.TelephonyCallStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the call. Required. Known values are: \"in_progress\", \"success\", and + \"failed\".""" + phase: Union[str, "_models.TelephonyCallPhase"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-neutral lifecycle phase reached by the call. Required. Known values are: + \"received\", \"validated\", \"admitted\", \"answering\", \"answered\", \"media_connected\", + \"agent_session_ready\", \"bridging\", \"managing\", \"completed\", \"rejected\", and + \"failed\".""" + started_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the inbound webhook was received. Required.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported the call as answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call ended.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The call duration.""" + end_reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated reason that the call ended.""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the terminal result.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the terminal result.""" + provider_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider message associated with the terminal result.""" + timing: "_models.TelephonyCallTiming" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Detailed provider-neutral call timing. Required.""" + trace: Optional["_models.TelephonyCallTrace"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Correlation to the customer-facing Foundry trace.""" + events: list["_models.TelephonyCallLifecycleEvent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle timeline. Required.""" + events_truncated: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether older lifecycle events were omitted from the timeline. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: Union[str, "_models.TelephonyProvider"], + status: Union[str, "_models.TelephonyCallStatus"], + phase: Union[str, "_models.TelephonyCallPhase"], + started_at: datetime.datetime, + timing: "_models.TelephonyCallTiming", + events: list["_models.TelephonyCallLifecycleEvent"], + events_truncated: bool, + provider_call_id: Optional[str] = None, + caller_number: Optional[str] = None, + provider_number: Optional[str] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_ms: Optional[datetime.timedelta] = None, + end_reason: Optional[str] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + provider_message: Optional[str] = None, + trace: Optional["_models.TelephonyCallTrace"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallSummary(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A summary of a durable inbound call to a voice agent. + + :ivar id: The service-generated call identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar provider_call_id: The provider-assigned call identifier, when available. + :vartype provider_call_id: str + :ivar caller_number: The caller's phone number, when supplied by the provider. + :vartype caller_number: str + :ivar provider_number: The Teams Phone Extension or Twilio number that received the call. + :vartype provider_number: str + :ivar status: The lifecycle status of the call. Required. Known values are: "in_progress", + "success", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :ivar phase: The provider-neutral lifecycle phase reached by the call. Required. Known values + are: "received", "validated", "admitted", "answering", "answered", "media_connected", + "agent_session_ready", "bridging", "managing", "completed", "rejected", and "failed". + :vartype phase: str or ~azure.ai.projects.models.TelephonyCallPhase + :ivar started_at: The Unix timestamp (in seconds) for when the inbound webhook was received. + Required. + :vartype started_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported the call as + answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call ended. + :vartype ended_at: ~datetime.datetime + :ivar duration_ms: The call duration. + :vartype duration_ms: ~datetime.timedelta + :ivar end_reason: The service-generated reason that the call ended. + :vartype end_reason: str + :ivar provider_status_code: The provider status code associated with the terminal result. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the terminal result. + :vartype provider_sub_code: int + :ivar provider_message: The provider message associated with the terminal result. + :vartype provider_message: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call identifier. Required.""" + provider: Union[str, "_models.TelephonyProvider"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + provider_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider-assigned call identifier, when available.""" + caller_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller's phone number, when supplied by the provider.""" + provider_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Teams Phone Extension or Twilio number that received the call.""" + status: Union[str, "_models.TelephonyCallStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the call. Required. Known values are: \"in_progress\", \"success\", and + \"failed\".""" + phase: Union[str, "_models.TelephonyCallPhase"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-neutral lifecycle phase reached by the call. Required. Known values are: + \"received\", \"validated\", \"admitted\", \"answering\", \"answered\", \"media_connected\", + \"agent_session_ready\", \"bridging\", \"managing\", \"completed\", \"rejected\", and + \"failed\".""" + started_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the inbound webhook was received. Required.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported the call as answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call ended.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The call duration.""" + end_reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated reason that the call ended.""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the terminal result.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the terminal result.""" + provider_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider message associated with the terminal result.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: Union[str, "_models.TelephonyProvider"], + status: Union[str, "_models.TelephonyCallStatus"], + phase: Union[str, "_models.TelephonyCallPhase"], + started_at: datetime.datetime, + provider_call_id: Optional[str] = None, + caller_number: Optional[str] = None, + provider_number: Optional[str] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_ms: Optional[datetime.timedelta] = None, + end_reason: Optional[str] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + provider_message: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallTiming(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Detailed provider-neutral timing for an inbound telephony call. + + :ivar received_at: The Unix timestamp (in seconds) for when the provider webhook was received. + :vartype received_at: ~datetime.datetime + :ivar validated_at: The Unix timestamp (in seconds) for when webhook validation completed. + :vartype validated_at: ~datetime.datetime + :ivar admitted_at: The Unix timestamp (in seconds) for when the call was admitted to an agent + binding. + :vartype admitted_at: ~datetime.datetime + :ivar answer_requested_at: The Unix timestamp (in seconds) for when the service requested that + the provider answer the call. + :vartype answer_requested_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported that the call + was answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar first_caller_audio_at: The Unix timestamp (in seconds) for when caller audio was first + observed. + :vartype first_caller_audio_at: ~datetime.datetime + :ivar first_agent_audio_at: The Unix timestamp (in seconds) for when agent audio was first + observed. + :vartype first_agent_audio_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call reached a terminal state. + :vartype ended_at: ~datetime.datetime + :ivar duration_basis: The timestamp used as the basis for duration. Known values are: + "answered" and "received". + :vartype duration_basis: str or ~azure.ai.projects.models.TelephonyCallDurationBasis + :ivar timestamp_source: The primary source of the timing milestones. Individual lifecycle + events identify their own timestamp source separately. Required. Known values are: "provider", + "gateway", and "derived". + :vartype timestamp_source: str or ~azure.ai.projects.models.TelephonyCallTimestampSource + """ + + received_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider webhook was received.""" + validated_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when webhook validation completed.""" + admitted_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call was admitted to an agent binding.""" + answer_requested_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the service requested that the provider answer the + call.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported that the call was answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + first_caller_audio_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when caller audio was first observed.""" + first_agent_audio_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when agent audio was first observed.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call reached a terminal state.""" + duration_basis: Optional[Union[str, "_models.TelephonyCallDurationBasis"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The timestamp used as the basis for duration. Known values are: \"answered\" and \"received\".""" + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The primary source of the timing milestones. Individual lifecycle events identify their own + timestamp source separately. Required. Known values are: \"provider\", \"gateway\", and + \"derived\".""" + + @overload + def __init__( + self, + *, + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"], + received_at: Optional[datetime.datetime] = None, + validated_at: Optional[datetime.datetime] = None, + admitted_at: Optional[datetime.datetime] = None, + answer_requested_at: Optional[datetime.datetime] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + first_caller_audio_at: Optional[datetime.datetime] = None, + first_agent_audio_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_basis: Optional[Union[str, "_models.TelephonyCallDurationBasis"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallTrace(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Correlation from a durable telephony call record to its customer-facing Foundry trace. + + :ivar status: The trace availability status. Required. Known values are: "pending", "emitting", + "available", "not_recorded", "not_applicable", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallTraceStatus + :ivar trace_id: The W3C trace identifier, when a trace was recorded. + :vartype trace_id: str + :ivar root_span_id: The root span identifier, when a trace was recorded. + :vartype root_span_id: str + :ivar conversation_id: The voice-agent conversation identifier, when a conversation was + created. + :vartype conversation_id: str + :ivar mode: Whether the trace was emitted live or after the call ended. Known values are: + "live" and "post_call". + :vartype mode: str or ~azure.ai.projects.models.TelephonyCallTraceMode + """ + + status: Union[str, "_models.TelephonyCallTraceStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The trace availability status. Required. Known values are: \"pending\", \"emitting\", + \"available\", \"not_recorded\", \"not_applicable\", and \"failed\".""" + trace_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The W3C trace identifier, when a trace was recorded.""" + root_span_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The root span identifier, when a trace was recorded.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice-agent conversation identifier, when a conversation was created.""" + mode: Optional[Union[str, "_models.TelephonyCallTraceMode"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Whether the trace was emitted live or after the call ended. Known values are: \"live\" and + \"post_call\".""" + + @overload + def __init__( + self, + *, + status: Union[str, "_models.TelephonyCallTraceStatus"], + trace_id: Optional[str] = None, + root_span_id: Optional[str] = None, + conversation_id: Optional[str] = None, + mode: Optional[Union[str, "_models.TelephonyCallTraceMode"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCampaign(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A durable outbound campaign owned by a voice agent. + + :ivar display_name: A customer-visible name for the campaign. Required. + :vartype display_name: str + :ivar telephony_binding_id: The active agent telephony binding used to originate campaign + calls. Required. + :vartype telephony_binding_id: str + :ivar purpose: An optional customer-declared purpose for campaign calls. + :vartype purpose: str + :ivar schedule: When the published campaign becomes eligible to dispatch calls. + :vartype schedule: ~azure.ai.projects.models.TelephonyCampaignSchedule + :ivar id: Required. + :vartype id: str + :ivar object: Required. Default value is "telephony.campaign". + :vartype object: str + :ivar agent_name: Required. + :vartype agent_name: str + :ivar configuration_status: Required. Known values are: "draft", "importing", "validating", + "publishing", "published", and "publish_failed". + :vartype configuration_status: str or + ~azure.ai.projects.models.TelephonyCampaignConfigurationStatus + :ivar execution_status: Required. Known values are: "none", "scheduled", "running", "paused", + "completed", "failed", and "cancelled". + :vartype execution_status: str or ~azure.ai.projects.models.TelephonyCampaignExecutionStatus + :ivar retry_policy: Required. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicyResponse + :ivar latest_successful_validation_id: + :vartype latest_successful_validation_id: str + :ivar active_validation_id: + :vartype active_validation_id: str + :ivar active_recipient_import_id: + :vartype active_recipient_import_id: str + :ivar published_at: + :vartype published_at: ~datetime.datetime + :ivar call_job_counts: Required. + :vartype call_job_counts: ~azure.ai.projects.models.TelephonyCampaignCallJobCounts + :ivar created_at: Required. + :vartype created_at: ~datetime.datetime + :ivar updated_at: Required. + :vartype updated_at: ~datetime.datetime + """ + + display_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A customer-visible name for the campaign. Required.""" + telephony_binding_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The active agent telephony binding used to originate campaign calls. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for campaign calls.""" + schedule: Optional["_models.TelephonyCampaignSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the published campaign becomes eligible to dispatch calls.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + object: Literal["telephony.campaign"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. Default value is \"telephony.campaign\".""" + agent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + configuration_status: Union[str, "_models.TelephonyCampaignConfigurationStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"draft\", \"importing\", \"validating\", \"publishing\", + \"published\", and \"publish_failed\".""" + execution_status: Union[str, "_models.TelephonyCampaignExecutionStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"none\", \"scheduled\", \"running\", \"paused\", \"completed\", + \"failed\", and \"cancelled\".""" + retry_policy: "_models.TelephonyOutboundRetryPolicyResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + latest_successful_validation_id: Optional[str] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + active_validation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + active_recipient_import_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + published_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + call_job_counts: "_models.TelephonyCampaignCallJobCounts" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Required.""" + updated_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Required.""" + + @overload + def __init__( + self, + *, + display_name: str, + telephony_binding_id: str, + id: str, # pylint: disable=redefined-builtin + agent_name: str, + configuration_status: Union[str, "_models.TelephonyCampaignConfigurationStatus"], + execution_status: Union[str, "_models.TelephonyCampaignExecutionStatus"], + retry_policy: "_models.TelephonyOutboundRetryPolicyResponse", + call_job_counts: "_models.TelephonyCampaignCallJobCounts", + created_at: datetime.datetime, + updated_at: datetime.datetime, + purpose: Optional[str] = None, + schedule: Optional["_models.TelephonyCampaignSchedule"] = None, + latest_successful_validation_id: Optional[str] = None, + active_validation_id: Optional[str] = None, + active_recipient_import_id: Optional[str] = None, + published_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.object: Literal["telephony.campaign"] = "telephony.campaign" + + +class TelephonyCampaignCallJobCounts(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Aggregate call-job counts for an outbound campaign. + + :ivar total: Required. + :vartype total: int + :ivar pending: Required. + :vartype pending: int + :ivar in_progress: Required. + :vartype in_progress: int + :ivar completed: Required. + :vartype completed: int + :ivar failed: Required. + :vartype failed: int + :ivar blocked: Required. + :vartype blocked: int + :ivar cancelled: Required. + :vartype cancelled: int + :ivar expired: Required. + :vartype expired: int + """ + + total: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + pending: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + in_progress: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + completed: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + failed: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + blocked: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + cancelled: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + expired: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + total: int, + pending: int, + in_progress: int, + completed: int, + failed: int, + blocked: int, + cancelled: int, + expired: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCampaignRecipientImport(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A durable campaign recipient-import record. + + :ivar id: Required. + :vartype id: str + :ivar object: Required. Default value is "telephony.campaign.recipient_import". + :vartype object: str + :ivar campaign_id: Required. + :vartype campaign_id: str + :ivar status: Required. Known values are: "running", "succeeded", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCampaignRecipientImportStatus + :ivar source: Required. + :vartype source: ~azure.ai.projects.models.TelephonyCampaignRecipientImportSource + :ivar mapping: + :vartype mapping: ~azure.ai.projects.models.TelephonyCampaignRecipientMapping + :ivar duplicate_handling: Required. Known values are: "reject", "keep_each", and "merge". + :vartype duplicate_handling: str or + ~azure.ai.projects.models.TelephonyCampaignDuplicateHandling + :ivar rows_processed: Required. + :vartype rows_processed: int + :ivar eligible_recipient_count: Required. + :vartype eligible_recipient_count: int + :ivar invalid_recipient_count: Required. + :vartype invalid_recipient_count: int + :ivar error_code: + :vartype error_code: str + :ivar error_message: + :vartype error_message: str + :ivar created_at: Required. + :vartype created_at: ~datetime.datetime + :ivar updated_at: Required. + :vartype updated_at: ~datetime.datetime + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + object: Literal["telephony.campaign.recipient_import"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Default value is \"telephony.campaign.recipient_import\".""" + campaign_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + status: Union[str, "_models.TelephonyCampaignRecipientImportStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"running\", \"succeeded\", and \"failed\".""" + source: "_models.TelephonyCampaignRecipientImportSource" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + mapping: Optional["_models.TelephonyCampaignRecipientMapping"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + duplicate_handling: Union[str, "_models.TelephonyCampaignDuplicateHandling"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"reject\", \"keep_each\", and \"merge\".""" + rows_processed: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + eligible_recipient_count: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + invalid_recipient_count: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + error_code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + error_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Required.""" + updated_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + campaign_id: str, + status: Union[str, "_models.TelephonyCampaignRecipientImportStatus"], + source: "_models.TelephonyCampaignRecipientImportSource", + duplicate_handling: Union[str, "_models.TelephonyCampaignDuplicateHandling"], + rows_processed: int, + eligible_recipient_count: int, + invalid_recipient_count: int, + created_at: datetime.datetime, + updated_at: datetime.datetime, + mapping: Optional["_models.TelephonyCampaignRecipientMapping"] = None, + error_code: Optional[str] = None, + error_message: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.object: Literal["telephony.campaign.recipient_import"] = "telephony.campaign.recipient_import" + + +class TelephonyCampaignRecipientImportSource(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Dataset source for campaign recipient import. + + :ivar type: Required. Default value is "dataset". + :vartype type: str + :ivar dataset_name: Required. + :vartype dataset_name: str + :ivar dataset_version: Required. + :vartype dataset_version: str + :ivar file_name: A relative path to a CSV, JSON array, or JSONL file in the Dataset version. + Required. + :vartype file_name: str + :ivar format: Required. Known values are: "csv", "json", and "jsonl". + :vartype format: str or ~azure.ai.projects.models.TelephonyCampaignRecipientImportFormat + """ + + type: Literal["dataset"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. Default value is \"dataset\".""" + dataset_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + dataset_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + file_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A relative path to a CSV, JSON array, or JSONL file in the Dataset version. Required.""" + format: Union[str, "_models.TelephonyCampaignRecipientImportFormat"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"csv\", \"json\", and \"jsonl\".""" + + @overload + def __init__( + self, + *, + dataset_name: str, + dataset_version: str, + file_name: str, + format: Union[str, "_models.TelephonyCampaignRecipientImportFormat"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type: Literal["dataset"] = "dataset" + + +class TelephonyCampaignRecipientMapping(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Source fields or CSV columns mapped into each campaign recipient. Every unmapped CSV column or + JSON/JSONL top-level property becomes a same-named structured input. CSV cells are preserved as + strings until Agent-declared inputs are parsed according to their schemas; additional inputs + remain strings. + + :ivar destination: The source field containing the destination E.164 phone number. Defaults to + ``destination``. The source field is required for each recipient. Required. + :vartype destination: str + :ivar recipient_key: The source field containing the recipient key. Defaults to + ``recipient_key``. The source field is required for each recipient. Required. + :vartype recipient_key: str + :ivar recipient_item_key: The source field containing the recipient item key. Defaults to + ``recipient_item_key``. The source field is required when ``duplicate_handling`` is + ``keep_each``; otherwise it may be absent. + :vartype recipient_item_key: str + :ivar not_before: The source field containing the earliest dispatch time as a Unix timestamp in + seconds. Defaults to ``not_before``. If the source field is absent, no per-recipient start + bound is applied. + :vartype not_before: str + :ivar expires_at: The source field containing the expiry time as a Unix timestamp in seconds. + Defaults to ``expires_at``. If the source field is absent, no per-recipient expiry bound is + applied. + :vartype expires_at: str + """ + + destination: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the destination E.164 phone number. Defaults to ``destination``. + The source field is required for each recipient. Required.""" + recipient_key: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the recipient key. Defaults to ``recipient_key``. The source field + is required for each recipient. Required.""" + recipient_item_key: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the recipient item key. Defaults to ``recipient_item_key``. The + source field is required when ``duplicate_handling`` is ``keep_each``; otherwise it may be + absent.""" + not_before: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the earliest dispatch time as a Unix timestamp in seconds. Defaults + to ``not_before``. If the source field is absent, no per-recipient start bound is applied.""" + expires_at: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the expiry time as a Unix timestamp in seconds. Defaults to + ``expires_at``. If the source field is absent, no per-recipient expiry bound is applied.""" + + @overload + def __init__( + self, + *, + destination: str, + recipient_key: str, + recipient_item_key: Optional[str] = None, + not_before: Optional[str] = None, + expires_at: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCampaignRecipientMappingRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Optional source-field mappings for a recipient import. Each omitted entry uses its same-named + source field. + + :ivar destination: The source field containing the destination E.164 phone number. Defaults to + ``destination``. The source field is required for each recipient. + :vartype destination: str + :ivar recipient_key: The source field containing the recipient key. Defaults to + ``recipient_key``. The source field is required for each recipient. + :vartype recipient_key: str + :ivar recipient_item_key: The source field containing the recipient item key. Defaults to + ``recipient_item_key``. The source field is required when ``duplicate_handling`` is + ``keep_each``; otherwise it may be absent. + :vartype recipient_item_key: str + :ivar not_before: The source field containing the earliest dispatch time as a Unix timestamp in + seconds. Defaults to ``not_before``. If the source field is absent, no per-recipient start + bound is applied. + :vartype not_before: str + :ivar expires_at: The source field containing the expiry time as a Unix timestamp in seconds. + Defaults to ``expires_at``. If the source field is absent, no per-recipient expiry bound is + applied. + :vartype expires_at: str + """ + + destination: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the destination E.164 phone number. Defaults to ``destination``. + The source field is required for each recipient.""" + recipient_key: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the recipient key. Defaults to ``recipient_key``. The source field + is required for each recipient.""" + recipient_item_key: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the recipient item key. Defaults to ``recipient_item_key``. The + source field is required when ``duplicate_handling`` is ``keep_each``; otherwise it may be + absent.""" + not_before: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the earliest dispatch time as a Unix timestamp in seconds. Defaults + to ``not_before``. If the source field is absent, no per-recipient start bound is applied.""" + expires_at: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The source field containing the expiry time as a Unix timestamp in seconds. Defaults to + ``expires_at``. If the source field is absent, no per-recipient expiry bound is applied.""" + + @overload + def __init__( + self, + *, + destination: Optional[str] = None, + recipient_key: Optional[str] = None, + recipient_item_key: Optional[str] = None, + not_before: Optional[str] = None, + expires_at: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCampaignSchedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The schedule for an outbound campaign. + + :ivar type: Whether calls are eligible immediately after publication or at a future instant. + Required. Known values are: "immediate" and "scheduled". + :vartype type: str or ~azure.ai.projects.models.TelephonyCampaignScheduleType + :ivar start_at: The scheduled start instant. Required only when ``type`` is ``scheduled``. + :vartype start_at: ~datetime.datetime + """ + + type: Union[str, "_models.TelephonyCampaignScheduleType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Whether calls are eligible immediately after publication or at a future instant. Required. + Known values are: \"immediate\" and \"scheduled\".""" + start_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The scheduled start instant. Required only when ``type`` is ``scheduled``.""" + + @overload + def __init__( + self, + *, + type: Union[str, "_models.TelephonyCampaignScheduleType"], + start_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOperation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An asynchronous outbound telephony operation. + + :ivar id: Required. + :vartype id: str + :ivar object: Required. Default value is "telephony.operation". + :vartype object: str + :ivar status: Required. Known values are: "not_started", "running", "succeeded", "failed", + "cancelled", and "unknown". + :vartype status: str or ~azure.ai.projects.models.TelephonyOperationStatus + :ivar created_at: + :vartype created_at: ~datetime.datetime + :ivar error: + :vartype error: ~azure.ai.projects.models.ApiError + :ivar resource: + :vartype resource: ~azure.ai.projects.models.TelephonyOperationResource + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + object: Literal["telephony.operation"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. Default value is \"telephony.operation\".""" + status: Union[str, "_models.TelephonyOperationStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required. Known values are: \"not_started\", \"running\", \"succeeded\", \"failed\", + \"cancelled\", and \"unknown\".""" + created_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + error: Optional["_models.ApiError"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + resource: Optional["_models.TelephonyOperationResource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + status: Union[str, "_models.TelephonyOperationStatus"], + created_at: Optional[datetime.datetime] = None, + error: Optional["_models.ApiError"] = None, + resource: Optional["_models.TelephonyOperationResource"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.object: Literal["telephony.operation"] = "telephony.operation" + + +class TelephonyOperationResource(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A resource produced by a successful outbound telephony operation. + + :ivar id: Required. + :vartype id: str + :ivar type: Required. + :vartype type: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundDestination(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The destination of an outbound call. + + :ivar type: The destination type. Only E.164 phone numbers are currently supported. Required. + "phone_number" + :vartype type: str or ~azure.ai.projects.models.TelephonyOutboundDestinationType + :ivar value: The destination E.164 phone number. Required. + :vartype value: str + """ + + type: Union[str, "_models.TelephonyOutboundDestinationType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The destination type. Only E.164 phone numbers are currently supported. Required. + \"phone_number\"""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The destination E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + type: Union[str, "_models.TelephonyOutboundDestinationType"], + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundRetryPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The retry policy for one durable outbound call intent. ``max_attempts`` includes the first + attempt. Strategy-specific settings are defined by the derived policy. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TelephonyOutboundFixedIntervalRetryPolicy + + :ivar type: The retry strategy. Only fixed-interval retries are currently supported. Required. + "fixed_interval" + :vartype type: str or ~azure.ai.projects.models.TelephonyOutboundRetryPolicyType + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Defaults to 1. + :vartype max_attempts: int + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The retry strategy. Only fixed-interval retries are currently supported. Required. + \"fixed_interval\"""" + max_attempts: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The maximum number of provider attempts, including the first attempt. Defaults to 1.""" + + @overload + def __init__( + self, + *, + type: str, + max_attempts: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundFixedIntervalRetryPolicy( + TelephonyOutboundRetryPolicy, discriminator="fixed_interval" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """A retry policy with a fixed interval between outbound call attempts. + + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Defaults to 1. + :vartype max_attempts: int + :ivar type: The fixed-interval retry strategy. Required. Retry after a fixed interval between + attempts. + :vartype type: str or ~azure.ai.projects.models.FIXED_INTERVAL + :ivar interval: The fixed delay in seconds between attempts. It must be 0 when ``max_attempts`` + is 1, and from 60 through 86400 when retries are enabled. + :vartype interval: ~datetime.timedelta + """ + + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The fixed-interval retry strategy. Required. Retry after a fixed interval between attempts.""" + interval: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The fixed delay in seconds between attempts. It must be 0 when ``max_attempts`` is 1, and from + 60 through 86400 when retries are enabled.""" + + @overload + def __init__( + self, + *, + max_attempts: Optional[int] = None, + interval: Optional[datetime.timedelta] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TelephonyOutboundRetryPolicyType.FIXED_INTERVAL # type: ignore + + +class TelephonyOutboundRetryPolicyResponse(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The frozen retry policy returned for an outbound call or campaign. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TelephonyOutboundFixedIntervalRetryPolicyResponse + + :ivar type: The retry strategy. Required. "fixed_interval" + :vartype type: str or ~azure.ai.projects.models.TelephonyOutboundRetryPolicyType + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Required. + :vartype max_attempts: int + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The retry strategy. Required. \"fixed_interval\"""" + max_attempts: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The maximum number of provider attempts, including the first attempt. Required.""" + + @overload + def __init__( + self, + *, + type: str, + max_attempts: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundFixedIntervalRetryPolicyResponse( + TelephonyOutboundRetryPolicyResponse, discriminator="fixed_interval" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The frozen fixed-interval retry policy returned for an outbound call or campaign. + + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Required. + :vartype max_attempts: int + :ivar type: The fixed-interval retry strategy. Required. Retry after a fixed interval between + attempts. + :vartype type: str or ~azure.ai.projects.models.FIXED_INTERVAL + :ivar interval: The fixed delay in seconds between attempts. Required. + :vartype interval: ~datetime.timedelta + """ + + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The fixed-interval retry strategy. Required. Retry after a fixed interval between attempts.""" + interval: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The fixed delay in seconds between attempts. Required.""" + + @overload + def __init__( + self, + *, + max_attempts: int, + interval: datetime.timedelta, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TelephonyOutboundRetryPolicyType.FIXED_INTERVAL # type: ignore + + +class TelephonyTransferTarget(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A named destination to which the voice agent may transfer a call. + + :ivar name: The unique name exposed to the voice agent for this transfer target. Required. + :vartype name: str + :ivar description: A description that helps the voice agent decide when to use this target. + Required. + :vartype description: str + :ivar destination: The provider-specific transfer destination. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyTransferDestination + """ + + name: str = rest_field(visibility=["read", "create"]) + """The unique name exposed to the voice agent for this transfer target. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description that helps the voice agent decide when to use this target. Required.""" + destination: "_models.TelephonyTransferDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-specific transfer destination. Required.""" + + @overload + def __init__( + self, + *, + name: str, + description: str, + destination: "_models.TelephonyTransferDestination", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyTransferTargets(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The telephony transfer targets configured for one voice agent. + + :ivar transfer_targets: The complete set of destinations to which the voice agent may transfer + calls. An empty array clears all targets when replacing the configuration. Required. + :vartype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + """ + + transfer_targets: list["_models.TelephonyTransferTarget"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The complete set of destinations to which the voice agent may transfer calls. An empty array + clears all targets when replacing the configuration. Required.""" + + @overload + def __init__( + self, + *, + transfer_targets: list["_models.TelephonyTransferTarget"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TextResponseFormat(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An object specifying the format that the model must output. Configuring ``{ "type": + "json_schema" }`` enables Structured Outputs, which ensures the model will match your supplied + JSON schema. Learn more in the `Structured Outputs guide `_. + The default format is ``{ "type": "text" }`` with no additional options. *Not recommended for + gpt-4o and newer models:** Setting to ``{ "type": "json_object" }`` enables the older JSON + mode, which ensures the message the model generates is valid JSON. Using ``json_schema`` is + preferred for models that support it. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TextResponseFormatJsonObject, TextResponseFormatJsonSchema, TextResponseFormatText + + :ivar type: Required. Known values are: "text", "json_schema", and "json_object". + :vartype type: str or ~azure.ai.projects.models.TextResponseFormatConfigurationType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"text\", \"json_schema\", and \"json_object\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TextResponseFormatJsonObject(TextResponseFormat, discriminator="json_object"): + """JSON object. + + :ivar type: The type of response format being defined. Always ``json_object``. Required. + JSON_OBJECT. + :vartype type: str or ~azure.ai.projects.models.JSON_OBJECT + """ + + type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``json_object``. Required. JSON_OBJECT.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.JSON_OBJECT # type: ignore + + +class TextResponseFormatJsonSchema( + TextResponseFormat, discriminator="json_schema" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """JSON schema. + + :ivar type: The type of response format being defined. Always ``json_schema``. Required. + JSON_SCHEMA. + :vartype type: str or ~azure.ai.projects.models.JSON_SCHEMA + :ivar description: A description of what the response format is for, used by the model to + determine how to respond in the format. + :vartype description: str + :ivar name: The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and + dashes, with a maximum length of 64. Required. + :vartype name: str + :ivar schema: Required. + :vartype schema: dict[str, any] + :ivar strict: + :vartype strict: bool + """ + + type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``json_schema``. Required. JSON_SCHEMA.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of what the response format is for, used by the model to determine how to respond + in the format.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with + a maximum length of 64. Required.""" + schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + strict: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + name: str, + schema: dict[str, Any], + description: Optional[str] = None, + strict: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.JSON_SCHEMA # type: ignore + + +class TextResponseFormatText(TextResponseFormat, discriminator="text"): + """Text. + + :ivar type: The type of response format being defined. Always ``text``. Required. TEXT. + :vartype type: str or ~azure.ai.projects.models.TEXT + """ + + type: Literal[TextResponseFormatConfigurationType.TEXT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``text``. Required. TEXT.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.TEXT # type: ignore + + +class TimerRoutineTrigger( + RoutineTrigger, discriminator="timer" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A one-shot timer routine trigger. + + :ivar type: The trigger type. Required. A one-shot timer trigger. + :vartype type: str or ~azure.ai.projects.models.TIMER + :ivar at: The UTC date and time at which the timer fires. + :vartype at: ~datetime.datetime + """ + + type: Literal[RoutineTriggerType.TIMER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The trigger type. Required. A one-shot timer trigger.""" + at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The UTC date and time at which the timer fires.""" + + @overload + def __init__( + self, + *, + at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RoutineTriggerType.TIMER # type: ignore + + +class ToolboxObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox that stores reusable tool definitions for agents. + + :ivar id: The unique identifier of the toolbox. Required. + :vartype id: str + :ivar name: The name of the toolbox. Required. + :vartype name: str + :ivar default_version: The version identifier that the toolbox currently points to. Defaults to + the latest version. Can be changed via updateToolbox. Required. + :vartype default_version: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the toolbox. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox. Required.""" + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier that the toolbox currently points to. Defaults to the latest version. + Can be changed via updateToolbox. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + default_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxPolicies(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Policy configuration for a toolbox, including content safety and other governance settings. + + :ivar rai_config: Responsible AI content filtering configuration. + :vartype rai_config: ~azure.ai.projects.models.RaiConfig + """ + + rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Responsible AI content filtering configuration.""" + + @overload + def __init__( + self, + *, + rai_config: Optional["_models.RaiConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxSearchPreviewToolboxTool( + ToolboxTool, discriminator="toolbox_search_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox search tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``toolbox_search_preview``. Required. + TOOLBOX_SEARCH_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH_PREVIEW + """ + + type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox_search_preview``. Required. TOOLBOX_SEARCH_PREVIEW.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.TOOLBOX_SEARCH_PREVIEW # type: ignore + + +class ToolboxShellEnvironment(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An execution environment for a shell tool stored in a toolbox. This environment model is scoped + to toolbox configuration and does not modify the OpenAI shell environment contract. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxShellContainerAutoEnvironment, ToolboxShellContainerReferenceEnvironment + + :ivar type: The type of the shell execution environment. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of the shell execution environment. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxShellContainerAutoEnvironment( + ToolboxShellEnvironment, discriminator="container_auto" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An automatically provisioned container environment for a shell tool stored in a toolbox. + + :ivar type: The type of the shell execution environment. Always ``container_auto``. Required. + Default value is "container_auto". + :vartype type: str + :ivar file_ids: An optional list of uploaded files to make available to your code. + :vartype file_ids: list[str] + :ivar memory_limit: Known values are: "1g", "4g", "16g", and "64g". + :vartype memory_limit: str or ~azure.ai.projects.models.ContainerMemoryLimit + :ivar skills: An optional list of skills referenced by id or inline data. + :vartype skills: list[~azure.ai.projects.models.ContainerSkill] + :ivar network_policy: The network access policy for the container. When omitted, the service + defaults to disabled outbound network access. + :vartype network_policy: ~azure.ai.projects.models.ToolboxShellNetworkPolicy + """ + + type: Literal["container_auto"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the shell execution environment. Always ``container_auto``. Required. Default value + is \"container_auto\".""" + file_ids: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional list of uploaded files to make available to your code.""" + memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"1g\", \"4g\", \"16g\", and \"64g\".""" + skills: Optional[list["_models.ContainerSkill"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """An optional list of skills referenced by id or inline data.""" + network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The network access policy for the container. When omitted, the service defaults to disabled + outbound network access.""" + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = None, + memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = None, + skills: Optional[list["_models.ContainerSkill"]] = None, + network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "container_auto" # type: ignore + + +class ToolboxShellContainerReferenceEnvironment( + ToolboxShellEnvironment, discriminator="container_reference" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """An existing container environment for a shell tool stored in a toolbox. + + :ivar type: The type of the shell execution environment. Always ``container_reference``. + Required. Default value is "container_reference". + :vartype type: str + :ivar container_id: The ID of the referenced container. Required. + :vartype container_id: str + """ + + type: Literal["container_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the shell execution environment. Always ``container_reference``. Required. Default + value is \"container_reference\".""" + container_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the referenced container. Required.""" + + @overload + def __init__( + self, + *, + container_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "container_reference" # type: ignore + + +class ToolboxShellNetworkPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Network access policy for an automatically provisioned toolbox shell container. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxShellNetworkPolicyDisabled + + :ivar type: The type of network access policy. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of network access policy. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator="disabled"): + """A network policy that disables outbound access from a toolbox shell container. + + :ivar type: The type of network access policy. Always ``disabled``. Required. Default value is + "disabled". + :vartype type: str + """ + + type: Literal["disabled"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of network access policy. Always ``disabled``. Required. Default value is + \"disabled\".""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "disabled" # type: ignore + + +class ToolboxSkill(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A skill source included in a toolbox. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxSkillReference + + :ivar type: The type of skill source. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of skill source. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxSkillReference( + ToolboxSkill, discriminator="skill_reference" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reference to an existing skill to include in a toolbox. + + :ivar type: The type of skill source. Required. Default value is "skill_reference". + :vartype type: str + :ivar name: The name of the skill. Required. + :vartype name: str + :ivar version: The version of the skill. If not specified, the skill's default version is used. + When a version is specified, the reference is pinned to that immutable version. + :vartype version: str + """ + + type: Literal["skill_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of skill source. Required. Default value is \"skill_reference\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the skill. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version of the skill. If not specified, the skill's default version is used. When a version + is specified, the reference is pinned to that immutable version.""" + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "skill_reference" # type: ignore + + +class ToolboxVersionObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A specific version of a toolbox. + + :ivar metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Required. + :vartype metadata: dict[str, str] + :ivar id: The unique identifier of the toolbox version. Required. + :vartype id: str + :ivar name: The name of the toolbox. Required. + :vartype name: str + :ivar version: The version identifier of the toolbox. Toolbox versions are immutable and every + update creates a new version. Required. + :vartype version: str + :ivar description: A human-readable description of the toolbox. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the toolbox version was created. Required. + :vartype created_at: ~datetime.datetime + :ivar tools: The list of tools contained in this toolbox version. Required. + :vartype tools: list[~azure.ai.projects.models.ToolboxTool] + :ivar skills: The list of skill sources included in this toolbox version. + :vartype skills: list[~azure.ai.projects.models.ToolboxSkill] + :ivar policies: Policy configuration for the toolbox version. + :vartype policies: ~azure.ai.projects.models.ToolboxPolicies + """ + + metadata: dict[str, str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Required.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the toolbox version. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox. Required.""" + version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier of the toolbox. Toolbox versions are immutable and every update creates + a new version. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the toolbox.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the toolbox version was created. Required.""" + tools: list["_models.ToolboxTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The list of tools contained in this toolbox version. Required.""" + skills: Optional[list["_models.ToolboxSkill"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The list of skill sources included in this toolbox version.""" + policies: Optional["_models.ToolboxPolicies"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Policy configuration for the toolbox version.""" + + @overload + def __init__( + self, + *, + metadata: dict[str, str], + id: str, # pylint: disable=redefined-builtin + name: str, + version: str, + created_at: datetime.datetime, + tools: list["_models.ToolboxTool"], + description: Optional[str] = None, + skills: Optional[list["_models.ToolboxSkill"]] = None, + policies: Optional["_models.ToolboxPolicies"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolChoiceAllowed( + ToolChoiceParam, discriminator="allowed_tools" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Allowed tools. + + :ivar type: Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS. + :vartype type: str or ~azure.ai.projects.models.ALLOWED_TOOLS + :ivar mode: Constrains the tools available to the model to a pre-defined set. ``auto`` allows + the model to pick from among the allowed tools and generate a message. ``required`` requires + the model to call one or more of the allowed tools. Required. Is either a Literal["auto"] type + or a Literal["required"] type. + :vartype mode: str or str + :ivar tools: Required. A list of tool definitions that the model should be allowed to call. For + the Responses API, the list of tool definitions might look like: + + .. code-block:: json + + [ + { "type": "function", "name": "get_weather" }, + { "type": "mcp", "server_label": "deepwiki" }, + { "type": "image_generation" } + ] + :vartype tools: list[dict[str, any]] + """ + + type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS.""" + mode: Literal["auto", "required"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Constrains the tools available to the model to a pre-defined set. ``auto`` allows the model to + pick from among the allowed tools and generate a message. ``required`` requires the model to + call one or more of the allowed tools. Required. Is either a Literal[\"auto\"] type or a + Literal[\"required\"] type.""" + tools: list[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. A list of tool definitions that the model should be allowed to call. For the + Responses API, the list of tool definitions might look like: + + .. code-block:: json + + [ + { \"type\": \"function\", \"name\": \"get_weather\" }, + { \"type\": \"mcp\", \"server_label\": \"deepwiki\" }, + { \"type\": \"image_generation\" } + ]""" + + @overload + def __init__( + self, + *, + mode: Literal["auto", "required"], + tools: list[dict[str, Any]], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.ALLOWED_TOOLS # type: ignore + + +class ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator="code_interpreter"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. CODE_INTERPRETER. + :vartype type: str or ~azure.ai.projects.models.CODE_INTERPRETER + """ + + type: Literal[ToolChoiceParamType.CODE_INTERPRETER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. CODE_INTERPRETER.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.CODE_INTERPRETER # type: ignore + + +class ToolChoiceComputer(ToolChoiceParam, discriminator="computer"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER. + :vartype type: str or ~azure.ai.projects.models.COMPUTER + """ + + type: Literal[ToolChoiceParamType.COMPUTER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER # type: ignore + + +class ToolChoiceComputerUse(ToolChoiceParam, discriminator="computer_use"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER_USE. + :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE + """ + + type: Literal[ToolChoiceParamType.COMPUTER_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER_USE.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER_USE # type: ignore + + +class ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator="computer_use_preview"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER_USE_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE_PREVIEW + """ + + type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER_USE_PREVIEW.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER_USE_PREVIEW # type: ignore + + +class ToolChoiceCustom( + ToolChoiceParam, discriminator="custom" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Custom tool. + + :ivar type: For custom tool calling, the type is always ``custom``. Required. CUSTOM. + :vartype type: str or ~azure.ai.projects.models.CUSTOM + :ivar name: The name of the custom tool to call. Required. + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.CUSTOM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For custom tool calling, the type is always ``custom``. Required. CUSTOM.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the custom tool to call. Required.""" + + @overload + def __init__( + self, + *, + name: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.CUSTOM # type: ignore + + +class ToolChoiceFileSearch(ToolChoiceParam, discriminator="file_search"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. FILE_SEARCH. + :vartype type: str or ~azure.ai.projects.models.FILE_SEARCH + """ + + type: Literal[ToolChoiceParamType.FILE_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. FILE_SEARCH.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.FILE_SEARCH # type: ignore + + +class ToolChoiceFunction( + ToolChoiceParam, discriminator="function" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Function tool. + + :ivar type: For function calling, the type is always ``function``. Required. FUNCTION. + :vartype type: str or ~azure.ai.projects.models.FUNCTION + :ivar name: The name of the function to call. Required. + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.FUNCTION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For function calling, the type is always ``function``. Required. FUNCTION.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function to call. Required.""" + + @overload + def __init__( + self, + *, + name: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.FUNCTION # type: ignore + + +class ToolChoiceImageGeneration(ToolChoiceParam, discriminator="image_generation"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. IMAGE_GENERATION. + :vartype type: str or ~azure.ai.projects.models.IMAGE_GENERATION + """ + + type: Literal[ToolChoiceParamType.IMAGE_GENERATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. IMAGE_GENERATION.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.IMAGE_GENERATION # type: ignore + + +class ToolChoiceMCP( + ToolChoiceParam, discriminator="mcp" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """MCP tool. + + :ivar type: For MCP tools, the type is always ``mcp``. Required. MCP. + :vartype type: str or ~azure.ai.projects.models.MCP + :ivar server_label: The label of the MCP server to use. Required. + :vartype server_label: str + :ivar name: + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.MCP] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For MCP tools, the type is always ``mcp``. Required. MCP.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server to use. Required.""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + server_label: str, + name: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.MCP # type: ignore + + +class ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator="web_search_preview"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. WEB_SEARCH_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW + """ + + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WEB_SEARCH_PREVIEW.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW # type: ignore + + +class ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator="web_search_preview_2025_03_11"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. WEB_SEARCH_PREVIEW_2025_03_11. + :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW_2025_03_11 + """ + + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WEB_SEARCH_PREVIEW_2025_03_11.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11 # type: ignore + + +class ToolConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Per-tool configuration that controls tool visibility and search behavior. + + :ivar pin: When true, the tool is always included in agent context and visible in + ``tools/list``. When false (default), the tool is hidden from ``tools/list`` and only + discoverable via ``tool_search``. + :vartype pin: bool + :ivar additional_search_text: Additional text indexed for tool_search. Supplements the native + tool description to improve discoverability. Does not alter ``tools/list`` output. + :vartype additional_search_text: str + """ + + pin: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """When true, the tool is always included in agent context and visible in ``tools/list``. When + false (default), the tool is hidden from ``tools/list`` and only discoverable via + ``tool_search``.""" + additional_search_text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional text indexed for tool_search. Supplements the native tool description to improve + discoverability. Does not alter ``tools/list`` output.""" + + @overload + def __init__( + self, + *, + pin: Optional[bool] = None, + additional_search_text: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolDescription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Description of a tool that can be used by an agent. + + :ivar name: The name of the tool. + :vartype name: str + :ivar description: A brief description of the tool's purpose. + :vartype description: str + """ + + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A brief description of the tool's purpose.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolProjectConnection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A project connection resource. + + :ivar project_connection_id: A project connection in a ToolProjectConnectionList attached to + this tool. Required. + :vartype project_connection_id: str + """ + + project_connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A project connection in a ToolProjectConnectionList attached to this tool. Required.""" + + @overload + def __init__( + self, + *, + project_connection_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolSearchToolboxTool( + ToolboxTool, discriminator="toolbox_search" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox search tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH. + :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH + """ + + type: Literal[ToolboxToolType.TOOLBOX_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.TOOLBOX_SEARCH # type: ignore + + +class ToolSearchToolParam( + Tool, discriminator="tool_search" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Tool search tool. + + :ivar type: The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH. + :vartype type: str or ~azure.ai.projects.models.TOOL_SEARCH + :ivar execution: Whether tool search is executed by the server or by the client. Known values + are: "server" and "client". + :vartype execution: str or ~azure.ai.projects.models.ToolSearchExecutionType + :ivar description: + :vartype description: str + :ivar parameters: + :vartype parameters: ~azure.ai.projects.models.EmptyModelParam + """ + + type: Literal[ToolType.TOOL_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH.""" + execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Whether tool search is executed by the server or by the client. Known values are: \"server\" + and \"client\".""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + parameters: Optional["_models.EmptyModelParam"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = None, + description: Optional[str] = None, + parameters: Optional["_models.EmptyModelParam"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolType.TOOL_SEARCH # type: ignore + + +class ToolUseFineTuningDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="tool_use" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The options for a data generation job with ToolUse type. Used only for fine-tuning scenarios. + + :ivar max_samples: Maximum number of samples to generate. Required. + :vartype max_samples: int + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is ToolUse for this model. Required. Tool + calling conversation between user and agent. + :vartype type: str or ~azure.ai.projects.models.TOOL_USE + """ + + type: Literal[DataGenerationJobType.TOOL_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is ToolUse for this model. Required. Tool calling + conversation between user and agent.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.TOOL_USE # type: ignore + + +class TracesDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a data generation job with Traces type. + + :ivar max_samples: Maximum number of samples to generate. Required. + :vartype max_samples: int + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is Traces for this model. Required. Single turn + query and response from agent traces. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar redact_private_content: Whether to redact private content from traces. When omitted or + set to true, private content is redacted. Set to false to opt out of redaction. + :vartype redact_private_content: bool + """ + + type: Literal[DataGenerationJobType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is Traces for this model. Required. Single turn query and + response from agent traces.""" + redact_private_content: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether to redact private content from traces. When omitted or set to true, private content is + redacted. Set to false to opt out of redaction.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + redact_private_content: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.TRACES # type: ignore + + +class TracesDataGenerationJobSource( + DataGenerationJobSource, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Traces source for data generation jobs — conversation traces from Application Insights. + + :ivar description: Optional description of what this source represents — helps the pipeline + interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core + capabilities'). + :vartype description: str + :ivar type: The source type for this source, which is Traces. Required. Traces source — + conversation traces from Application Insights. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_id: str + :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_name: str + :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent + are included within the time window. + :vartype agent_version: str + :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + Required. + :vartype start_time: ~datetime.datetime + :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. + :vartype end_time: ~datetime.datetime + """ + + type: Literal[DataGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The source type for this source, which is Traces. Required. Traces source — conversation traces + from Application Insights.""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at + least one is required.""" + agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least + one is required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version. If not specified, traces for ALL versions of the agent are included within + the time window.""" + start_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" + end_time: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + + @overload + def __init__( + self, + *, + start_time: datetime.datetime, + description: Optional[str] = None, + agent_id: Optional[str] = None, + agent_name: Optional[str] = None, + agent_version: Optional[str] = None, + end_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobSourceType.TRACES # type: ignore + + +class TracesEvaluatorGenerationJobSource( + EvaluatorGenerationJobSource, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Traces source for evaluator generation jobs — conversation traces from Application Insights. + + :ivar description: Optional description of what this source represents — helps the pipeline + interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core + capabilities'). + :vartype description: str + :ivar type: The source type for this source, which is Traces. Required. Traces source — + conversation traces from Application Insights. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_id: str + :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_name: str + :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent + are included within the time window. + :vartype agent_version: str + :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + Required. + :vartype start_time: ~datetime.datetime + :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. + :vartype end_time: ~datetime.datetime + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional description of what this source represents — helps the pipeline interpret its content + (e.g., 'Company refund policy document' or 'Describes the agent's core capabilities').""" + type: Literal[EvaluatorGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The source type for this source, which is Traces. Required. Traces source — conversation traces + from Application Insights.""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at + least one is required.""" + agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least + one is required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version. If not specified, traces for ALL versions of the agent are included within + the time window.""" + start_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" + end_time: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + + @overload + def __init__( + self, + *, + start_time: datetime.datetime, + description: Optional[str] = None, + agent_id: Optional[str] = None, + agent_name: Optional[str] = None, + agent_version: Optional[str] = None, + end_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = EvaluatorGenerationJobSourceType.TRACES # type: ignore + + +class TranscriptionLanguage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A language detected in transcribed audio. + + :ivar code: The code of a language detected in the audio. Required. + :vartype code: str + """ + + code: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The code of a language detected in the audio. Required.""" + + @overload + def __init__( + self, + *, + code: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TranscriptTextUsageDuration( + CreateTranscriptionResponseJsonUsage, discriminator="duration" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Duration Usage. + + :ivar type: The type of the usage object. Always ``duration`` for this variant. Required. + DURATION. + :vartype type: str or ~azure.ai.projects.models.DURATION + :ivar seconds: Duration of the input audio in seconds. Required. + :vartype seconds: ~datetime.timedelta + """ + + type: Literal[CreateTranscriptionResponseJsonUsageType.DURATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the usage object. Always ``duration`` for this variant. Required. DURATION.""" + seconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """Duration of the input audio in seconds. Required.""" + + @overload + def __init__( + self, + *, + seconds: datetime.timedelta, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CreateTranscriptionResponseJsonUsageType.DURATION # type: ignore + + +class TranscriptTextUsageTokens( + CreateTranscriptionResponseJsonUsage, discriminator="tokens" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Token Usage. + + :ivar type: The type of the usage object. Always ``tokens`` for this variant. Required. TOKENS. + :vartype type: str or ~azure.ai.projects.models.TOKENS + :ivar input_tokens: Number of input tokens billed for this request. Required. + :vartype input_tokens: int + :ivar input_token_details: Details about the input tokens billed for this request. + :vartype input_token_details: + ~azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails + :ivar output_tokens: Number of output tokens generated. Required. + :vartype output_tokens: int + :ivar total_tokens: Total number of tokens used (input + output). Required. + :vartype total_tokens: int + """ + + type: Literal[CreateTranscriptionResponseJsonUsageType.TOKENS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the usage object. Always ``tokens`` for this variant. Required. TOKENS.""" + input_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of input tokens billed for this request. Required.""" + input_token_details: Optional["_models.TranscriptTextUsageTokensInputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details about the input tokens billed for this request.""" + output_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of output tokens generated. Required.""" + total_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Total number of tokens used (input + output). Required.""" + + @overload + def __init__( + self, + *, + input_tokens: int, + output_tokens: int, + total_tokens: int, + input_token_details: Optional["_models.TranscriptTextUsageTokensInputTokenDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CreateTranscriptionResponseJsonUsageType.TOKENS # type: ignore + + +class TranscriptTextUsageTokensInputTokenDetails( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """TranscriptTextUsageTokensInputTokenDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TwilioTelephonyBinding( + TelephonyBinding, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Twilio binding owned by a voice agent. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + +class TwilioTelephonyBindingListItem( + TelephonyBindingListItem, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Twilio binding returned in a list, including its entity tag. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection: The Foundry connection name for the telephony provider. Required. + :vartype connection: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + +class UpdateModelVersionRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Request body for updating a model version. Only description and tags can be modified. + + :ivar description: The asset description text. + :vartype description: str + :ivar tags: Tag dictionary. Tags can be added, removed, and updated. + :vartype tags: dict[str, str] + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The asset description text.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Tag dictionary. Tags can be added, removed, and updated.""" + + @overload + def __init__( + self, + *, + description: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UpdateTelephonyBindingRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to update an existing telephony binding. Every property is optional and the + binding's provider is immutable. + + :ivar status: The new lifecycle status. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar label: The replacement display label. Omit it to preserve the current value; use null to + clear it. + :vartype label: str + :ivar connection: The replacement Foundry connection name. This property is valid only for a + Teams Phone Extension binding; a Twilio binding's connection is immutable. + :vartype connection: str + :ivar phone_number: The replacement Teams Phone Extension display phone number. Omit it to + preserve the current value; use null to clear it. This property is valid only for a Teams Phone + Extension binding. + :vartype phone_number: str + """ + + status: Optional[Union[str, "_models.TelephonyBindingStatus"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The new lifecycle status. Known values are: \"active\" and \"suspended\".""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement display label. Omit it to preserve the current value; use null to clear it.""" + connection: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement Foundry connection name. This property is valid only for a Teams Phone + Extension binding; a Twilio binding's connection is immutable.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement Teams Phone Extension display phone number. Omit it to preserve the current + value; use null to clear it. This property is valid only for a Teams Phone Extension binding.""" + + @overload + def __init__( + self, + *, + status: Optional[Union[str, "_models.TelephonyBindingStatus"]] = None, + label: Optional[str] = None, + connection: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UpdateToolboxRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """UpdateToolboxRequest. + + :ivar default_version: The version identifier that the toolbox should point to. When set, the + toolbox's default version will resolve to this version instead of the latest. Required. + :vartype default_version: str + """ + + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier that the toolbox should point to. When set, the toolbox's default + version will resolve to this version instead of the latest. Required.""" + + @overload + def __init__( + self, + *, + default_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UserProfileMemoryItem( + MemoryItem, discriminator="user_profile" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A memory item specifically containing user profile information extracted from conversations, + such as preferences, interests, and personal details. + + :ivar memory_id: The unique ID of the memory item. Required. + :vartype memory_id: str + :ivar updated_at: The last update time of the memory item. Required. + :vartype updated_at: ~datetime.datetime + :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :vartype scope: str + :ivar content: The content of the memory. Required. + :vartype content: str + :ivar kind: The kind of the memory item. Required. User profile information extracted from + conversations. + :vartype kind: str or ~azure.ai.projects.models.USER_PROFILE + """ + + kind: Literal[MemoryItemKind.USER_PROFILE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The kind of the memory item. Required. User profile information extracted from conversations.""" + + @overload + def __init__( + self, + *, + memory_id: str, + updated_at: datetime.datetime, + scope: str, + content: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = MemoryItemKind.USER_PROFILE # type: ignore + + +class VersionIndicator(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Version indicator determining which agent version backs the session. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VersionRefIndicator + + :ivar type: The type of version indicator. Required. "version_ref" + :vartype type: str or ~azure.ai.projects.models.VersionIndicatorType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of version indicator. Required. \"version_ref\"""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VersionRefIndicator( + VersionIndicator, discriminator="version_ref" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Version indicator that references a specific agent version by name. + + :ivar type: Discriminator value for version_ref. Required. Direct reference to a specific agent + version. + :vartype type: str or ~azure.ai.projects.models.VERSION_REF + :ivar agent_version: The agent version identifier returned by the agent version APIs. Required. + :vartype agent_version: str + """ + + type: Literal[VersionIndicatorType.VERSION_REF] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Discriminator value for version_ref. Required. Direct reference to a specific agent version.""" + agent_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version identifier returned by the agent version APIs. Required.""" + + @overload + def __init__( + self, + *, + agent_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = VersionIndicatorType.VERSION_REF # type: ignore + + +class VersionSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """VersionSelector. + + :ivar version_selection_rules: Required. + :vartype version_selection_rules: list[~azure.ai.projects.models.VersionSelectionRule] + """ + + version_selection_rules: list["_models.VersionSelectionRule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + version_selection_rules: list["_models.VersionSelectionRule"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceAgentAnimationConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Animation settings for a voice-agent session. + + :ivar model_name: The animation model name. + :vartype model_name: str + :ivar outputs: The requested animation output kinds. + :vartype outputs: list[str or ~azure.ai.projects.models.VoiceAgentAnimationOutputType] + """ + + model_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The animation model name.""" + outputs: Optional[list[Union[str, "_models.VoiceAgentAnimationOutputType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The time when the underlying run reached a terminal state.""" - dispatch_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The dispatch identifier associated with the routine attempt.""" - action_correlation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream action correlation identifier, when available.""" - response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream response or invocation identifier, when available.""" - task_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The workspace task identifier linked to the routine attempt, when available.""" - error_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream error status code captured for a failed attempt, when available.""" - error_type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The fully qualified error type captured for a failed attempt, when available.""" - error_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The truncated failure message captured for a failed attempt, when available.""" + """The requested animation output kinds.""" @overload def __init__( self, *, - status: Optional["_unions.RoutineRunStatus"] = None, - phase: Optional[Union[str, "_models.RoutineRunPhase"]] = None, - trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = None, - trigger_name: Optional[str] = None, - trigger_event_payload: Optional[dict[str, Any]] = None, - attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = None, - action_type: Optional[Union[str, "_models.RoutineActionType"]] = None, - agent_id: Optional[str] = None, - agent_endpoint_id: Optional[str] = None, - conversation_id: Optional[str] = None, - session_id: Optional[str] = None, - triggered_at: Optional[datetime.datetime] = None, - scheduled_fire_at: Optional[datetime.datetime] = None, - started_at: Optional[datetime.datetime] = None, - ended_at: Optional[datetime.datetime] = None, - dispatch_id: Optional[str] = None, - action_correlation_id: Optional[str] = None, - response_id: Optional[str] = None, - task_id: Optional[str] = None, - error_status_code: Optional[int] = None, - error_type: Optional[str] = None, - error_message: Optional[str] = None, + model_name: Optional[str] = None, + outputs: Optional[list[Union[str, "_models.VoiceAgentAnimationOutputType"]]] = None, ) -> None: ... @overload @@ -14671,61 +25344,31 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class RubricBasedEvaluatorDefinition( - EvaluatorDefinition, discriminator="rubric" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Rubric-based evaluator definition — stores dimensions produced by the generate API. Used for - both quality and safety evaluators. +class VoiceAgentAudioConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The audio configuration for a voice agent. These values are session defaults and may be + overridden when connecting. - :ivar init_parameters: The JSON schema (Draft 2020-12) for the evaluator's input parameters. - This includes parameters like type, properties, required. - :vartype init_parameters: dict[str, any] - :ivar data_schema: The JSON schema (Draft 2020-12) for the evaluator's input data. This - includes parameters like type, properties, required. - :vartype data_schema: dict[str, any] - :ivar metrics: List of output metrics produced by this evaluator. - :vartype metrics: dict[str, ~azure.ai.projects.models.EvaluatorMetric] - :ivar type: Required. Rubric-based evaluator definition. Stores dimensions (the scoring - blueprint) for both quality and safety evaluators. Can be created via the generate API or - manually via createVersion. - :vartype type: str or ~azure.ai.projects.models.RUBRIC - :ivar dimensions: The set of dimensions — the scoring blueprint used by the LLM judge. Quality - evaluators include a non-editable residual dimension with id 'general_quality' - (always_applicable: true); safety evaluators include 'general_policy_compliance'. Both use the - same Dimension structure. Required. - :vartype dimensions: list[~azure.ai.projects.models.Dimension] - :ivar pass_threshold: Pass/fail threshold for the aggregate rubric score, on the same - normalized 0.0-1.0 scale as the emitted ``score``. When the runtime weighted average meets or - exceeds this value, the result is ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted - average of 3.0). The 'any dimension scored 1 → fail' rule still applies regardless of this - threshold. - :vartype pass_threshold: float + :ivar input: Input (microphone) audio configuration. + :vartype input: ~azure.ai.projects.models.VoiceAgentAudioInputConfig + :ivar output: Output (agent speech) audio configuration. + :vartype output: ~azure.ai.projects.models.VoiceAgentAudioOutputConfig """ - type: Literal[EvaluatorDefinitionType.RUBRIC] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. Rubric-based evaluator definition. Stores dimensions (the scoring blueprint) for both - quality and safety evaluators. Can be created via the generate API or manually via - createVersion.""" - dimensions: list["_models.Dimension"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The set of dimensions — the scoring blueprint used by the LLM judge. Quality evaluators include - a non-editable residual dimension with id 'general_quality' (always_applicable: true); safety - evaluators include 'general_policy_compliance'. Both use the same Dimension structure. - Required.""" - pass_threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Pass/fail threshold for the aggregate rubric score, on the same normalized 0.0-1.0 scale as the - emitted ``score``. When the runtime weighted average meets or exceeds this value, the result is - ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted average of 3.0). The 'any dimension - scored 1 → fail' rule still applies regardless of this threshold.""" + input: Optional["_models.VoiceAgentAudioInputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Input (microphone) audio configuration.""" + output: Optional["_models.VoiceAgentAudioOutputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Output (agent speech) audio configuration.""" @overload def __init__( self, *, - dimensions: list["_models.Dimension"], - init_parameters: Optional[dict[str, Any]] = None, - data_schema: Optional[dict[str, Any]] = None, - metrics: Optional[dict[str, "_models.EvaluatorMetric"]] = None, - pass_threshold: Optional[float] = None, + input: Optional["_models.VoiceAgentAudioInputConfig"] = None, + output: Optional["_models.VoiceAgentAudioOutputConfig"] = None, ) -> None: ... @overload @@ -14737,66 +25380,56 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = EvaluatorDefinitionType.RUBRIC # type: ignore -class RubricGenerationInputQualityWarning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A non-fatal advisory produced during rubric evaluator generation when resolved inputs are - technically valid but likely too weak to produce a high-quality rubric. Read-only; - service-generated. Persisted with the terminal EvaluatorGenerationJob. +class VoiceAgentAudioInputConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Input audio configuration for a voice agent. - :ivar code: Stable searchable machine-readable warning code. Required. Known values are: - "empty_prompt", "short_prompt", "empty_agent_instructions", "short_agent_instructions", - "empty_dataset_content", "short_dataset_content", "low_trace_count", and - "insufficient_total_input". - :vartype code: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningCode - :ivar severity: Advisory severity. Initial values: ``warning``. Required. "warning" - :vartype severity: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity - :ivar message: Human-readable message suitable for direct SDK/CLI/UI display. Must not include - raw prompt, instruction, dataset, or trace text. Required. - :vartype message: str - :ivar source: Which source category the warning applies to. ``aggregate`` is used only for - cross-source warnings. Required. Known values are: "prompt", "agent", "dataset", and - "aggregate". - :vartype source: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSource - :ivar source_index: Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the - warning applies to a specific source. Omitted for aggregate warnings and for warnings not tied - to one source. - :vartype source_index: int + :ivar format: The input audio format. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + :ivar noise_reduction: Input noise reduction. Set to null to disable. + :vartype noise_reduction: ~azure.ai.projects.models.VoiceAgentNoiseReduction + :ivar turn_detection: Turn (end-of-speech) detection. Server-side turn detection is enabled by + default; set to null to disable it, in which case the client must trigger responses manually. + :vartype turn_detection: ~azure.ai.projects.models.VoiceAgentTurnDetectionConfig + :ivar echo_cancellation: Optional server-side echo cancellation settings. + :vartype echo_cancellation: ~azure.ai.projects.models.VoiceAgentEchoCancellation + :ivar transcription: Asynchronous input-audio transcription. Set to null to disable + transcription. + :vartype transcription: ~azure.ai.projects.models.VoiceAgentInputTranscription """ - code: Union[str, "_models.RubricGenerationInputQualityWarningCode"] = rest_field( + format: Optional["_models.RealtimeAudioFormats"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Stable searchable machine-readable warning code. Required. Known values are: \"empty_prompt\", - \"short_prompt\", \"empty_agent_instructions\", \"short_agent_instructions\", - \"empty_dataset_content\", \"short_dataset_content\", \"low_trace_count\", and - \"insufficient_total_input\".""" - severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"] = rest_field( + """The input audio format.""" + noise_reduction: Optional["_models.VoiceAgentNoiseReduction"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Advisory severity. Initial values: ``warning``. Required. \"warning\"""" - message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Human-readable message suitable for direct SDK/CLI/UI display. Must not include raw prompt, - instruction, dataset, or trace text. Required.""" - source: Union[str, "_models.RubricGenerationInputQualityWarningSource"] = rest_field( + """Input noise reduction. Set to null to disable.""" + turn_detection: Optional["_models.VoiceAgentTurnDetectionConfig"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Which source category the warning applies to. ``aggregate`` is used only for cross-source - warnings. Required. Known values are: \"prompt\", \"agent\", \"dataset\", and \"aggregate\".""" - source_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the warning applies to a - specific source. Omitted for aggregate warnings and for warnings not tied to one source.""" + """Turn (end-of-speech) detection. Server-side turn detection is enabled by default; set to null + to disable it, in which case the client must trigger responses manually.""" + echo_cancellation: Optional["_models.VoiceAgentEchoCancellation"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional server-side echo cancellation settings.""" + transcription: Optional["_models.VoiceAgentInputTranscription"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Asynchronous input-audio transcription. Set to null to disable transcription.""" @overload def __init__( self, *, - code: Union[str, "_models.RubricGenerationInputQualityWarningCode"], - severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"], - message: str, - source: Union[str, "_models.RubricGenerationInputQualityWarningSource"], - source_index: Optional[int] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, + noise_reduction: Optional["_models.VoiceAgentNoiseReduction"] = None, + turn_detection: Optional["_models.VoiceAgentTurnDetectionConfig"] = None, + echo_cancellation: Optional["_models.VoiceAgentEchoCancellation"] = None, + transcription: Optional["_models.VoiceAgentInputTranscription"] = None, ) -> None: ... @overload @@ -14810,23 +25443,141 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SASCredentials(BaseCredentials, discriminator="SAS"): - """Shared Access Signature (SAS) credential definition. +class VoiceAgentAudioOutputConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Output audio configuration for a voice agent. + Provider-specific fields are selected by ``voice_type``: - :ivar type: The credential type. Required. Shared Access Signature (SAS) credential. - :vartype type: str or ~azure.ai.projects.models.SAS - :ivar sas_token: SAS token. - :vartype sas_token: str + * `openai`: `voice` and `speed`. + * `azure-standard`: `voice`, `voice_locale`, `speed`, `voice_temperature`, + `custom_lexicon_url`, + `custom_text_normalization_url`, `prefer_locales`, `style`, `pitch`, and `volume`. + * `azure-custom`: all `azure-standard` fields except `style`, plus `custom_voice_endpoint_id`. + * `azure-personal`: all `azure-standard` fields except `style`, plus `personal_voice_model`. + * `avatar-voice-sync`: all `azure-standard` fields except `voice` and `style`, plus + `personal_voice_model`; the voice name is derived from the avatar. + * `azure-realtime-native`: `voice` and `speed`. + + `format` and `output_audio_timestamp_types` apply to every voice type. + + :ivar format: The output audio format. Applies to every ``voice_type`` and defaults to 24 kHz + PCM. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + :ivar voice: The voice name or identifier. Applies to ``openai``, ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``azure-realtime-native``. It does not apply to + ``avatar-voice-sync``, which derives the voice name from the avatar. + :vartype voice: str + :ivar voice_type: The voice implementation. Known values are: "openai", "azure-standard", + "azure-custom", "azure-personal", "avatar-voice-sync", and "azure-realtime-native". + :vartype voice_type: str or ~azure.ai.projects.models.VoiceType + :ivar voice_locale: The enforced BCP-47 output locale. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype voice_locale: str + :ivar speed: The numeric output speed multiplier. Applies to all known ``voice_type`` values + and defaults to 1. + :vartype speed: float + :ivar voice_temperature: The voice variation temperature. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype voice_temperature: float + :ivar custom_lexicon_url: The URL of a custom pronunciation lexicon. Applies to + ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype custom_lexicon_url: str + :ivar custom_text_normalization_url: The URL of a custom text-normalization configuration. + Applies to ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype custom_text_normalization_url: str + :ivar prefer_locales: Preferred BCP-47 locales for multilingual synthesis. Applies to + ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype prefer_locales: list[str] + :ivar style: The voice speaking style. Applies only when ``voice_type`` is ``azure-standard``. + :vartype style: str + :ivar pitch: The voice pitch adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``. + :vartype pitch: str + :ivar volume: The voice volume adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``. + :vartype volume: str + :ivar custom_voice_endpoint_id: The Azure custom-voice deployment endpoint identifier. Applies + only when ``voice_type`` is ``azure-custom``. + :vartype custom_voice_endpoint_id: str + :ivar personal_voice_model: The Azure personal or avatar voice model. Applies only when + ``voice_type`` is ``azure-personal`` or ``avatar-voice-sync``. + :vartype personal_voice_model: str + :ivar output_audio_timestamp_types: Timestamp kinds to include with output audio. Applies to + every ``voice_type``. + :vartype output_audio_timestamp_types: list[str or + ~azure.ai.projects.models.VoiceAgentAudioTimestampType] """ - type: Literal[CredentialType.SAS] = rest_discriminator(name="type", visibility=["read"]) # type: ignore - """The credential type. Required. Shared Access Signature (SAS) credential.""" - sas_token: Optional[str] = rest_field(name="SAS", visibility=["read"]) - """SAS token.""" + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output audio format. Applies to every ``voice_type`` and defaults to 24 kHz PCM.""" + voice: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice name or identifier. Applies to ``openai``, ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``azure-realtime-native``. It does not apply to ``avatar-voice-sync``, + which derives the voice name from the avatar.""" + voice_type: Optional[Union[str, "_models.VoiceType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The voice implementation. Known values are: \"openai\", \"azure-standard\", \"azure-custom\", + \"azure-personal\", \"avatar-voice-sync\", and \"azure-realtime-native\".""" + voice_locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The enforced BCP-47 output locale. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + speed: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The numeric output speed multiplier. Applies to all known ``voice_type`` values and defaults to + 1.""" + voice_temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice variation temperature. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_lexicon_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The URL of a custom pronunciation lexicon. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_text_normalization_url: Optional[str] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The URL of a custom text-normalization configuration. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``.""" + prefer_locales: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Preferred BCP-47 locales for multilingual synthesis. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``.""" + style: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice speaking style. Applies only when ``voice_type`` is ``azure-standard``.""" + pitch: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice pitch adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + volume: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice volume adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_voice_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Azure custom-voice deployment endpoint identifier. Applies only when ``voice_type`` is + ``azure-custom``.""" + personal_voice_model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Azure personal or avatar voice model. Applies only when ``voice_type`` is + ``azure-personal`` or ``avatar-voice-sync``.""" + output_audio_timestamp_types: Optional[list[Union[str, "_models.VoiceAgentAudioTimestampType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Timestamp kinds to include with output audio. Applies to every ``voice_type``.""" @overload def __init__( self, + *, + format: Optional["_models.RealtimeAudioFormats"] = None, + voice: Optional[str] = None, + voice_type: Optional[Union[str, "_models.VoiceType"]] = None, + voice_locale: Optional[str] = None, + speed: Optional[float] = None, + voice_temperature: Optional[float] = None, + custom_lexicon_url: Optional[str] = None, + custom_text_normalization_url: Optional[str] = None, + prefer_locales: Optional[list[str]] = None, + style: Optional[str] = None, + pitch: Optional[str] = None, + volume: Optional[str] = None, + custom_voice_endpoint_id: Optional[str] = None, + personal_voice_model: Optional[str] = None, + output_audio_timestamp_types: Optional[list[Union[str, "_models.VoiceAgentAudioTimestampType"]]] = None, ) -> None: ... @overload @@ -14838,74 +25589,110 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = CredentialType.SAS # type: ignore -class Schedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Schedule model. +class VoiceAgentAvatarConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar configuration for a voice agent. These values are session defaults and may be overridden + when connecting. - :ivar schedule_id: Identifier of the schedule. Required. - :vartype schedule_id: str - :ivar display_name: Name of the schedule. - :vartype display_name: str - :ivar description: Description of the schedule. - :vartype description: str - :ivar enabled: Enabled status of the schedule. Required. - :vartype enabled: bool - :ivar provisioning_status: Provisioning status of the schedule. Known values are: "Creating", - "Updating", "Deleting", "Succeeded", and "Failed". - :vartype provisioning_status: str or ~azure.ai.projects.models.ScheduleProvisioningStatus - :ivar trigger: Trigger for the schedule. Required. - :vartype trigger: ~azure.ai.projects.models.Trigger - :ivar task: Task for the schedule. Required. - :vartype task: ~azure.ai.projects.models.ScheduleTask - :ivar tags: Schedule's tags. Unlike properties, tags are fully mutable. - :vartype tags: dict[str, str] - :ivar properties: Schedule's properties. Unlike tags, properties are add-only. Once added, a - property cannot be removed. - :vartype properties: dict[str, str] - :ivar system_data: System metadata for the resource. Required. - :vartype system_data: dict[str, str] + :ivar type: The avatar type. Required. Known values are: "video_avatar" and "photo_avatar". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentAvatarType + :ivar character: The avatar character identifier, e.g. 'lisa'. Required. + :vartype character: str + :ivar style: The avatar style, e.g. 'casual-sitting'. + :vartype style: str + :ivar customized: Whether the avatar is a customer-customized avatar. Defaults to false. + :vartype customized: bool + :ivar output_protocol: The transport used to deliver the avatar video stream. Known values are: + "webrtc" and "websocket". + :vartype output_protocol: str or ~azure.ai.projects.models.VoiceAgentAvatarOutputProtocol + :ivar model: The avatar model identifier. + :vartype model: str + :ivar video: Avatar video encoder and presentation settings. + :vartype video: ~azure.ai.projects.models.VoiceAgentAvatarVideoParams + :ivar scene: Avatar placement and motion settings. + :vartype scene: ~azure.ai.projects.models.VoiceAgentAvatarScene + :ivar output_audit_audio: Whether audit audio is emitted with avatar output. Defaults to false. + :vartype output_audit_audio: bool """ - schedule_id: str = rest_field(name="id", visibility=["read"]) - """Identifier of the schedule. Required.""" - display_name: Optional[str] = rest_field( - name="displayName", visibility=["read", "create", "update", "delete", "query"] + type: Union[str, "_models.VoiceAgentAvatarType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """Name of the schedule.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the schedule.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Enabled status of the schedule. Required.""" - provisioning_status: Optional[Union[str, "_models.ScheduleProvisioningStatus"]] = rest_field( - name="provisioningStatus", visibility=["read"] + """The avatar type. Required. Known values are: \"video_avatar\" and \"photo_avatar\".""" + character: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar character identifier, e.g. 'lisa'. Required.""" + style: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar style, e.g. 'casual-sitting'.""" + customized: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the avatar is a customer-customized avatar. Defaults to false.""" + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """Provisioning status of the schedule. Known values are: \"Creating\", \"Updating\", - \"Deleting\", \"Succeeded\", and \"Failed\".""" - trigger: "_models.Trigger" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Trigger for the schedule. Required.""" - task: "_models.ScheduleTask" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Task for the schedule. Required.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Schedule's tags. Unlike properties, tags are fully mutable.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Schedule's properties. Unlike tags, properties are add-only. Once added, a property cannot be - removed.""" - system_data: dict[str, str] = rest_field(name="systemData", visibility=["read"]) - """System metadata for the resource. Required.""" + """The transport used to deliver the avatar video stream. Known values are: \"webrtc\" and + \"websocket\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar model identifier.""" + video: Optional["_models.VoiceAgentAvatarVideoParams"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Avatar video encoder and presentation settings.""" + scene: Optional["_models.VoiceAgentAvatarScene"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Avatar placement and motion settings.""" + output_audit_audio: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether audit audio is emitted with avatar output. Defaults to false.""" @overload def __init__( self, *, - enabled: bool, - trigger: "_models.Trigger", - task: "_models.ScheduleTask", - display_name: Optional[str] = None, - description: Optional[str] = None, - tags: Optional[dict[str, str]] = None, - properties: Optional[dict[str, str]] = None, + type: Union[str, "_models.VoiceAgentAvatarType"], + character: str, + style: Optional[str] = None, + customized: Optional[bool] = None, + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = None, + model: Optional[str] = None, + video: Optional["_models.VoiceAgentAvatarVideoParams"] = None, + scene: Optional["_models.VoiceAgentAvatarScene"] = None, + output_audit_audio: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceAgentAvatarIceServer(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An ICE server used for avatar WebRTC negotiation. + + :ivar urls: Required. + :vartype urls: list[str] + :ivar username: + :vartype username: str + :ivar credential: + :vartype credential: str + """ + + urls: list[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + username: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + credential: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + urls: list[str], + username: Optional[str] = None, + credential: Optional[str] = None, ) -> None: ... @overload @@ -14919,34 +25706,44 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ScheduleRoutineTrigger( - RoutineTrigger, discriminator="schedule" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A recurring cron-based routine trigger. +class VoiceAgentAvatarScene(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar placement and motion settings. - :ivar type: The trigger type. Required. A recurring cron-based trigger. - :vartype type: str or ~azure.ai.projects.models.SCHEDULE - :ivar cron_expression: A 5-field cron expression. The service enforces a minimum interval of - five minutes by default. Required. - :vartype cron_expression: str - :ivar time_zone: An IANA or Windows time zone identifier for the schedule. Required. - :vartype time_zone: str + :ivar zoom: + :vartype zoom: float + :ivar position_x: + :vartype position_x: float + :ivar position_y: + :vartype position_y: float + :ivar rotation_x: + :vartype rotation_x: float + :ivar rotation_y: + :vartype rotation_y: float + :ivar rotation_z: + :vartype rotation_z: float + :ivar amplitude: + :vartype amplitude: float """ - type: Literal[RoutineTriggerType.SCHEDULE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The trigger type. Required. A recurring cron-based trigger.""" - cron_expression: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A 5-field cron expression. The service enforces a minimum interval of five minutes by default. - Required.""" - time_zone: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """An IANA or Windows time zone identifier for the schedule. Required.""" + zoom: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + position_x: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + position_y: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_x: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_y: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_z: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + amplitude: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - cron_expression: str, - time_zone: str, + zoom: Optional[float] = None, + position_x: Optional[float] = None, + position_y: Optional[float] = None, + rotation_x: Optional[float] = None, + rotation_y: Optional[float] = None, + rotation_z: Optional[float] = None, + amplitude: Optional[float] = None, ) -> None: ... @overload @@ -14958,47 +25755,26 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = RoutineTriggerType.SCHEDULE # type: ignore -class ScheduleRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Schedule run model. +class VoiceAgentAvatarVideoBackground(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The avatar video background. - :ivar run_id: Identifier of the schedule run. Required. - :vartype run_id: str - :ivar schedule_id: Identifier of the schedule. Required. - :vartype schedule_id: str - :ivar success: Trigger success status of the schedule run. Required. - :vartype success: bool - :ivar trigger_time: Trigger time of the schedule run. - :vartype trigger_time: ~datetime.datetime - :ivar error: Error information for the schedule run. - :vartype error: str - :ivar properties: Properties of the schedule run. Required. - :vartype properties: dict[str, str] + :ivar image_url: + :vartype image_url: str + :ivar color: + :vartype color: str """ - run_id: str = rest_field(name="id", visibility=["read"]) - """Identifier of the schedule run. Required.""" - schedule_id: str = rest_field(name="scheduleId", visibility=["read", "create", "update", "delete", "query"]) - """Identifier of the schedule. Required.""" - success: bool = rest_field(visibility=["read"]) - """Trigger success status of the schedule run. Required.""" - trigger_time: Optional[datetime.datetime] = rest_field( - name="triggerTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """Trigger time of the schedule run.""" - error: Optional[str] = rest_field(visibility=["read"]) - """Error information for the schedule run.""" - properties: dict[str, str] = rest_field(visibility=["read"]) - """Properties of the schedule run. Required.""" + image_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + color: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - schedule_id: str, - trigger_time: Optional[datetime.datetime] = None, + image_url: Optional[str] = None, + color: Optional[str] = None, ) -> None: ... @overload @@ -15012,26 +25788,26 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionConfiguration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Session defaults applied to sessions created for a hosted agent version. +class VoiceAgentAvatarVideoCrop(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The rectangular crop applied to avatar video. - :ivar idle_timeout_seconds: The idle duration, in seconds, before a session's sandbox is - suspended. Optional — when unset, the server default of 900 seconds is used. Must be between - 120 and 3600 seconds (inclusive). - :vartype idle_timeout_seconds: ~datetime.timedelta + :ivar bottom_right: Required. + :vartype bottom_right: list[int] + :ivar top_left: Required. + :vartype top_left: list[int] """ - idle_timeout_seconds: Optional[datetime.timedelta] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" - ) - """The idle duration, in seconds, before a session's sandbox is suspended. Optional — when unset, - the server default of 900 seconds is used. Must be between 120 and 3600 seconds (inclusive).""" + bottom_right: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + top_left: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - idle_timeout_seconds: Optional[datetime.timedelta] = None, + bottom_right: list[int], + top_left: list[int], ) -> None: ... @overload @@ -15045,38 +25821,43 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionDirectoryEntry(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single entry in a directory listing. +class VoiceAgentAvatarVideoParams(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar video encoder and presentation settings. - :ivar name: The name of the file or directory. Required. - :vartype name: str - :ivar size: The size in bytes (0 for directories). Required. - :vartype size: int - :ivar is_directory: Whether this entry is a directory. Required. - :vartype is_directory: bool - :ivar modified_time: The Unix timestamp (in seconds) when the file was last modified. Required. - :vartype modified_time: ~datetime.datetime + :ivar bitrate: The target video bitrate in bits per second. + :vartype bitrate: int + :ivar crop: + :vartype crop: ~azure.ai.projects.models.VoiceAgentAvatarVideoCrop + :ivar resolution: + :vartype resolution: ~azure.ai.projects.models.VoiceAgentAvatarVideoResolution + :ivar background: + :vartype background: ~azure.ai.projects.models.VoiceAgentAvatarVideoBackground + :ivar gop_size: + :vartype gop_size: int """ - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the file or directory. Required.""" - size: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The size in bytes (0 for directories). Required.""" - is_directory: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether this entry is a directory. Required.""" - modified_time: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + bitrate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The target video bitrate in bits per second.""" + crop: Optional["_models.VoiceAgentAvatarVideoCrop"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The Unix timestamp (in seconds) when the file was last modified. Required.""" + resolution: Optional["_models.VoiceAgentAvatarVideoResolution"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + background: Optional["_models.VoiceAgentAvatarVideoBackground"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + gop_size: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - name: str, - size: int, - is_directory: bool, - modified_time: datetime.datetime, + bitrate: Optional[int] = None, + crop: Optional["_models.VoiceAgentAvatarVideoCrop"] = None, + resolution: Optional["_models.VoiceAgentAvatarVideoResolution"] = None, + background: Optional["_models.VoiceAgentAvatarVideoBackground"] = None, + gop_size: Optional[int] = None, ) -> None: ... @overload @@ -15090,27 +25871,26 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionFileWriteResult(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Response from uploading a file to a session sandbox. +class VoiceAgentAvatarVideoResolution(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The avatar video resolution. - :ivar path: The path where the file was written, relative to the session home directory. - Required. - :vartype path: str - :ivar bytes_written: Number of bytes written. Required. - :vartype bytes_written: int + :ivar width: Required. + :vartype width: int + :ivar height: Required. + :vartype height: int """ - path: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The path where the file was written, relative to the session home directory. Required.""" - bytes_written: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Number of bytes written. Required.""" + width: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + height: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - path: str, - bytes_written: int, + width: int, + height: int, ) -> None: ... @overload @@ -15124,51 +25904,127 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionLogEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single Server-Sent Event frame emitted by the hosted agent session log stream. +class VoiceAgentTurnDetectionConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Turn-detection configuration for a voice agent. - Each frame contains an ``event`` field identifying the event type and a ``data`` - field carrying the payload as plain text. Although the current ``data`` payload - is JSON-formatted, its schema is not contractual — additional keys may appear - and the format may change over time. Clients should treat ``data`` as an - opaque string and optionally attempt JSON parsing. + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentAzureSemanticVadTurnDetection, VoiceAgentAzureSemanticVadEnTurnDetection, + VoiceAgentAzureSemanticVadMultilingualTurnDetection, VoiceAgentSemanticVadTurnDetection, + VoiceAgentServerVadTurnDetection - New event types may be added in the future. Clients should gracefully - ignore unrecognized event types. + :ivar type: The turn-detection strategy. Required. Known values are: "server_vad", + "semantic_vad", "azure_semantic_vad", "azure_semantic_vad_en", and + "azure_semantic_vad_multilingual". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentTurnDetectionType + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + """ - Wire format: + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The turn-detection strategy. Required. Known values are: \"server_vad\", \"semantic_vad\", + \"azure_semantic_vad\", \"azure_semantic_vad_en\", and \"azure_semantic_vad_multilingual\".""" + auto_truncate: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the input audio buffer is truncated automatically when speech stops.""" - .. code-block:: + @overload + def __init__( + self, + *, + type: str, + auto_truncate: Optional[bool] = None, + ) -> None: ... - event: log - data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting server on port 18080"} + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ - event: log - data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) - :ivar event: The SSE event type. Currently ``log``, but additional event types may be added in - the future. Clients should ignore unrecognized event types. Required. "log" - :vartype event: str or ~azure.ai.projects.models.SessionLogEventType - :ivar data: The event payload as plain text. Currently JSON-formatted but the schema is not - contractual and may change. Required. - :vartype data: str - """ - event: Union[str, "_models.SessionLogEventType"] = rest_field( +class VoiceAgentAzureSemanticVadEnTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad_en" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """English-optimized Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. English-optimized Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD_EN + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. English-optimized Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The SSE event type. Currently ``log``, but additional event types may be added in the future. - Clients should ignore unrecognized event types. Required. \"log\"""" - data: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The event payload as plain text. Currently JSON-formatted but the schema is not contractual and - may change. Required.""" + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" @overload def __init__( self, *, - event: Union[str, "_models.SessionLogEventType"], - data: str, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, ) -> None: ... @overload @@ -15180,27 +26036,92 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN # type: ignore -class SharepointGroundingToolParameters(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """The sharepoint grounding tool parameters. - - :ivar project_connections: The project connections attached to this tool. There can be a - maximum of 1 connection resource attached to the tool. - :vartype project_connections: list[~azure.ai.projects.models.ToolProjectConnection] - """ - - project_connections: Optional[list["_models.ToolProjectConnection"]] = rest_field( +class VoiceAgentAzureSemanticVadMultilingualTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad_multilingual" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Multilingual Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. Multilingual Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD_MULTILINGUAL + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + :ivar languages: BCP-47 language codes used for speech detection. + :vartype languages: list[str] + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Multilingual Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The project connections attached to this tool. There can be a maximum of 1 connection resource - attached to the tool.""" + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """BCP-47 language codes used for speech detection.""" @overload def __init__( self, *, - project_connections: Optional[list["_models.ToolProjectConnection"]] = None, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + languages: Optional[list[str]] = None, ) -> None: ... @overload @@ -15212,34 +26133,92 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL # type: ignore -class SharepointPreviewTool( - Tool, discriminator="sharepoint_grounding_preview" +class VoiceAgentAzureSemanticVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """The input definition information for a sharepoint tool as used to configure an agent. - - :ivar type: The object type, which is always 'sharepoint_grounding_preview'. Required. - SHAREPOINT_GROUNDING_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.SHAREPOINT_GROUNDING_PREVIEW - :ivar sharepoint_grounding_preview: The sharepoint grounding tool parameters. Required. - :vartype sharepoint_grounding_preview: - ~azure.ai.projects.models.SharepointGroundingToolParameters - """ - - type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The object type, which is always 'sharepoint_grounding_preview'. Required. - SHAREPOINT_GROUNDING_PREVIEW.""" - sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters" = rest_field( + """Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + :ivar languages: BCP-47 language codes used for speech detection. + :vartype languages: list[str] + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The sharepoint grounding tool parameters. Required.""" + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """BCP-47 language codes used for speech detection.""" @overload def __init__( self, *, - sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters", + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + languages: Optional[list[str]] = None, ) -> None: ... @overload @@ -15251,52 +26230,85 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolType.SHAREPOINT_GROUNDING_PREVIEW # type: ignore + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD # type: ignore -class ShellToolboxTool( - ToolboxTool, discriminator="shell" +class VoiceAgentClientEventRtcCallSdpCreate( + RealtimeClientEvent, discriminator="rtc.call.sdp.create" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """A shell tool stored in a toolbox. This model is additive to toolbox configuration and does not - modify the OpenAI tool contract or existing toolbox tool definitions. + """The ``rtc.call.sdp.create`` client event: begins WebRTC signaling with an SDP offer. + + :ivar type: The event type. Always ``rtc.call.sdp.create``. Required. RTC_CALL_SDP_CREATE. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_SDP_CREATE + :ivar event_id: An optional client-generated event identifier. + :vartype event_id: str + :ivar sdp_offer: The client's SDP offer for the WebRTC connection. Required. + :vartype sdp_offer: str + :ivar session: Optional session configuration. For an ``/agents`` endpoint the service rebuilds + it authoritatively from the persisted agent definition. + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig + """ + + type: Literal[RealtimeClientEventType.RTC_CALL_SDP_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.sdp.create``. Required. RTC_CALL_SDP_CREATE.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional client-generated event identifier.""" + sdp_offer: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The client's SDP offer for the WebRTC connection. Required.""" + session: Optional["_models.VoiceAgentSessionUpdateConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional session configuration. For an ``/agents`` endpoint the service rebuilds it + authoritatively from the persisted agent definition.""" - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``shell``. Required. SHELL. - :vartype type: str or ~azure.ai.projects.models.SHELL - :ivar allowed_callers: - :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] - :ivar environment: The environment in which shell commands are executed. Specify an - automatically provisioned container or an existing container. Required. - :vartype environment: ~azure.ai.projects.models.ToolboxShellEnvironment + @overload + def __init__( + self, + *, + sdp_offer: str, + event_id: Optional[str] = None, + session: Optional["_models.VoiceAgentSessionUpdateConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.RTC_CALL_SDP_CREATE # type: ignore + + +class VoiceAgentClientEventSessionAvatarConnect( + RealtimeClientEvent, discriminator="session.avatar.connect" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.connect`` client event. + + :ivar type: The event type. Always ``session.avatar.connect``. Required. + SESSION_AVATAR_CONNECT. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_CONNECT + :ivar event_id: An optional client-generated event identifier. + :vartype event_id: str + :ivar client_sdp: The client's SDP offer for avatar media negotiation. Required. + :vartype client_sdp: str """ - type: Literal[ToolboxToolType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``shell``. Required. SHELL.""" - allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - environment: "_models.ToolboxShellEnvironment" = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The environment in which shell commands are executed. Specify an automatically provisioned - container or an existing container. Required.""" + type: Literal[RealtimeClientEventType.SESSION_AVATAR_CONNECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.avatar.connect``. Required. SESSION_AVATAR_CONNECT.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional client-generated event identifier.""" + client_sdp: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The client's SDP offer for avatar media negotiation. Required.""" @overload def __init__( self, *, - environment: "_models.ToolboxShellEnvironment", - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, - allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + client_sdp: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -15308,44 +26320,44 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.SHELL # type: ignore + self.type = RealtimeClientEventType.SESSION_AVATAR_CONNECT # type: ignore -class SimpleQnADataGenerationJobOptions( - DataGenerationJobOptions, discriminator="simple_qna" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a data generation job with SimpleQnA type. +class VoiceAgentClientEventSessionUpdate(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``session.update`` client event. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is SimpleQnA for this model. Required. Simple - question and answers between user and agent. - :vartype type: str or ~azure.ai.projects.models.SIMPLE_QNA - :ivar question_types: The question types to generate. Used only for fine-tuning scenarios. - :vartype question_types: list[str or ~azure.ai.projects.models.SimpleQnAFineTuningQuestionType] + :ivar event_id: Optional client-generated ID used to identify this event. This is an arbitrary + string that a client may assign. It will be passed back if there is an error with the event, + but the corresponding ``session.updated`` event will not include it. + :vartype event_id: str + :ivar type: The event type, must be ``session.update``. Required. SESSION_UPDATE. + :vartype type: str or ~azure.ai.projects.models.SESSION_UPDATE + :ivar session: The voice-agent session settings to update. Required. Is one of the following + types: VoiceAgentSessionUpdateConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig """ - type: Literal[DataGenerationJobType.SIMPLE_QNA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is SimpleQnA for this model. Required. Simple question and - answers between user and agent.""" - question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = rest_field( + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event. This is an arbitrary string that a + client may assign. It will be passed back if there is an error with the event, but the + corresponding ``session.updated`` event will not include it.""" + type: Literal[RealtimeClientEventType.SESSION_UPDATE] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The question types to generate. Used only for fine-tuning scenarios.""" + """The event type, must be ``session.update``. Required. SESSION_UPDATE.""" + session: "_models.VoiceAgentSessionUpdateConfig" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The voice-agent session settings to update. Required. Is one of the following types: + VoiceAgentSessionUpdateConfig""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, - question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = None, + type: Literal[RealtimeClientEventType.SESSION_UPDATE], + session: "_models.VoiceAgentSessionUpdateConfig", + event_id: Optional[str] = None, ) -> None: ... @overload @@ -15357,39 +26369,208 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.SIMPLE_QNA # type: ignore -class SimulationSeedDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="simulation_seed" +class VoiceAgentDefinition( + AgentDefinition, discriminator="voice" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a task generation data generation job. Use with multiturn evaluation scenarios - and with prompt, file, or agent sources. Generated dataset rows include fields such as ``id``, - ``category``, ``test_case_description``, and ``desired_num_turns``. - - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is SimulationSeed for this model. Required. - Simulation seed for evaluation scenarios. - :vartype type: str or ~azure.ai.projects.models.SIMULATION_SEED - """ + """The voice agent definition. Its configuration (model, instructions, audio, tools, and optional + avatar) drives a managed speech-to-speech experience. Establish realtime voice sessions through + ``GET /agents/{agent_name}/endpoint/protocols/voice``. Every create or update produces a new + immutable version. - type: Literal[DataGenerationJobType.SIMULATION_SEED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is SimulationSeed for this model. Required. Simulation seed - for evaluation scenarios.""" + :ivar rai_config: Configuration for Responsible AI (RAI) content filtering and safety features. + :vartype rai_config: ~azure.ai.projects.models.RaiConfig + :ivar kind: The kind discriminator for a voice agent definition. Always ``voice``. Required. + VOICE. + :vartype kind: str or ~azure.ai.projects.models.VOICE + :ivar model_type: How the model backing this voice agent is served. Required with ``model`` for + a model-backed voice agent and omitted when ``conversation_engine`` is provided. This is + independent of the architecture (realtime or cascaded), which the service derives from the + selected model. Known values are: "managed" and "self_deployed". + :vartype model_type: str or ~azure.ai.projects.models.VoiceModelType + :ivar model: The model to use for this agent. Required with ``model_type`` for a model-backed + voice agent and omitted when ``conversation_engine`` is provided. The model must support + realtime or cascaded voice. + :vartype model: str + :ivar conversation_engine: The engine that owns conversation handling for this voice agent. + Exactly one of this property and the model-backed configuration (``model_type`` with ``model``) + must be provided. When this property is provided, ``model_type``, ``model``, ``instructions``, + ``tools``, and ``tool_choice`` must be omitted, and ``greeting.tool_choice`` cannot be + ``required``, because the engine owns the conversation logic. The initial implementation + supports a hosted-agent engine. + :vartype conversation_engine: ~azure.ai.projects.models.VoiceConversationEngine + :ivar instructions: A system (or developer) message inserted into the model's context. Supports + template substitution via ``structured_inputs``, rendered per session before the live session + starts. + :vartype instructions: str + :ivar greeting: Optional session-start greeting. Template mode speaks exact rendered text; + LLM-generated mode asks the session model to author the opening response and may use configured + tools. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig + :ivar audio: The audio configuration, including input and output formats, voice, turn + detection, noise reduction, and transcription. These values are session defaults; a client may + override supported fields when connecting. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar output_modalities: The output modalities the agent produces. Defaults to ``["audio"]``. + ``animation`` and ``avatar`` are available when an avatar is configured. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar avatar: Optional avatar configuration. These values are session defaults and may be + overridden when connecting. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentAvatarConfig + :ivar tools: The tools the voice agent may use. Supported tool kinds are ``function`` (executed + by the client), ``mcp``, ``system`` (service-managed session controls), and ``toolbox``. + Server-side tools such as ``web_search``, ``azure_ai_search``, and ``openapi`` are provided + through a toolbox rather than declared directly. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: How the model chooses tools for generated responses. ``none`` prevents tool + calls, ``auto`` lets the model decide, ``required`` requires at least one tool call, and a + specific function or MCP tool can be selected with an object. Defaults to ``auto``. Is one of + the following types: Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, + ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar structured_inputs: Set of structured inputs that participate in prompt template + substitution, rendered per session before the live session starts. + :vartype structured_inputs: dict[str, ~azure.ai.projects.models.StructuredInputDefinition] + :ivar subagent_config: Optional configuration for sibling Foundry text agents that this voice + agent may consult as background specialists. + :vartype subagent_config: ~azure.ai.projects.models.VoiceAgentSubagentConfig + :ivar store: Whether conversations with this agent are persisted. A single, all-or-nothing + persistence switch that defaults to ``false`` (privacy-safe: off by default). When ``true``, + Foundry persists the full conversation — the transcript/event timeline and raw audio. When + ``false``, nothing is persisted and no conversation is surfaced. There is no separate + audio-logging control; audio is persisted only as part of this switch. Latency/performance + telemetry (e.g. time-to-first-audio, inter-token latency, interruption) is observability-only + (customer trace / App Insights) and is not part of the persisted conversation content. + :vartype store: bool + """ + + kind: Literal[AgentKind.VOICE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The kind discriminator for a voice agent definition. Always ``voice``. Required. VOICE.""" + model_type: Optional[Union[str, "_models.VoiceModelType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the model backing this voice agent is served. Required with ``model`` for a model-backed + voice agent and omitted when ``conversation_engine`` is provided. This is independent of the + architecture (realtime or cascaded), which the service derives from the selected model. Known + values are: \"managed\" and \"self_deployed\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The model to use for this agent. Required with ``model_type`` for a model-backed voice agent + and omitted when ``conversation_engine`` is provided. The model must support realtime or + cascaded voice.""" + conversation_engine: Optional["_models.VoiceConversationEngine"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The engine that owns conversation handling for this voice agent. Exactly one of this property + and the model-backed configuration (``model_type`` with ``model``) must be provided. When this + property is provided, ``model_type``, ``model``, ``instructions``, ``tools``, and + ``tool_choice`` must be omitted, and ``greeting.tool_choice`` cannot be ``required``, because + the engine owns the conversation logic. The initial implementation supports a hosted-agent + engine.""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A system (or developer) message inserted into the model's context. Supports template + substitution via ``structured_inputs``, rendered per session before the live session starts.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional session-start greeting. Template mode speaks exact rendered text; LLM-generated mode + asks the session model to author the opening response and may use configured tools.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio configuration, including input and output formats, voice, turn detection, noise + reduction, and transcription. These values are session defaults; a client may override + supported fields when connecting.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities the agent produces. Defaults to ``[\"audio\"]``. ``animation`` and + ``avatar`` are available when an avatar is configured.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + avatar: Optional["_models.VoiceAgentAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional avatar configuration. These values are session defaults and may be overridden when + connecting.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The tools the voice agent may use. Supported tool kinds are ``function`` (executed by the + client), ``mcp``, ``system`` (service-managed session controls), and ``toolbox``. Server-side + tools such as ``web_search``, ``azure_ai_search``, and ``openapi`` are provided through a + toolbox rather than declared directly.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the model chooses tools for generated responses. ``none`` prevents tool calls, ``auto`` + lets the model decide, ``required`` requires at least one tool call, and a specific function or + MCP tool can be selected with an object. Defaults to ``auto``. Is one of the following types: + Literal[\"none\"], Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + structured_inputs: Optional[dict[str, "_models.StructuredInputDefinition"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Set of structured inputs that participate in prompt template substitution, rendered per session + before the live session starts.""" + subagent_config: Optional["_models.VoiceAgentSubagentConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional configuration for sibling Foundry text agents that this voice agent may consult as + background specialists.""" + store: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether conversations with this agent are persisted. A single, all-or-nothing persistence + switch that defaults to ``false`` (privacy-safe: off by default). When ``true``, Foundry + persists the full conversation — the transcript/event timeline and raw audio. When ``false``, + nothing is persisted and no conversation is surfaced. There is no separate audio-logging + control; audio is persisted only as part of this switch. Latency/performance telemetry (e.g. + time-to-first-audio, inter-token latency, interruption) is observability-only (customer trace / + App Insights) and is not part of the persisted conversation content.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, + rai_config: Optional["_models.RaiConfig"] = None, + model_type: Optional[Union[str, "_models.VoiceModelType"]] = None, + model: Optional[str] = None, + conversation_engine: Optional["_models.VoiceConversationEngine"] = None, + instructions: Optional[str] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + avatar: Optional["_models.VoiceAgentAvatarConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + parallel_tool_calls: Optional[bool] = None, + structured_inputs: Optional[dict[str, "_models.StructuredInputDefinition"]] = None, + subagent_config: Optional["_models.VoiceAgentSubagentConfig"] = None, + store: Optional[bool] = None, ) -> None: ... @overload @@ -15401,52 +26582,42 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.SIMULATION_SEED # type: ignore + self.kind = AgentKind.VOICE # type: ignore -class SkillDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A skill resource. - - :ivar id: The unique identifier of the skill. Required. - :vartype id: str - :ivar name: The unique name of the skill. Required. - :vartype name: str - :ivar description: A human-readable description of the skill. Required. - :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the skill was created. Required. - :vartype created_at: ~datetime.datetime - :ivar default_version: The default version for the skill. Can be changed via updateSkill. - Required. - :vartype default_version: str - :ivar latest_version: The latest version for the skill. Required. - :vartype latest_version: str - """ +class VoiceAgentEchoCancellation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Server-side echo cancellation settings for input audio. - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the skill. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique name of the skill. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the skill. Required.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + :ivar type: The echo cancellation implementation. Always ``server_echo_cancellation``. + Required. Default value is "server_echo_cancellation". + :vartype type: str + :ivar reference_source: Whether reference audio comes from server playback or a client-provided + channel. Known values are: "server" and "client". + :vartype reference_source: str or + ~azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource + :ivar channels: The number of input channels. Use two interleaved channels when + ``reference_source`` is ``client``. + :vartype channels: int + """ + + type: Literal["server_echo_cancellation"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The echo cancellation implementation. Always ``server_echo_cancellation``. Required. Default + value is \"server_echo_cancellation\".""" + reference_source: Optional[Union[str, "_models.VoiceAgentEchoCancellationReferenceSource"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The Unix timestamp (seconds) when the skill was created. Required.""" - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The default version for the skill. Can be changed via updateSkill. Required.""" - latest_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The latest version for the skill. Required.""" + """Whether reference audio comes from server playback or a client-provided channel. Known values + are: \"server\" and \"client\".""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of input channels. Use two interleaved channels when ``reference_source`` is + ``client``.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - description: str, - created_at: datetime.datetime, - default_version: str, - latest_version: str, + reference_source: Optional[Union[str, "_models.VoiceAgentEchoCancellationReferenceSource"]] = None, + channels: Optional[int] = None, ) -> None: ... @overload @@ -15458,52 +26629,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type: Literal["server_echo_cancellation"] = "server_echo_cancellation" -class SkillInlineContent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Inline content for defining a simple skill without uploading files. Follows the agentskills.io - SKILL.md specification. +class VoiceAgentEndOfUtteranceDetection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Semantic end-of-utterance detection configuration. - :ivar description: A human-readable description of what the skill does and when to use it. - Required. - :vartype description: str - :ivar instructions: The skill instructions in markdown format. This is the body content of the - SKILL.md file. Required. - :vartype instructions: str - :ivar license: License name or reference to a bundled license file. - :vartype license: str - :ivar compatibility: Environment requirements or compatibility notes for the skill. - :vartype compatibility: str - :ivar metadata: Arbitrary key-value metadata for additional properties. - :vartype metadata: dict[str, str] - :ivar allowed_tools: List of pre-approved tools the skill may use. Experimental. - :vartype allowed_tools: list[str] + :ivar model: The semantic detection model. Required. Known values are: "semantic_detection_v1", + "semantic_detection_v1_en", "semantic_detection_v1_multilingual", and + "smart_end_of_turn_detection". + :vartype model: str or ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel + :ivar threshold_level: The sensitivity threshold. Known values are: "low", "medium", "high", + and "default". + :vartype threshold_level: str or + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel + :ivar timeout_ms: The detection timeout in milliseconds. + :vartype timeout_ms: ~datetime.timedelta """ - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of what the skill does and when to use it. Required.""" - instructions: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The skill instructions in markdown format. This is the body content of the SKILL.md file. - Required.""" - license: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """License name or reference to a bundled license file.""" - compatibility: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Environment requirements or compatibility notes for the skill.""" - metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Arbitrary key-value metadata for additional properties.""" - allowed_tools: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """List of pre-approved tools the skill may use. Experimental.""" + model: Union[str, "_models.VoiceAgentEndOfUtteranceDetectionModel"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The semantic detection model. Required. Known values are: \"semantic_detection_v1\", + \"semantic_detection_v1_en\", \"semantic_detection_v1_multilingual\", and + \"smart_end_of_turn_detection\".""" + threshold_level: Optional[Union[str, "_models.VoiceAgentEndOfUtteranceThresholdLevel"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sensitivity threshold. Known values are: \"low\", \"medium\", \"high\", and \"default\".""" + timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The detection timeout in milliseconds.""" @overload def __init__( self, *, - description: str, - instructions: str, - license: Optional[str] = None, - compatibility: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, - allowed_tools: Optional[list[str]] = None, + model: Union[str, "_models.VoiceAgentEndOfUtteranceDetectionModel"], + threshold_level: Optional[Union[str, "_models.VoiceAgentEndOfUtteranceThresholdLevel"]] = None, + timeout_ms: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -15517,32 +26682,25 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SkillReferenceParam( - ContainerSkill, discriminator="skill_reference" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """SkillReferenceParam. +class VoiceAgentTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A tool usable by a voice agent. - :ivar type: References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE. - :vartype type: str or ~azure.ai.projects.models.SKILL_REFERENCE - :ivar skill_id: The ID of the referenced skill. Required. - :vartype skill_id: str - :ivar version: Optional skill version. Use a positive integer or 'latest'. Omit for default. - :vartype version: str + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentFunctionTool, VoiceAgentMcpTool, VoiceAgentSystemTool, VoiceAgentToolboxTool + + :ivar type: The tool kind. Required. Default value is None. + :vartype type: str """ - type: Literal[ContainerSkillType.SKILL_REFERENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE.""" - skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The ID of the referenced skill. Required.""" - version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Optional skill version. Use a positive integer or 'latest'. Omit for default.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The tool kind. Required. Default value is None.""" @overload def __init__( self, *, - skill_id: str, - version: Optional[str] = None, + type: str, ) -> None: ... @overload @@ -15554,51 +26712,43 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ContainerSkillType.SKILL_REFERENCE # type: ignore -class SkillVersion(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A specific version of a skill. +class VoiceAgentFunctionTool( + VoiceAgentTool, discriminator="function" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A native function tool executed by the client. - :ivar id: The unique identifier of the skill version. Required. - :vartype id: str - :ivar skill_id: The identifier of the parent skill. Required. - :vartype skill_id: str - :ivar name: The name of the skill version. Required. - :vartype name: str - :ivar version: The version identifier. Skill versions are immutable. Required. - :vartype version: str - :ivar description: A human-readable description of the skill version. Required. + :ivar description: The description of the function, including guidance on when and how to call + it, and guidance about what to tell the user when calling (if anything). :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the skill version was created. Required. - :vartype created_at: ~datetime.datetime - """ - - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the skill version. Required.""" - skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The identifier of the parent skill. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the skill version. Required.""" - version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier. Skill versions are immutable. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the skill version. Required.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + :ivar parameters: Parameters of the function in JSON Schema. + :vartype parameters: ~azure.ai.projects.models.RealtimeFunctionToolParameters + :ivar type: Required. Default value is "function". + :vartype type: str + :ivar name: The function name. Required. + :vartype name: str + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The description of the function, including guidance on when and how to call it, and guidance + about what to tell the user when calling (if anything).""" + parameters: Optional["_models.RealtimeFunctionToolParameters"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The Unix timestamp (seconds) when the skill version was created. Required.""" + """Parameters of the function in JSON Schema.""" + type: Literal["function"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"function\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The function name. Required.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - skill_id: str, name: str, - version: str, - description: str, - created_at: datetime.datetime, + description: Optional[str] = None, + parameters: Optional["_models.RealtimeFunctionToolParameters"] = None, ) -> None: ... @overload @@ -15610,32 +26760,22 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "function" # type: ignore -class ToolChoiceParam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """How the model should select which tool (or tools) to use when generating a response. See the - ``tools`` parameter to see how to specify which tools the model can call. +class VoiceAgentGreetingConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Session-start greeting configuration for a voice agent. You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolChoiceAllowed, SpecificApplyPatchParam, ToolChoiceCodeInterpreter, ToolChoiceComputer, - ToolChoiceComputerUse, ToolChoiceComputerUsePreview, ToolChoiceCustom, ToolChoiceFileSearch, - ToolChoiceFunction, ToolChoiceImageGeneration, ToolChoiceMCP, - SpecificProgrammaticToolCallingParam, SpecificFunctionShellParam, ToolChoiceWebSearchPreview, - ToolChoiceWebSearchPreview20250311 + VoiceAgentLlmGeneratedGreetingConfig, VoiceAgentTemplateGreetingConfig - :ivar type: Required. Known values are: "allowed_tools", "function", "mcp", "custom", - "programmatic_tool_calling", "apply_patch", "shell", "file_search", "web_search_preview", - "computer_use_preview", "web_search_preview_2025_03_11", "image_generation", - "code_interpreter", "computer", and "computer_use". - :vartype type: str or ~azure.ai.projects.models.ToolChoiceParamType + :ivar type: The greeting mode. Required. Default value is None. + :vartype type: str """ __mapping__: dict[str, _Model] = {} type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"allowed_tools\", \"function\", \"mcp\", \"custom\", - \"programmatic_tool_calling\", \"apply_patch\", \"shell\", \"file_search\", - \"web_search_preview\", \"computer_use_preview\", \"web_search_preview_2025_03_11\", - \"image_generation\", \"code_interpreter\", \"computer\", and \"computer_use\".""" + """The greeting mode. Required. Default value is None.""" @overload def __init__( @@ -15655,19 +26795,91 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SpecificApplyPatchParam(ToolChoiceParam, discriminator="apply_patch"): - """Specific apply patch tool choice. +class VoiceAgentInputTranscription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Asynchronous input-audio transcription configuration. Extends the OpenAI Realtime transcription + options with the Azure and MAI transcription models, custom speech models, and phrase hints. - :ivar type: The tool to call. Always ``apply_patch``. Required. APPLY_PATCH. - :vartype type: str or ~azure.ai.projects.models.APPLY_PATCH + :ivar language: The language of the input audio. Supplying the input language in `ISO-639-1 + `_ (e.g. ``en``) format will improve + accuracy and latency. + :vartype language: str + :ivar languages: Possible languages of the input audio, in `ISO-639-1 + `_ format. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``. + :vartype languages: list[str] + :ivar keywords: Words or phrases to guide transcription of the input audio. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``. + :vartype keywords: list[str] + :ivar prompt: An optional text to guide the model's style or continue a previous audio segment. + For ``whisper-1``, the `prompt is a list of keywords `_. + For ``gpt-4o-transcribe`` models (excluding ``gpt-4o-transcribe-diarize``), the prompt is a + free text string, for example "expect words related to technology". Prompt is not supported + with ``gpt-realtime-whisper`` in GA Realtime sessions. + :vartype prompt: str + :ivar delay: Controls how long the model waits before emitting transcription text. Higher + values can improve transcription accuracy at the cost of latency. Only supported with + ``gpt-realtime-whisper`` in GA Realtime sessions. Is one of the following types: + Literal["minimal"], Literal["low"], Literal["medium"], Literal["high"], Literal["xhigh"] + :vartype delay: str or str or str or str or str + :ivar model: The transcription model identifier. Configure customer custom speech deployments + in ``custom_speech``. Required. Known values are: "whisper-1", "gpt-realtime-whisper", + "gpt-4o-transcribe", "gpt-4o-mini-transcribe", "gpt-4o-transcribe-diarize", "gpt-transcribe", + "gpt-live-transcribe", "mai-transcribe", and "azure-speech". + :vartype model: str or ~azure.ai.projects.models.VoiceAgentInputTranscriptionModel + :ivar custom_speech: Optional customer custom speech deployment configuration, keyed by locale. + :vartype custom_speech: dict[str, str] + :ivar phrase_list: Optional phrase hints that bias recognition toward domain terms. + :vartype phrase_list: list[str] """ - type: Literal[ToolChoiceParamType.APPLY_PATCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``apply_patch``. Required. APPLY_PATCH.""" + language: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The language of the input audio. Supplying the input language in `ISO-639-1 + `_ (e.g. ``en``) format will improve + accuracy and latency.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Possible languages of the input audio, in `ISO-639-1 + `_ format. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``.""" + keywords: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Words or phrases to guide transcription of the input audio. Supported by ``gpt-transcribe`` and + ``gpt-live-transcribe``.""" + prompt: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional text to guide the model's style or continue a previous audio segment. For + ``whisper-1``, the `prompt is a list of keywords `_. For + ``gpt-4o-transcribe`` models (excluding ``gpt-4o-transcribe-diarize``), the prompt is a free + text string, for example \"expect words related to technology\". Prompt is not supported with + ``gpt-realtime-whisper`` in GA Realtime sessions.""" + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls how long the model waits before emitting transcription text. Higher values can improve + transcription accuracy at the cost of latency. Only supported with ``gpt-realtime-whisper`` in + GA Realtime sessions. Is one of the following types: Literal[\"minimal\"], Literal[\"low\"], + Literal[\"medium\"], Literal[\"high\"], Literal[\"xhigh\"]""" + model: Union[str, "_models.VoiceAgentInputTranscriptionModel"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The transcription model identifier. Configure customer custom speech deployments in + ``custom_speech``. Required. Known values are: \"whisper-1\", \"gpt-realtime-whisper\", + \"gpt-4o-transcribe\", \"gpt-4o-mini-transcribe\", \"gpt-4o-transcribe-diarize\", + \"gpt-transcribe\", \"gpt-live-transcribe\", \"mai-transcribe\", and \"azure-speech\".""" + custom_speech: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional customer custom speech deployment configuration, keyed by locale.""" + phrase_list: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional phrase hints that bias recognition toward domain terms.""" @overload def __init__( self, + *, + model: Union[str, "_models.VoiceAgentInputTranscriptionModel"], + language: Optional[str] = None, + languages: Optional[list[str]] = None, + keywords: Optional[list[str]] = None, + prompt: Optional[str] = None, + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] = None, + custom_speech: Optional[dict[str, str]] = None, + phrase_list: Optional[list[str]] = None, ) -> None: ... @overload @@ -15679,22 +26891,41 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.APPLY_PATCH # type: ignore -class SpecificFunctionShellParam(ToolChoiceParam, discriminator="shell"): - """Specific shell tool choice. +class VoiceAgentInterimResponseConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Fields shared by interim-response configurations. - :ivar type: The tool to call. Always ``shell``. Required. SHELL. - :vartype type: str or ~azure.ai.projects.models.SHELL + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentLlmInterimResponseConfig, VoiceAgentStaticInterimResponseConfig + + :ivar type: The interim-response implementation. Required. Default value is None. + :vartype type: str + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta """ - type: Literal[ToolChoiceParamType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``shell``. Required. SHELL.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The interim-response implementation. Required. Default value is None.""" + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Conditions that may trigger one interim response.""" + latency_threshold_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The latency threshold in milliseconds.""" @overload def __init__( self, + *, + type: str, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -15706,23 +26937,41 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.SHELL # type: ignore -class SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator="programmatic_tool_calling"): - """SpecificProgrammaticToolCallingParam. +class VoiceAgentLlmGeneratedGreetingConfig( + VoiceAgentGreetingConfig, discriminator="llm_generated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A greeting authored by the session model from a scoped opening-turn prompt. - :ivar type: The tool to call. Always ``programmatic_tool_calling``. Required. - PROGRAMMATIC_TOOL_CALLING. - :vartype type: str or ~azure.ai.projects.models.PROGRAMMATIC_TOOL_CALLING + :ivar type: Required. Default value is "llm_generated". + :vartype type: str + :ivar prompt: The Handlebars prompt that guides the opening turn. Required. + :vartype prompt: str + :ivar tool_choice: The tool-selection policy for the opening response. Defaults to ``none``. Is + one of the following types: Literal["none"], Literal["auto"], Literal["required"], + ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP """ - type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``programmatic_tool_calling``. Required. PROGRAMMATIC_TOOL_CALLING.""" + type: Literal["llm_generated"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"llm_generated\".""" + prompt: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Handlebars prompt that guides the opening turn. Required.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The tool-selection policy for the opening response. Defaults to ``none``. Is one of the + following types: Literal[\"none\"], Literal[\"auto\"], Literal[\"required\"], + ToolChoiceFunction, ToolChoiceMCP""" @overload def __init__( self, + *, + prompt: str, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, ) -> None: ... @overload @@ -15734,42 +26983,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING # type: ignore + self.type = "llm_generated" # type: ignore -class StructuredInputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An structured input that can participate in prompt template substitutions and tool argument - binding. +class VoiceAgentLlmInterimResponseConfig( + VoiceAgentInterimResponseConfig, discriminator="llm_interim_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An interim response generated by a language model. - :ivar description: A human-readable description of the input. - :vartype description: str - :ivar default_value: The default value for the input if no run-time value is provided. - :vartype default_value: any - :ivar schema: The JSON schema for the structured input (optional). - :vartype schema: dict[str, any] - :ivar required: Whether the input property is required when the agent is invoked. The service - defaults to ``false`` if a value is not specified by the caller. - :vartype required: bool + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta + :ivar type: Required. Default value is "llm_interim_response". + :vartype type: str + :ivar model: The model used to generate interim responses. + :vartype model: str + :ivar instructions: Optional instructions for generating interim responses. + :vartype instructions: str + :ivar max_completion_tokens: The maximum completion-token count for an interim response. + :vartype max_completion_tokens: int """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the input.""" - default_value: Optional[Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The default value for the input if no run-time value is provided.""" - schema: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The JSON schema for the structured input (optional).""" - required: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether the input property is required when the agent is invoked. The service defaults to - ``false`` if a value is not specified by the caller.""" + type: Literal["llm_interim_response"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"llm_interim_response\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The model used to generate interim responses.""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional instructions for generating interim responses.""" + max_completion_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The maximum completion-token count for an interim response.""" @overload def __init__( self, *, - description: Optional[str] = None, - default_value: Optional[Any] = None, - schema: Optional[dict[str, Any]] = None, - required: Optional[bool] = None, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, + model: Optional[str] = None, + instructions: Optional[str] = None, + max_completion_tokens: Optional[int] = None, ) -> None: ... @overload @@ -15781,103 +27034,137 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "llm_interim_response" # type: ignore -class StructuredOutputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A structured output that can be produced by the agent. +class VoiceAgentMcpTool( + VoiceAgentTool, discriminator="mcp" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An MCP tool available to a voice agent. - :ivar name: The name of the structured output. Required. - :vartype name: str - :ivar description: A description of the output to emit. Used by the model to determine when to - emit the output. Required. - :vartype description: str - :ivar schema: The JSON schema for the structured output. Required. - :vartype schema: dict[str, any] - :ivar strict: Whether to enforce strict validation. Default ``true``. Required. - :vartype strict: bool + :ivar server_label: A label for this MCP server, used to identify it in tool calls. Required. + :vartype server_label: str + :ivar authorization: An OAuth access token that can be used with a remote MCP server, either + with a custom MCP server URL or a service connector. Your application must handle the OAuth + authorization flow and provide the token here. + :vartype authorization: str + :ivar server_description: Optional description of the MCP server, used to provide more context. + :vartype server_description: str + :ivar headers: + :vartype headers: dict[str, str] + :ivar allowed_tools: Is either a [str] type or a MCPToolFilter type. + :vartype allowed_tools: list[str] or ~azure.ai.projects.models.MCPToolFilter + :ivar allowed_callers: + :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] + :ivar require_approval: Is one of the following types: MCPToolRequireApproval, + Literal["always"], Literal["never"] + :vartype require_approval: ~azure.ai.projects.models.MCPToolRequireApproval or str or str + :ivar defer_loading: Whether this MCP tool is deferred and discovered via tool search. + :vartype defer_loading: bool + :ivar project_connection_id: The connection ID in the project for the MCP server. The + connection stores authentication and other connection details needed to connect to the MCP + server. + :vartype project_connection_id: str + :ivar tool_configs: Deprecated. This property is deprecated and will be removed in a future + version. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: Required. Default value is "mcp". + :vartype type: str + :ivar server_url: The URL for the MCP server. + :vartype server_url: str + :ivar response_scheduling: When the MCP invocation creates a follow-up response. Defaults to + ``when_idle``. Known values are: "silent", "when_idle", "interrupt", and "skip_if_busy". + :vartype response_scheduling: str or ~azure.ai.projects.models.VoiceAgentToolResponseScheduling """ - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the structured output. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A description of the output to emit. Used by the model to determine when to emit the output. - Required.""" - schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The JSON schema for the structured output. Required.""" - strict: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether to enforce strict validation. Default ``true``. Required.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A label for this MCP server, used to identify it in tool calls. Required.""" + authorization: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An OAuth access token that can be used with a remote MCP server, either with a custom MCP + server URL or a service connector. Your application must handle the OAuth authorization flow + and provide the token here.""" + server_description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional description of the MCP server, used to provide more context.""" + headers: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + allowed_tools: Optional[Union[list[str], "_models.MCPToolFilter"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a [str] type or a MCPToolFilter type.""" + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + require_approval: Optional[Union["_models.MCPToolRequireApproval", Literal["always"], Literal["never"]]] = ( + rest_field(visibility=["read", "create", "update", "delete", "query"]) + ) + """Is one of the following types: MCPToolRequireApproval, Literal[\"always\"], Literal[\"never\"]""" + defer_loading: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether this MCP tool is deferred and discovered via tool search.""" + project_connection_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The connection ID in the project for the MCP server. The connection stores authentication and + other connection details needed to connect to the MCP server.""" + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Deprecated. This property is deprecated and will be removed in a future version.""" + type: Literal["mcp"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"mcp\".""" + server_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The URL for the MCP server.""" + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the MCP invocation creates a follow-up response. Defaults to ``when_idle``. Known values + are: \"silent\", \"when_idle\", \"interrupt\", and \"skip_if_busy\".""" @overload def __init__( self, *, - name: str, - description: str, - schema: dict[str, Any], - strict: bool, + server_label: str, + authorization: Optional[str] = None, + server_description: Optional[str] = None, + headers: Optional[dict[str, str]] = None, + allowed_tools: Optional[Union[list[str], "_models.MCPToolFilter"]] = None, + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + require_approval: Optional[Union["_models.MCPToolRequireApproval", Literal["always"], Literal["never"]]] = None, + defer_loading: Optional[bool] = None, + project_connection_id: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + server_url: Optional[str] = None, + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = None, ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - - -class TaxonomyCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Taxonomy category definition. - - :ivar id: Unique identifier of the taxonomy category. Required. - :vartype id: str - :ivar name: Name of the taxonomy category. Required. - :vartype name: str - :ivar description: Description of the taxonomy category. - :vartype description: str - :ivar risk_category: Risk category associated with this taxonomy category. Required. Known - values are: "HateUnfairness", "Violence", "Sexual", "SelfHarm", "ProtectedMaterial", - "CodeVulnerability", "UngroundedAttributes", "ProhibitedActions", "SensitiveDataLeakage", and - "TaskAdherence". - :vartype risk_category: str or ~azure.ai.projects.models.RiskCategory - :ivar sub_categories: List of taxonomy sub categories. Required. - :vartype sub_categories: list[~azure.ai.projects.models.TaxonomySubCategory] - :ivar properties: Additional properties for the taxonomy category. - :vartype properties: dict[str, str] - """ - - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Unique identifier of the taxonomy category. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Name of the taxonomy category. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the taxonomy category.""" - risk_category: Union[str, "_models.RiskCategory"] = rest_field( - name="riskCategory", visibility=["read", "create", "update", "delete", "query"] - ) - """Risk category associated with this taxonomy category. Required. Known values are: - \"HateUnfairness\", \"Violence\", \"Sexual\", \"SelfHarm\", \"ProtectedMaterial\", - \"CodeVulnerability\", \"UngroundedAttributes\", \"ProhibitedActions\", - \"SensitiveDataLeakage\", and \"TaskAdherence\".""" - sub_categories: list["_models.TaxonomySubCategory"] = rest_field( - name="subCategories", visibility=["read", "create", "update", "delete", "query"] + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "mcp" # type: ignore + + +class VoiceAgentNoiseReduction(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Input audio noise reduction configuration. + + :ivar type: The noise reduction mode. Required. Known values are: "near_field", "far_field", + and "azure_deep_noise_suppression". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentNoiseReductionType + """ + + type: Union[str, "_models.VoiceAgentNoiseReductionType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """List of taxonomy sub categories. Required.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional properties for the taxonomy category.""" + """The noise reduction mode. Required. Known values are: \"near_field\", \"far_field\", and + \"azure_deep_noise_suppression\".""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - risk_category: Union[str, "_models.RiskCategory"], - sub_categories: list["_models.TaxonomySubCategory"], - description: Optional[str] = None, - properties: Optional[dict[str, str]] = None, + type: Union[str, "_models.VoiceAgentNoiseReductionType"], ) -> None: ... @overload @@ -15891,41 +27178,98 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TaxonomySubCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Taxonomy sub-category definition. +class VoiceAgentRealtimeResponseBase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Properties shared by realtime responses returned by the voice-agent service. - :ivar id: Unique identifier of the taxonomy sub-category. Required. + :ivar id: The unique ID of the response, will look like ``resp_1234``. :vartype id: str - :ivar name: Name of the taxonomy sub-category. Required. - :vartype name: str - :ivar description: Description of the taxonomy sub-category. - :vartype description: str - :ivar enabled: List of taxonomy items under this sub-category. Required. - :vartype enabled: bool - :ivar properties: Additional properties for the taxonomy sub-category. - :vartype properties: dict[str, str] - """ - - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Unique identifier of the taxonomy sub-category. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Name of the taxonomy sub-category. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the taxonomy sub-category.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """List of taxonomy items under this sub-category. Required.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional properties for the taxonomy sub-category.""" + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar conversation_id: Which conversation the response is added to, determined by the + ``conversation`` field in the ``response.create`` event. If ``auto``, the response will be + added to the default conversation and the value of ``conversation_id`` will be an id like + ``conv_1234``. If ``none``, the response will not be added to any conversation and the value of + ``conversation_id`` will be ``null``. If responses are being triggered automatically by VAD the + response will be added to the default conversation. + :vartype conversation_id: str + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the response, will look like ``resp_1234``.""" + object: Optional[Literal["realtime.response"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The object type, must be ``realtime.response``. Default value is \"realtime.response\".""" + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The final status of the response (``completed``, ``cancelled``, ``failed``, or ``incomplete``, + ``in_progress``). Is one of the following types: Literal[\"completed\"], + Literal[\"cancelled\"], Literal[\"failed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + status_details: Optional["_models.RealtimeResponseStatusDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional details about the status.""" + metadata: Optional["_models.Metadata"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the Response, this will correspond to billing. A Realtime API session will + maintain a conversation context and append new Items to the Conversation, thus output from + previous turns (text and audio tokens) will become the input for later turns.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Which conversation the response is added to, determined by the ``conversation`` field in the + ``response.create`` event. If ``auto``, the response will be added to the default conversation + and the value of ``conversation_id`` will be an id like ``conv_1234``. If ``none``, the + response will not be added to any conversation and the value of ``conversation_id`` will be + ``null``. If responses are being triggered automatically by VAD the response will be added to + the default conversation.""" + output_modalities: Optional[list[Literal["text", "audio"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The set of modalities the model used to respond, currently the only possible values are + ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text transcript. Setting the + output to mode ``text`` will disable audio output from the model.""" + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls, that + was used in this response. Is either a int type or a Literal[\"inf\"] type.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - enabled: bool, - description: Optional[str] = None, - properties: Optional[dict[str, str]] = None, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + metadata: Optional["_models.Metadata"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + conversation_id: Optional[str] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, ) -> None: ... @overload @@ -15939,23 +27283,76 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TelemetryConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Customer-supplied telemetry configuration for exporting container logs, traces, and metrics. - - :ivar endpoints: Customer-supplied telemetry export endpoint configurations. Required. - :vartype endpoints: list[~azure.ai.projects.models.TelemetryEndpoint] - """ +class VoiceAgentRealtimeResponse( + VoiceAgentRealtimeResponseBase +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A live realtime response returned by the voice-agent service in both ``response.created`` and + ``response.done`` events. - endpoints: list["_models.TelemetryEndpoint"] = rest_field( + :ivar id: The unique ID of the response, will look like ``resp_1234``. + :vartype id: str + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar conversation_id: Which conversation the response is added to, determined by the + ``conversation`` field in the ``response.create`` event. If ``auto``, the response will be + added to the default conversation and the value of ``conversation_id`` will be an id like + ``conv_1234``. If ``none``, the response will not be added to any conversation and the value of + ``conversation_id`` will be ``null``. If responses are being triggered automatically by VAD the + response will be added to the default conversation. + :vartype conversation_id: str + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar audio: The audio configuration used by the live response, including flat voice provider, + locale, and format fields under ``output``. + :vartype audio: ~azure.ai.projects.models.VoiceResponseAudio + :ivar output: The items produced by the live response. + :vartype output: list[~azure.ai.projects.models.RealtimeConversationItem] + """ + + audio: Optional["_models.VoiceResponseAudio"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Customer-supplied telemetry export endpoint configurations. Required.""" + """The audio configuration used by the live response, including flat voice provider, locale, and + format fields under ``output``.""" + output: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The items produced by the live response.""" @overload def __init__( self, *, - endpoints: list["_models.TelemetryEndpoint"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + metadata: Optional["_models.Metadata"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + conversation_id: Optional[str] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + audio: Optional["_models.VoiceResponseAudio"] = None, + output: Optional[list["_models.RealtimeConversationItem"]] = None, ) -> None: ... @overload @@ -15969,31 +27366,138 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TextResponseFormat(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An object specifying the format that the model must output. Configuring ``{ "type": - "json_schema" }`` enables Structured Outputs, which ensures the model will match your supplied - JSON schema. Learn more in the `Structured Outputs guide `_. - The default format is ``{ "type": "text" }`` with no additional options. *Not recommended for - gpt-4o and newer models:** Setting to ``{ "type": "json_object" }`` enables the older JSON - mode, which ensures the message the model generates is valid JSON. Using ``json_schema`` is - preferred for models that support it. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - TextResponseFormatJsonObject, TextResponseFormatJsonSchema, TextResponseFormatText +class VoiceAgentResponseCreateParams(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Parameters accepted by a voice-agent ``response.create`` event. - :ivar type: Required. Known values are: "text", "json_schema", and "json_object". - :vartype type: str or ~azure.ai.projects.models.TextResponseFormatConfigurationType + :ivar instructions: The default system instructions (i.e. system message) prepended to model + calls. This field allows the client to guide the model on desired responses. The model can be + instructed on response content and format, (e.g. "be extremely succinct", "act friendly", "here + are examples of good responses") and on audio behavior (e.g. "talk quickly", "inject emotion + into your voice", "laugh frequently"). The instructions are not guaranteed to be followed by + the model, but they provide guidance to the model on the desired behavior. Note that the server + sets default instructions which will be used if this field is not set and are visible in the + ``session.created`` event at the start of the session. + :vartype instructions: str + :ivar tools: Tools available to the model. + :vartype tools: list[~azure.ai.projects.models.RealtimeFunctionTool or + ~azure.ai.projects.models.MCPTool] + :ivar tool_choice: How the model chooses tools. Provide one of the string modes or force a + specific function/MCP tool. Is one of the following types: Union[str, + "_models.ToolChoiceOptions"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or ~azure.ai.projects.models.ToolChoiceOptions or + ~azure.ai.projects.models.ToolChoiceFunction or ~azure.ai.projects.models.ToolChoiceMCP + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. Only + supported by reasoning Realtime models such as ``gpt-realtime-2``. + :vartype parallel_tool_calls: bool + :ivar reasoning: + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls. Provide an integer between 1 and 4096 to limit output tokens, or + ``inf`` for the maximum available tokens for a given model. Defaults to ``inf``. Is either a + int type or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar conversation: Controls which conversation the response is added to. Currently supports + ``auto`` and ``none``, with ``auto`` as the default value. The ``auto`` value means that the + contents of the response will be added to the default conversation. Set this to ``none`` to + create an out-of-band response which will not add items to default conversation. Is one of the + following types: Literal["auto"], Literal["none"], str + :vartype conversation: str or str or str + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar output_modalities: Modalities that the response may return. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: Response-specific audio settings. + :vartype audio: ~azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig + :ivar input: Conversation items used as inline response input. + :vartype input: list[~azure.ai.projects.models.RealtimeConversationItem] + :ivar pre_generated_assistant_message: A pre-generated assistant message used to begin the + response. + :vartype pre_generated_assistant_message: ~azure.ai.projects.models.RealtimeConversationItem + :ivar interim_response: Interim-response settings for this response. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"text\", \"json_schema\", and \"json_object\".""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default system instructions (i.e. system message) prepended to model calls. This field + allows the client to guide the model on desired responses. The model can be instructed on + response content and format, (e.g. \"be extremely succinct\", \"act friendly\", \"here are + examples of good responses\") and on audio behavior (e.g. \"talk quickly\", \"inject emotion + into your voice\", \"laugh frequently\"). The instructions are not guaranteed to be followed by + the model, but they provide guidance to the model on the desired behavior. Note that the server + sets default instructions which will be used if this field is not set and are visible in the + ``session.created`` event at the start of the session.""" + tools: Optional[list[Union["_models.RealtimeFunctionTool", "_models.MCPTool"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the model.""" + tool_choice: Optional[ + Union[str, "_models.ToolChoiceOptions", "_models.ToolChoiceFunction", "_models.ToolChoiceMCP"] + ] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """How the model chooses tools. Provide one of the string modes or force a specific function/MCP + tool. Is one of the following types: Union[str, \"_models.ToolChoiceOptions\"], + ToolChoiceFunction, ToolChoiceMCP""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel. Only supported by reasoning Realtime + models such as ``gpt-realtime-2``.""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls. + Provide an integer between 1 and 4096 to limit output tokens, or ``inf`` for the maximum + available tokens for a given model. Defaults to ``inf``. Is either a int type or a + Literal[\"inf\"] type.""" + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls which conversation the response is added to. Currently supports ``auto`` and ``none``, + with ``auto`` as the default value. The ``auto`` value means that the contents of the response + will be added to the default conversation. Set this to ``none`` to create an out-of-band + response which will not add items to default conversation. Is one of the following types: + Literal[\"auto\"], Literal[\"none\"], str""" + metadata: Optional["_models.Metadata"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Modalities that the response may return.""" + audio: Optional["_models.PickPropertiesVoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Response-specific audio settings.""" + input: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Conversation items used as inline response input.""" + pre_generated_assistant_message: Optional["_models.RealtimeConversationItem"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A pre-generated assistant message used to begin the response.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for this response.""" @overload def __init__( self, *, - type: str, + instructions: Optional[str] = None, + tools: Optional[list[Union["_models.RealtimeFunctionTool", "_models.MCPTool"]]] = None, + tool_choice: Optional[ + Union[str, "_models.ToolChoiceOptions", "_models.ToolChoiceFunction", "_models.ToolChoiceMCP"] + ] = None, + parallel_tool_calls: Optional[bool] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] = None, + metadata: Optional["_models.Metadata"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.PickPropertiesVoiceAgentAudioConfig"] = None, + input: Optional[list["_models.RealtimeConversationItem"]] = None, + pre_generated_assistant_message: Optional["_models.RealtimeConversationItem"] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, ) -> None: ... @overload @@ -16007,20 +27511,36 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TextResponseFormatJsonObject(TextResponseFormat, discriminator="json_object"): - """JSON object. +class VoiceAgentRtcCallErrorDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Details of a WebRTC signaling error. - :ivar type: The type of response format being defined. Always ``json_object``. Required. - JSON_OBJECT. - :vartype type: str or ~azure.ai.projects.models.JSON_OBJECT + :ivar type: The error category, following the VoiceLive wire contract: + ``invalid_request_error`` for a client-side signaling fault (for example, a malformed SDP + offer) or ``server_error`` for a service-side failure. Additional categories may be added over + time. Required. + :vartype type: str + :ivar code: A machine-readable error code, when available. + :vartype code: str + :ivar message: A human-readable error message. Required. + :vartype message: str """ - type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``json_object``. Required. JSON_OBJECT.""" + type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The error category, following the VoiceLive wire contract: ``invalid_request_error`` for a + client-side signaling fault (for example, a malformed SDP offer) or ``server_error`` for a + service-side failure. Additional categories may be added over time. Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A machine-readable error code, when available.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable error message. Required.""" @overload def __init__( self, + *, + type: str, + message: str, + code: Optional[str] = None, ) -> None: ... @overload @@ -16032,49 +27552,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.JSON_OBJECT # type: ignore -class TextResponseFormatJsonSchema( - TextResponseFormat, discriminator="json_schema" +class VoiceAgentSemanticVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="semantic_vad" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """JSON schema. + """OpenAI semantic VAD turn-detection settings. - :ivar type: The type of response format being defined. Always ``json_schema``. Required. - JSON_SCHEMA. - :vartype type: str or ~azure.ai.projects.models.JSON_SCHEMA - :ivar description: A description of what the response format is for, used by the model to - determine how to respond in the format. - :vartype description: str - :ivar name: The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and - dashes, with a maximum length of 64. Required. - :vartype name: str - :ivar schema: Required. - :vartype schema: dict[str, any] - :ivar strict: - :vartype strict: bool + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar eagerness: Is one of the following types: Literal["low"], Literal["medium"], + Literal["high"], Literal["auto"] + :vartype eagerness: str or str or str or str + :ivar create_response: + :vartype create_response: bool + :ivar interrupt_response: + :vartype interrupt_response: bool + :ivar type: Required. Semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.SEMANTIC_VAD """ - type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``json_schema``. Required. JSON_SCHEMA.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A description of what the response format is for, used by the model to determine how to respond - in the format.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with - a maximum length of 64. Required.""" - schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" - strict: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + eagerness: Optional[Literal["low", "medium", "high", "auto"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"low\"], Literal[\"medium\"], Literal[\"high\"], + Literal[\"auto\"]""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + type: Literal[VoiceAgentTurnDetectionType.SEMANTIC_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Semantic voice activity detection.""" @overload def __init__( self, *, - name: str, - schema: dict[str, Any], - description: Optional[str] = None, - strict: Optional[bool] = None, + auto_truncate: Optional[bool] = None, + eagerness: Optional[Literal["low", "medium", "high", "auto"]] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, ) -> None: ... @overload @@ -16086,22 +27602,60 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.JSON_SCHEMA # type: ignore - + self.type = VoiceAgentTurnDetectionType.SEMANTIC_VAD # type: ignore -class TextResponseFormatText(TextResponseFormat, discriminator="text"): - """Text. - :ivar type: The type of response format being defined. Always ``text``. Required. TEXT. - :vartype type: str or ~azure.ai.projects.models.TEXT - """ +class VoiceAgentServerEventResponseAnimationBlendshapesDelta( + RealtimeServerEvent, discriminator="response.animation_blendshapes.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_blendshapes.delta`` server event. - type: Literal[TextResponseFormatConfigurationType.TEXT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``text``. Required. TEXT.""" + :ivar type: Required. RESPONSE_ANIMATION_BLENDSHAPES_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_BLENDSHAPES_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar frames: Animation frames as numeric blendshape weights. Required. + :vartype frames: list[list[float]] + :ivar frame_index: The index of the first frame in this delta. Required. + :vartype frame_index: int + """ + + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_BLENDSHAPES_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + frames: list[list[float]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Animation frames as numeric blendshape weights. Required.""" + frame_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the first frame in this delta. Required.""" @overload def __init__( self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + frames: list[list[float]], + frame_index: int, ) -> None: ... @overload @@ -16113,32 +27667,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.TEXT # type: ignore + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA # type: ignore -class TimerRoutineTrigger( - RoutineTrigger, discriminator="timer" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A one-shot timer routine trigger. +class VoiceAgentServerEventResponseAnimationBlendshapesDone( + RealtimeServerEvent, discriminator="response.animation_blendshapes.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_blendshapes.done`` server event. - :ivar type: The trigger type. Required. A one-shot timer trigger. - :vartype type: str or ~azure.ai.projects.models.TIMER - :ivar at: The UTC date and time at which the timer fires. - :vartype at: ~datetime.datetime + :ivar type: Required. RESPONSE_ANIMATION_BLENDSHAPES_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_BLENDSHAPES_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int """ - type: Literal[RoutineTriggerType.TIMER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The trigger type. Required. A one-shot timer trigger.""" - at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The UTC date and time at which the timer fires.""" + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_BLENDSHAPES_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - at: Optional[datetime.datetime] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, ) -> None: ... @overload @@ -16150,36 +27717,62 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = RoutineTriggerType.TIMER # type: ignore + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE # type: ignore -class ToolboxObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox that stores reusable tool definitions for agents. - - :ivar id: The unique identifier of the toolbox. Required. - :vartype id: str - :ivar name: The name of the toolbox. Required. - :vartype name: str - :ivar default_version: The version identifier that the toolbox currently points to. Defaults to - the latest version. Can be changed via updateToolbox. Required. - :vartype default_version: str - """ +class VoiceAgentServerEventResponseAnimationVisemeDelta( + RealtimeServerEvent, discriminator="response.animation_viseme.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_viseme.delta`` server event. - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the toolbox. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the toolbox. Required.""" - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier that the toolbox currently points to. Defaults to the latest version. - Can be changed via updateToolbox. Required.""" + :ivar type: Required. RESPONSE_ANIMATION_VISEME_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_VISEME_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar audio_offset_ms: Required. + :vartype audio_offset_ms: ~datetime.timedelta + :ivar viseme_id: Required. + :vartype viseme_id: int + """ + + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_VISEME_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + audio_offset_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Required.""" + viseme_id: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - default_version: str, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + audio_offset_ms: datetime.timedelta, + viseme_id: int, ) -> None: ... @overload @@ -16191,23 +27784,50 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA # type: ignore -class ToolboxPolicies(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Policy configuration for a toolbox, including content safety and other governance settings. +class VoiceAgentServerEventResponseAnimationVisemeDone( + RealtimeServerEvent, discriminator="response.animation_viseme.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_viseme.done`` server event. - :ivar rai_config: Responsible AI content filtering configuration. - :vartype rai_config: ~azure.ai.projects.models.RaiConfig + :ivar type: Required. RESPONSE_ANIMATION_VISEME_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_VISEME_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int """ - rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Responsible AI content filtering configuration.""" + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_VISEME_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - rai_config: Optional["_models.RaiConfig"] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, ) -> None: ... @overload @@ -16219,36 +27839,73 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE # type: ignore -class ToolboxSearchPreviewToolboxTool( - ToolboxTool, discriminator="toolbox_search_preview" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox search tool stored in a toolbox. +class VoiceAgentServerEventResponseAudioTimestampDelta( + RealtimeServerEvent, discriminator="response.audio_timestamp.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.audio_timestamp.delta`` server event. - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``toolbox_search_preview``. Required. - TOOLBOX_SEARCH_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH_PREVIEW + :ivar type: Required. RESPONSE_AUDIO_TIMESTAMP_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_AUDIO_TIMESTAMP_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar audio_offset_ms: Required. + :vartype audio_offset_ms: ~datetime.timedelta + :ivar audio_duration_ms: Required. + :vartype audio_duration_ms: ~datetime.timedelta + :ivar text: Required. + :vartype text: str + :ivar timestamp_type: Required. Default value is "word". + :vartype timestamp_type: str """ - type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``toolbox_search_preview``. Required. TOOLBOX_SEARCH_PREVIEW.""" + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_AUDIO_TIMESTAMP_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + audio_offset_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Required.""" + audio_duration_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + timestamp_type: Literal["word"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. Default value is \"word\".""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + audio_offset_ms: datetime.timedelta, + audio_duration_ms: datetime.timedelta, + text: str, ) -> None: ... @overload @@ -16260,29 +27917,51 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.TOOLBOX_SEARCH_PREVIEW # type: ignore + self.type = RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA # type: ignore + self.timestamp_type: Literal["word"] = "word" -class ToolboxShellEnvironment(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An execution environment for a shell tool stored in a toolbox. This environment model is scoped - to toolbox configuration and does not modify the OpenAI shell environment contract. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxShellContainerAutoEnvironment, ToolboxShellContainerReferenceEnvironment +class VoiceAgentServerEventResponseAudioTimestampDone( + RealtimeServerEvent, discriminator="response.audio_timestamp.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.audio_timestamp.done`` server event. - :ivar type: The type of the shell execution environment. Required. Default value is None. - :vartype type: str + :ivar type: Required. RESPONSE_AUDIO_TIMESTAMP_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_AUDIO_TIMESTAMP_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of the shell execution environment. Required. Default value is None.""" + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_AUDIO_TIMESTAMP_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - type: str, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, ) -> None: ... @overload @@ -16294,54 +27973,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE # type: ignore -class ToolboxShellContainerAutoEnvironment( - ToolboxShellEnvironment, discriminator="container_auto" +class VoiceAgentServerEventResponseVideoDelta( + RealtimeServerEvent, discriminator="response.video.delta" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """An automatically provisioned container environment for a shell tool stored in a toolbox. - - :ivar type: The type of the shell execution environment. Always ``container_auto``. Required. - Default value is "container_auto". - :vartype type: str - :ivar file_ids: An optional list of uploaded files to make available to your code. - :vartype file_ids: list[str] - :ivar memory_limit: Known values are: "1g", "4g", "16g", and "64g". - :vartype memory_limit: str or ~azure.ai.projects.models.ContainerMemoryLimit - :ivar skills: An optional list of skills referenced by id or inline data. - :vartype skills: list[~azure.ai.projects.models.ContainerSkill] - :ivar network_policy: The network access policy for the container. When omitted, the service - defaults to disabled outbound network access. - :vartype network_policy: ~azure.ai.projects.models.ToolboxShellNetworkPolicy - """ - - type: Literal["container_auto"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the shell execution environment. Always ``container_auto``. Required. Default value - is \"container_auto\".""" - file_ids: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """An optional list of uploaded files to make available to your code.""" - memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Known values are: \"1g\", \"4g\", \"16g\", and \"64g\".""" - skills: Optional[list["_models.ContainerSkill"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """An optional list of skills referenced by id or inline data.""" - network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The network access policy for the container. When omitted, the service defaults to disabled - outbound network access.""" + """The ``response.video.delta`` server event. + + :ivar type: Required. RESPONSE_VIDEO_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_VIDEO_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar codec: Required. + :vartype codec: str + :ivar delta: The base64-encoded video frame data. Required. + :vartype delta: str + """ + + type: Literal[RealtimeServerEventType.RESPONSE_VIDEO_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_VIDEO_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + codec: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The base64-encoded video frame data. Required.""" @overload def __init__( self, *, - file_ids: Optional[list[str]] = None, - memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = None, - skills: Optional[list["_models.ContainerSkill"]] = None, - network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = None, + event_id: str, + output_index: int, + codec: str, + delta: str, ) -> None: ... @overload @@ -16353,32 +28023,47 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "container_auto" # type: ignore - - -class ToolboxShellContainerReferenceEnvironment( - ToolboxShellEnvironment, discriminator="container_reference" -): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only - """An existing container environment for a shell tool stored in a toolbox. + self.type = RealtimeServerEventType.RESPONSE_VIDEO_DELTA # type: ignore - :ivar type: The type of the shell execution environment. Always ``container_reference``. - Required. Default value is "container_reference". - :vartype type: str - :ivar container_id: The ID of the referenced container. Required. - :vartype container_id: str - """ - type: Literal["container_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the shell execution environment. Always ``container_reference``. Required. Default - value is \"container_reference\".""" - container_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The ID of the referenced container. Required.""" +class VoiceAgentServerEventRtcCallError( + RealtimeServerEvent, discriminator="rtc.call.error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``rtc.call.error`` server event: a WebRTC signaling failure. + + :ivar type: The event type. Always ``rtc.call.error``. Required. RTC_CALL_ERROR. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_ERROR + :ivar event_id: An optional server-generated event identifier. + :vartype event_id: str + :ivar operation: The signaling operation that failed, when known. + :vartype operation: str + :ivar rtc_call_id: The identifier of the WebRTC call, when known. + :vartype rtc_call_id: str + :ivar error: The error detail. Required. + :vartype error: ~azure.ai.projects.models.VoiceAgentRtcCallErrorDetails + """ + + type: Literal[RealtimeServerEventType.RTC_CALL_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.error``. Required. RTC_CALL_ERROR.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional server-generated event identifier.""" + operation: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The signaling operation that failed, when known.""" + rtc_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the WebRTC call, when known.""" + error: "_models.VoiceAgentRtcCallErrorDetails" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The error detail. Required.""" @overload def __init__( self, *, - container_id: str, + error: "_models.VoiceAgentRtcCallErrorDetails", + event_id: Optional[str] = None, + operation: Optional[str] = None, + rtc_call_id: Optional[str] = None, ) -> None: ... @overload @@ -16390,28 +28075,40 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "container_reference" # type: ignore - + self.type = RealtimeServerEventType.RTC_CALL_ERROR # type: ignore -class ToolboxShellNetworkPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Network access policy for an automatically provisioned toolbox shell container. - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxShellNetworkPolicyDisabled +class VoiceAgentServerEventRtcCallSdpCreated( + RealtimeServerEvent, discriminator="rtc.call.sdp.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``rtc.call.sdp.created`` server event: the SDP answer that completes WebRTC negotiation. - :ivar type: The type of network access policy. Required. Default value is None. - :vartype type: str + :ivar type: The event type. Always ``rtc.call.sdp.created``. Required. RTC_CALL_SDP_CREATED. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_SDP_CREATED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar rtc_call_id: The identifier of the established WebRTC call. Required. + :vartype rtc_call_id: str + :ivar sdp_answer: The server's SDP answer for the WebRTC connection. Required. + :vartype sdp_answer: str """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of network access policy. Required. Default value is None.""" + type: Literal[RealtimeServerEventType.RTC_CALL_SDP_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.sdp.created``. Required. RTC_CALL_SDP_CREATED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + rtc_call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the established WebRTC call. Required.""" + sdp_answer: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server's SDP answer for the WebRTC connection. Required.""" @overload def __init__( self, *, - type: str, + event_id: str, + rtc_call_id: str, + sdp_answer: str, ) -> None: ... @overload @@ -16423,23 +28120,35 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RTC_CALL_SDP_CREATED # type: ignore -class ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator="disabled"): - """A network policy that disables outbound access from a toolbox shell container. +class VoiceAgentServerEventSessionAvatarConnecting( + RealtimeServerEvent, discriminator="session.avatar.connecting" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.connecting`` server event. - :ivar type: The type of network access policy. Always ``disabled``. Required. Default value is - "disabled". - :vartype type: str + :ivar type: Required. SESSION_AVATAR_CONNECTING. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_CONNECTING + :ivar event_id: Required. + :vartype event_id: str + :ivar server_sdp: The server's SDP answer for avatar media negotiation. Required. + :vartype server_sdp: str """ - type: Literal["disabled"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of network access policy. Always ``disabled``. Required. Default value is - \"disabled\".""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_CONNECTING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_CONNECTING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + server_sdp: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server's SDP answer for avatar media negotiation. Required.""" @overload def __init__( self, + *, + event_id: str, + server_sdp: str, ) -> None: ... @overload @@ -16451,28 +28160,34 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "disabled" # type: ignore - + self.type = RealtimeServerEventType.SESSION_AVATAR_CONNECTING # type: ignore -class ToolboxSkill(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A skill source included in a toolbox. - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxSkillReference +class VoiceAgentServerEventSessionAvatarSwitchToIdle( + RealtimeServerEvent, discriminator="session.avatar.switch_to_idle" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.switch_to_idle`` server event. - :ivar type: The type of skill source. Required. Default value is None. - :vartype type: str + :ivar type: Required. SESSION_AVATAR_SWITCH_TO_IDLE. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_SWITCH_TO_IDLE + :ivar event_id: Required. + :vartype event_id: str + :ivar turn_id: + :vartype turn_id: str """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of skill source. Required. Default value is None.""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_SWITCH_TO_IDLE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + turn_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - type: str, + event_id: str, + turn_id: Optional[str] = None, ) -> None: ... @overload @@ -16484,36 +28199,34 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE # type: ignore -class ToolboxSkillReference( - ToolboxSkill, discriminator="skill_reference" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A reference to an existing skill to include in a toolbox. +class VoiceAgentServerEventSessionAvatarSwitchToSpeaking( + RealtimeServerEvent, discriminator="session.avatar.switch_to_speaking" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.switch_to_speaking`` server event. - :ivar type: The type of skill source. Required. Default value is "skill_reference". - :vartype type: str - :ivar name: The name of the skill. Required. - :vartype name: str - :ivar version: The version of the skill. If not specified, the skill's default version is used. - When a version is specified, the reference is pinned to that immutable version. - :vartype version: str + :ivar type: Required. SESSION_AVATAR_SWITCH_TO_SPEAKING. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_SWITCH_TO_SPEAKING + :ivar event_id: Required. + :vartype event_id: str + :ivar turn_id: + :vartype turn_id: str """ - type: Literal["skill_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of skill source. Required. Default value is \"skill_reference\".""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the skill. Required.""" - version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version of the skill. If not specified, the skill's default version is used. When a version - is specified, the reference is pinned to that immutable version.""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_SWITCH_TO_SPEAKING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + turn_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - name: str, - version: Optional[str] = None, + event_id: str, + turn_id: Optional[str] = None, ) -> None: ... @overload @@ -16525,82 +28238,55 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "skill_reference" # type: ignore - + self.type = RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING # type: ignore -class ToolboxVersionObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A specific version of a toolbox. - - :ivar metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. - - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Required. - :vartype metadata: dict[str, str] - :ivar id: The unique identifier of the toolbox version. Required. - :vartype id: str - :ivar name: The name of the toolbox. Required. - :vartype name: str - :ivar version: The version identifier of the toolbox. Toolbox versions are immutable and every - update creates a new version. Required. - :vartype version: str - :ivar description: A human-readable description of the toolbox. - :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the toolbox version was created. Required. - :vartype created_at: ~datetime.datetime - :ivar tools: The list of tools contained in this toolbox version. Required. - :vartype tools: list[~azure.ai.projects.models.ToolboxTool] - :ivar skills: The list of skill sources included in this toolbox version. - :vartype skills: list[~azure.ai.projects.models.ToolboxSkill] - :ivar policies: Policy configuration for the toolbox version. - :vartype policies: ~azure.ai.projects.models.ToolboxPolicies - """ - metadata: dict[str, str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. - - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Required.""" - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the toolbox version. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the toolbox. Required.""" - version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier of the toolbox. Toolbox versions are immutable and every update creates - a new version. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the toolbox.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The Unix timestamp (seconds) when the toolbox version was created. Required.""" - tools: list["_models.ToolboxTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The list of tools contained in this toolbox version. Required.""" - skills: Optional[list["_models.ToolboxSkill"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The list of skill sources included in this toolbox version.""" - policies: Optional["_models.ToolboxPolicies"] = rest_field( +class VoiceAgentServerEventSessionSubagentAborted( + RealtimeServerEvent, discriminator="session.subagent.aborted" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.aborted`` server event. + + :ivar type: The event type. Always ``session.subagent.aborted``. Required. + SESSION_SUBAGENT_ABORTED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_ABORTED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str + :ivar reason: The reason the consultation was aborted. Required. Known values are: + "unknown_target", "timeout", "cancelled", "stopped_by_user", "superseded", and "failed". + :vartype reason: str or ~azure.ai.projects.models.VoiceAgentSubagentAbortReason + """ + + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_ABORTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.aborted``. Required. SESSION_SUBAGENT_ABORTED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" + reason: Union[str, "_models.VoiceAgentSubagentAbortReason"] = rest_field( visibility=["read", "create", "update", "delete", "query"] - ) - """Policy configuration for the toolbox version.""" - - @overload - def __init__( - self, - *, - metadata: dict[str, str], - id: str, # pylint: disable=redefined-builtin - name: str, - version: str, - created_at: datetime.datetime, - tools: list["_models.ToolboxTool"], - description: Optional[str] = None, - skills: Optional[list["_models.ToolboxSkill"]] = None, - policies: Optional["_models.ToolboxPolicies"] = None, + ) + """The reason the consultation was aborted. Required. Known values are: \"unknown_target\", + \"timeout\", \"cancelled\", \"stopped_by_user\", \"superseded\", and \"failed\".""" + + @overload + def __init__( + self, + *, + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, + reason: Union[str, "_models.VoiceAgentSubagentAbortReason"], ) -> None: ... @overload @@ -16612,58 +28298,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_SUBAGENT_ABORTED # type: ignore -class ToolChoiceAllowed( - ToolChoiceParam, discriminator="allowed_tools" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Allowed tools. - - :ivar type: Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS. - :vartype type: str or ~azure.ai.projects.models.ALLOWED_TOOLS - :ivar mode: Constrains the tools available to the model to a pre-defined set. ``auto`` allows - the model to pick from among the allowed tools and generate a message. ``required`` requires - the model to call one or more of the allowed tools. Required. Is either a Literal["auto"] type - or a Literal["required"] type. - :vartype mode: str or str - :ivar tools: Required. A list of tool definitions that the model should be allowed to call. For - the Responses API, the list of tool definitions might look like: - - .. code-block:: json +class VoiceAgentServerEventSessionSubagentCompleted( + RealtimeServerEvent, discriminator="session.subagent.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.completed`` server event. - [ - { "type": "function", "name": "get_weather" }, - { "type": "mcp", "server_label": "deepwiki" }, - { "type": "image_generation" } - ] - :vartype tools: list[dict[str, any]] + :ivar type: The event type. Always ``session.subagent.completed``. Required. + SESSION_SUBAGENT_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_COMPLETED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str """ - type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS.""" - mode: Literal["auto", "required"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Constrains the tools available to the model to a pre-defined set. ``auto`` allows the model to - pick from among the allowed tools and generate a message. ``required`` requires the model to - call one or more of the allowed tools. Required. Is either a Literal[\"auto\"] type or a - Literal[\"required\"] type.""" - tools: list[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required. A list of tool definitions that the model should be allowed to call. For the - Responses API, the list of tool definitions might look like: - - .. code-block:: json - - [ - { \"type\": \"function\", \"name\": \"get_weather\" }, - { \"type\": \"mcp\", \"server_label\": \"deepwiki\" }, - { \"type\": \"image_generation\" } - ]""" + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.completed``. Required. SESSION_SUBAGENT_COMPLETED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" @overload def __init__( self, *, - mode: Literal["auto", "required"], - tools: list[dict[str, Any]], + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, ) -> None: ... @overload @@ -16675,23 +28349,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.ALLOWED_TOOLS # type: ignore + self.type = RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED # type: ignore -class ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator="code_interpreter"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventSessionSubagentStarted( + RealtimeServerEvent, discriminator="session.subagent.started" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.started`` server event. - :ivar type: Required. CODE_INTERPRETER. - :vartype type: str or ~azure.ai.projects.models.CODE_INTERPRETER + :ivar type: The event type. Always ``session.subagent.started``. Required. + SESSION_SUBAGENT_STARTED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_STARTED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str """ - type: Literal[ToolChoiceParamType.CODE_INTERPRETER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. CODE_INTERPRETER.""" + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_STARTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.started``. Required. SESSION_SUBAGENT_STARTED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" @overload def __init__( self, + *, + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, ) -> None: ... @overload @@ -16703,23 +28400,37 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.CODE_INTERPRETER # type: ignore + self.type = RealtimeServerEventType.SESSION_SUBAGENT_STARTED # type: ignore -class ToolChoiceComputer(ToolChoiceParam, discriminator="computer"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventWarning( + RealtimeServerEvent, discriminator="warning" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``warning`` server event. - :ivar type: Required. COMPUTER. - :vartype type: str or ~azure.ai.projects.models.COMPUTER + :ivar type: Required. WARNING. + :vartype type: str or ~azure.ai.projects.models.WARNING + :ivar event_id: Required. + :vartype event_id: str + :ivar warning: Required. + :vartype warning: ~azure.ai.projects.models.VoiceAgentServerEventWarningDetails """ - type: Literal[ToolChoiceParamType.COMPUTER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER.""" + type: Literal[RealtimeServerEventType.WARNING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WARNING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + warning: "_models.VoiceAgentServerEventWarningDetails" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" @overload def __init__( self, + *, + event_id: str, + warning: "_models.VoiceAgentServerEventWarningDetails", ) -> None: ... @overload @@ -16731,23 +28442,32 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER # type: ignore + self.type = RealtimeServerEventType.WARNING # type: ignore -class ToolChoiceComputerUse(ToolChoiceParam, discriminator="computer_use"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventWarningDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Details of a non-fatal warning. - :ivar type: Required. COMPUTER_USE. - :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE + :ivar message: Required. + :vartype message: str + :ivar code: + :vartype code: str + :ivar param: + :vartype param: str """ - type: Literal[ToolChoiceParamType.COMPUTER_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER_USE.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, + *, + message: str, + code: Optional[str] = None, + param: Optional[str] = None, ) -> None: ... @overload @@ -16759,23 +28479,69 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER_USE # type: ignore -class ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator="computer_use_preview"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="server_vad" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Server-side voice activity detection. - :ivar type: Required. COMPUTER_USE_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE_PREVIEW + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar threshold: + :vartype threshold: float + :ivar prefix_padding_ms: + :vartype prefix_padding_ms: int + :ivar silence_duration_ms: + :vartype silence_duration_ms: int + :ivar create_response: + :vartype create_response: bool + :ivar interrupt_response: + :vartype interrupt_response: bool + :ivar idle_timeout_ms: + :vartype idle_timeout_ms: int + :ivar type: Required. Server-side voice activity detection. + :vartype type: str or ~azure.ai.projects.models.SERVER_VAD + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection """ - type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER_USE_PREVIEW.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + prefix_padding_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + silence_duration_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + idle_timeout_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + type: Literal[VoiceAgentTurnDetectionType.SERVER_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Server-side voice activity detection.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" @overload def __init__( self, + *, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[int] = None, + silence_duration_ms: Optional[int] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + idle_timeout_ms: Optional[int] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, ) -> None: ... @overload @@ -16787,30 +28553,55 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER_USE_PREVIEW # type: ignore + self.type = VoiceAgentTurnDetectionType.SERVER_VAD # type: ignore -class ToolChoiceCustom( - ToolChoiceParam, discriminator="custom" +class VoiceAgentSessionAvatarConfig( + VoiceAgentAvatarConfig ): # pylint: disable=docstring-keyword-should-match-keyword-only - """Custom tool. - - :ivar type: For custom tool calling, the type is always ``custom``. Required. CUSTOM. - :vartype type: str or ~azure.ai.projects.models.CUSTOM - :ivar name: The name of the custom tool to call. Required. - :vartype name: str + """Avatar settings accepted by the stable voice-agent WebSocket contract. + + :ivar type: The avatar type. Required. Known values are: "video_avatar" and "photo_avatar". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentAvatarType + :ivar character: The avatar character identifier, e.g. 'lisa'. Required. + :vartype character: str + :ivar style: The avatar style, e.g. 'casual-sitting'. + :vartype style: str + :ivar customized: Whether the avatar is a customer-customized avatar. Defaults to false. + :vartype customized: bool + :ivar output_protocol: The transport used to deliver the avatar video stream. Known values are: + "webrtc" and "websocket". + :vartype output_protocol: str or ~azure.ai.projects.models.VoiceAgentAvatarOutputProtocol + :ivar model: The avatar model identifier. + :vartype model: str + :ivar video: Avatar video encoder and presentation settings. + :vartype video: ~azure.ai.projects.models.VoiceAgentAvatarVideoParams + :ivar scene: Avatar placement and motion settings. + :vartype scene: ~azure.ai.projects.models.VoiceAgentAvatarScene + :ivar output_audit_audio: Whether audit audio is emitted with avatar output. Defaults to false. + :vartype output_audit_audio: bool + :ivar ice_servers: + :vartype ice_servers: list[~azure.ai.projects.models.VoiceAgentAvatarIceServer] """ - type: Literal[ToolChoiceParamType.CUSTOM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For custom tool calling, the type is always ``custom``. Required. CUSTOM.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the custom tool to call. Required.""" + ice_servers: Optional[list["_models.VoiceAgentAvatarIceServer"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) @overload def __init__( self, *, - name: str, + type: Union[str, "_models.VoiceAgentAvatarType"], + character: str, + style: Optional[str] = None, + customized: Optional[bool] = None, + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = None, + model: Optional[str] = None, + video: Optional["_models.VoiceAgentAvatarVideoParams"] = None, + scene: Optional["_models.VoiceAgentAvatarScene"] = None, + output_audit_audio: Optional[bool] = None, + ice_servers: Optional[list["_models.VoiceAgentAvatarIceServer"]] = None, ) -> None: ... @overload @@ -16822,23 +28613,146 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.CUSTOM # type: ignore -class ToolChoiceFileSearch(ToolChoiceParam, discriminator="file_search"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentSessionResponseConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The effective stable realtime session settings returned by the voice-agent service. - :ivar type: Required. FILE_SEARCH. - :vartype type: str or ~azure.ai.projects.models.FILE_SEARCH + :ivar type: The session type. Always ``realtime``. Required. Default value is "realtime". + :vartype type: str + :ivar instructions: Instructions applied throughout the session. + :vartype instructions: str + :ivar temperature: The sampling temperature for compatible cascaded pipelines. + :vartype temperature: float + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar output_modalities: The output modalities enabled for the session. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: The input- and output-audio settings for the session. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar avatar: The avatar settings for the session. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentSessionAvatarConfig + :ivar animation: Animation settings for the session. + :vartype animation: ~azure.ai.projects.models.VoiceAgentAnimationConfig + :ivar tools: Tools available to the session. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: Tool-selection behavior for the session. Is one of the following types: + Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar reasoning: Reasoning settings for compatible realtime models. + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar metadata: Up to 16 string key-value pairs attached to the session. + :vartype metadata: dict[str, str] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar greeting: A proactive assistant greeting started after session configuration. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig + :ivar object: The object type. Always ``realtime.session``. Required. Default value is + "realtime.session". + :vartype object: str + :ivar id: The session identifier. Required. + :vartype id: str + :ivar model: The selected model. Required. + :vartype model: str + :ivar expires_at: The session expiration time as a Unix timestamp in seconds. + :vartype expires_at: ~datetime.datetime """ - type: Literal[ToolChoiceParamType.FILE_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. FILE_SEARCH.""" + type: Literal["realtime"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session type. Always ``realtime``. Required. Default value is \"realtime\".""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions applied throughout the session.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature for compatible cascaded pipelines.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities enabled for the session.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The input- and output-audio settings for the session.""" + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The avatar settings for the session.""" + animation: Optional["_models.VoiceAgentAnimationConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Animation settings for the session.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the session.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tool-selection behavior for the session. Is one of the following types: Literal[\"none\"], + Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Reasoning settings for compatible realtime models.""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Up to 16 string key-value pairs attached to the session.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A proactive assistant greeting started after session configuration.""" + object: Literal["realtime.session"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``realtime.session``. Required. Default value is \"realtime.session\".""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session identifier. Required.""" + model: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The selected model. Required.""" + expires_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The session expiration time as a Unix timestamp in seconds.""" @overload def __init__( self, + *, + id: str, # pylint: disable=redefined-builtin + model: str, + instructions: Optional[str] = None, + temperature: Optional[float] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = None, + animation: Optional["_models.VoiceAgentAnimationConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + parallel_tool_calls: Optional[bool] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + metadata: Optional[dict[str, str]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, + expires_at: Optional[datetime.datetime] = None, ) -> None: ... @overload @@ -16850,30 +28764,126 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.FILE_SEARCH # type: ignore + self.type: Literal["realtime"] = "realtime" + self.object: Literal["realtime.session"] = "realtime.session" -class ToolChoiceFunction( - ToolChoiceParam, discriminator="function" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Function tool. +class VoiceAgentSessionUpdateConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The stable realtime session settings accepted in a ``session.update`` client event. - :ivar type: For function calling, the type is always ``function``. Required. FUNCTION. - :vartype type: str or ~azure.ai.projects.models.FUNCTION - :ivar name: The name of the function to call. Required. - :vartype name: str + :ivar type: The session type. Always ``realtime``. Required. Default value is "realtime". + :vartype type: str + :ivar instructions: Instructions applied throughout the session. + :vartype instructions: str + :ivar temperature: The sampling temperature for compatible cascaded pipelines. + :vartype temperature: float + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar output_modalities: The output modalities enabled for the session. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: The input- and output-audio settings for the session. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar avatar: The avatar settings for the session. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentSessionAvatarConfig + :ivar animation: Animation settings for the session. + :vartype animation: ~azure.ai.projects.models.VoiceAgentAnimationConfig + :ivar tools: Tools available to the session. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: Tool-selection behavior for the session. Is one of the following types: + Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar reasoning: Reasoning settings for compatible realtime models. + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar metadata: Up to 16 string key-value pairs attached to the session. + :vartype metadata: dict[str, str] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar greeting: A proactive assistant greeting started after session configuration. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig """ - type: Literal[ToolChoiceParamType.FUNCTION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For function calling, the type is always ``function``. Required. FUNCTION.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the function to call. Required.""" + type: Literal["realtime"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session type. Always ``realtime``. Required. Default value is \"realtime\".""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions applied throughout the session.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature for compatible cascaded pipelines.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities enabled for the session.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The input- and output-audio settings for the session.""" + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The avatar settings for the session.""" + animation: Optional["_models.VoiceAgentAnimationConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Animation settings for the session.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the session.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tool-selection behavior for the session. Is one of the following types: Literal[\"none\"], + Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Reasoning settings for compatible realtime models.""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Up to 16 string key-value pairs attached to the session.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A proactive assistant greeting started after session configuration.""" @overload def __init__( self, *, - name: str, + instructions: Optional[str] = None, + temperature: Optional[float] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = None, + animation: Optional["_models.VoiceAgentAnimationConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + parallel_tool_calls: Optional[bool] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + metadata: Optional[dict[str, str]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, ) -> None: ... @overload @@ -16885,23 +28895,36 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.FUNCTION # type: ignore + self.type: Literal["realtime"] = "realtime" -class ToolChoiceImageGeneration(ToolChoiceParam, discriminator="image_generation"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentStaticInterimResponseConfig( + VoiceAgentInterimResponseConfig, discriminator="static_interim_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A static interim response selected from configured text. - :ivar type: Required. IMAGE_GENERATION. - :vartype type: str or ~azure.ai.projects.models.IMAGE_GENERATION + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta + :ivar type: Required. Default value is "static_interim_response". + :vartype type: str + :ivar texts: Candidate text values for the interim response. + :vartype texts: list[str] """ - type: Literal[ToolChoiceParamType.IMAGE_GENERATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. IMAGE_GENERATION.""" + type: Literal["static_interim_response"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"static_interim_response\".""" + texts: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Candidate text values for the interim response.""" @overload def __init__( self, + *, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, + texts: Optional[list[str]] = None, ) -> None: ... @overload @@ -16913,34 +28936,56 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.IMAGE_GENERATION # type: ignore + self.type = "static_interim_response" # type: ignore -class ToolChoiceMCP( - ToolChoiceParam, discriminator="mcp" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """MCP tool. +class VoiceAgentSubagent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A sibling Foundry text agent that a voice agent may consult as a background specialist. - :ivar type: For MCP tools, the type is always ``mcp``. Required. MCP. - :vartype type: str or ~azure.ai.projects.models.MCP - :ivar server_label: The label of the MCP server to use. Required. - :vartype server_label: str - :ivar name: - :vartype name: str + :ivar agent_name: The name of the subagent. The subagent must be in the same project as the + voice agent. Required. + :vartype agent_name: str + :ivar agent_version: The version of the subagent. When omitted, the active version is used. + :vartype agent_version: str + :ivar agent_capabilities: A description of the subagent's capabilities, used by the voice agent + to decide whether to forward a query. Required. + :vartype agent_capabilities: str + :ivar response_policy: Policy for acknowledging forwarded requests and filling gaps while + waiting for this subagent's response. + :vartype response_policy: ~azure.ai.projects.models.VoiceAgentSubagentResponsePolicy + :ivar invoke_timeout_seconds: The wall-clock timeout, in seconds, for each invocation of this + subagent. When omitted, the service timeout is used. + :vartype invoke_timeout_seconds: ~datetime.timedelta """ - type: Literal[ToolChoiceParamType.MCP] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For MCP tools, the type is always ``mcp``. Required. MCP.""" - server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The label of the MCP server to use. Required.""" - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + agent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the subagent. The subagent must be in the same project as the voice agent. + Required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version of the subagent. When omitted, the active version is used.""" + agent_capabilities: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of the subagent's capabilities, used by the voice agent to decide whether to + forward a query. Required.""" + response_policy: Optional["_models.VoiceAgentSubagentResponsePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Policy for acknowledging forwarded requests and filling gaps while waiting for this subagent's + response.""" + invoke_timeout_seconds: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The wall-clock timeout, in seconds, for each invocation of this subagent. When omitted, the + service timeout is used.""" @overload def __init__( self, *, - server_label: str, - name: Optional[str] = None, + agent_name: str, + agent_capabilities: str, + agent_version: Optional[str] = None, + response_policy: Optional["_models.VoiceAgentSubagentResponsePolicy"] = None, + invoke_timeout_seconds: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -16952,23 +28997,27 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.MCP # type: ignore -class ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator="web_search_preview"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentSubagentConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Configuration for sibling Foundry text agents that a voice agent may consult. - :ivar type: Required. WEB_SEARCH_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW + :ivar subagents: The sibling Foundry text agents, in the same project, that this voice agent + may consult. Required. + :vartype subagents: list[~azure.ai.projects.models.VoiceAgentSubagent] """ - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. WEB_SEARCH_PREVIEW.""" + subagents: list["_models.VoiceAgentSubagent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sibling Foundry text agents, in the same project, that this voice agent may consult. + Required.""" @overload def __init__( self, + *, + subagents: list["_models.VoiceAgentSubagent"], ) -> None: ... @overload @@ -16980,23 +29029,65 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW # type: ignore -class ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator="web_search_preview_2025_03_11"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentSubagentResponsePolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Policy for delivering responses while a voice agent waits for a subagent. - :ivar type: Required. WEB_SEARCH_PREVIEW_2025_03_11. - :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW_2025_03_11 + :ivar immediate_ack: Whether the voice agent provides an immediate acknowledgement before + forwarding a request to a subagent. + :vartype immediate_ack: bool + :ivar gap_filling_interval: The number of seconds without subagent content or user input before + the voice agent provides a gap-filling response. + :vartype gap_filling_interval: ~datetime.timedelta + :ivar ack_instructions: Instructions used to generate the immediate acknowledgement. + :vartype ack_instructions: str + :ivar gap_filling_instructions: Instructions used to generate gap-filling speech while waiting + for progress. + :vartype gap_filling_instructions: str + :ivar enable_delta_progress: Whether progress updates are emitted incrementally instead of only + when the subagent invocation completes. Defaults to ``false``. + :vartype enable_delta_progress: bool + :ivar progress_instructions: Instructions used to summarize streamed subagent progress for + speech. + :vartype progress_instructions: str + :ivar progress_update_interval: The minimum number of seconds between spoken progress updates. + :vartype progress_update_interval: ~datetime.timedelta """ - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. WEB_SEARCH_PREVIEW_2025_03_11.""" + immediate_ack: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the voice agent provides an immediate acknowledgement before forwarding a request to a + subagent.""" + gap_filling_interval: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The number of seconds without subagent content or user input before the voice agent provides a + gap-filling response.""" + ack_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to generate the immediate acknowledgement.""" + gap_filling_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to generate gap-filling speech while waiting for progress.""" + enable_delta_progress: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether progress updates are emitted incrementally instead of only when the subagent invocation + completes. Defaults to ``false``.""" + progress_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to summarize streamed subagent progress for speech.""" + progress_update_interval: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The minimum number of seconds between spoken progress updates.""" @overload def __init__( self, + *, + immediate_ack: Optional[bool] = None, + gap_filling_interval: Optional[datetime.timedelta] = None, + ack_instructions: Optional[str] = None, + gap_filling_instructions: Optional[str] = None, + enable_delta_progress: Optional[bool] = None, + progress_instructions: Optional[str] = None, + progress_update_interval: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -17008,35 +29099,39 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11 # type: ignore -class ToolConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Per-tool configuration that controls tool visibility and search behavior. +class VoiceAgentSystemTool( + VoiceAgentTool, discriminator="system" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A service-managed control that acts on the active voice session without customer code or + external authentication. - :ivar pin: When true, the tool is always included in agent context and visible in - ``tools/list``. When false (default), the tool is hidden from ``tools/list`` and only - discoverable via ``tool_search``. - :vartype pin: bool - :ivar additional_search_text: Additional text indexed for tool_search. Supplements the native - tool description to improve discoverability. Does not alter ``tools/list`` output. - :vartype additional_search_text: str + :ivar type: The type of the tool. Always ``system``. Required. Default value is "system". + :vartype type: str + :ivar name: The service-managed control action. Known values are stable; additional values may + be added over time. Required. "end_conversation" + :vartype name: str or ~azure.ai.projects.models.VoiceAgentSystemToolName + :ivar description: An optional description of the system tool. + :vartype description: str """ - pin: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """When true, the tool is always included in agent context and visible in ``tools/list``. When - false (default), the tool is hidden from ``tools/list`` and only discoverable via - ``tool_search``.""" - additional_search_text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional text indexed for tool_search. Supplements the native tool description to improve - discoverability. Does not alter ``tools/list`` output.""" + type: Literal["system"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``system``. Required. Default value is \"system\".""" + name: Union[str, "_models.VoiceAgentSystemToolName"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The service-managed control action. Known values are stable; additional values may be added + over time. Required. \"end_conversation\"""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional description of the system tool.""" @overload def __init__( self, *, - pin: Optional[bool] = None, - additional_search_text: Optional[str] = None, + name: Union[str, "_models.VoiceAgentSystemToolName"], + description: Optional[str] = None, ) -> None: ... @overload @@ -17048,28 +29143,31 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "system" # type: ignore -class ToolDescription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Description of a tool that can be used by an agent. +class VoiceAgentTemplateGreetingConfig( + VoiceAgentGreetingConfig, discriminator="template" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A deterministic greeting rendered with the voice agent's structured inputs and synthesized + without model-authored generation. - :ivar name: The name of the tool. - :vartype name: str - :ivar description: A brief description of the tool's purpose. - :vartype description: str + :ivar type: Required. Default value is "template". + :vartype type: str + :ivar text: The Handlebars text template spoken at session start. Required. + :vartype text: str """ - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the tool.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A brief description of the tool's purpose.""" + type: Literal["template"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"template\".""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Handlebars text template spoken at session start. Required.""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, + text: str, ) -> None: ... @overload @@ -17081,24 +29179,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "template" # type: ignore -class ToolProjectConnection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A project connection resource. - - :ivar project_connection_id: A project connection in a ToolProjectConnectionList attached to - this tool. Required. - :vartype project_connection_id: str - """ +class VoiceAgentToolboxTool( + VoiceAgentTool, discriminator="toolbox" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reference to a Foundry toolbox, which is a versioned bundle of tools executed through its MCP + endpoint. - project_connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A project connection in a ToolProjectConnectionList attached to this tool. Required.""" + :ivar type: The type of the tool. Always ``toolbox``. Required. Default value is "toolbox". + :vartype type: str + :ivar toolbox_name: The name of the toolbox to attach. Required. + :vartype toolbox_name: str + :ivar toolbox_version: The immutable version of the toolbox to attach. Required. + :vartype toolbox_version: str + :ivar response_scheduling: When the toolbox invocation creates a follow-up response. Defaults + to ``when_idle``. Known values are: "silent", "when_idle", "interrupt", and "skip_if_busy". + :vartype response_scheduling: str or ~azure.ai.projects.models.VoiceAgentToolResponseScheduling + """ + + type: Literal["toolbox"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox``. Required. Default value is \"toolbox\".""" + toolbox_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox to attach. Required.""" + toolbox_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The immutable version of the toolbox to attach. Required.""" + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the toolbox invocation creates a follow-up response. Defaults to ``when_idle``. Known + values are: \"silent\", \"when_idle\", \"interrupt\", and \"skip_if_busy\".""" @overload def __init__( self, *, - project_connection_id: str, + toolbox_name: str, + toolbox_version: str, + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = None, ) -> None: ... @overload @@ -17110,35 +29229,56 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "toolbox" # type: ignore -class ToolSearchToolboxTool( - ToolboxTool, discriminator="toolbox_search" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox search tool stored in a toolbox. +class VoiceAgentTranscriptionPhrase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A transcribed phrase with timing information. - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH. - :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH + :ivar offset_milliseconds: The phrase offset from the beginning of the audio, in milliseconds. + Required. + :vartype offset_milliseconds: ~datetime.timedelta + :ivar duration_milliseconds: The phrase duration in milliseconds. Required. + :vartype duration_milliseconds: ~datetime.timedelta + :ivar text: The transcribed phrase text. Required. + :vartype text: str + :ivar words: Word-level timing details, when available. + :vartype words: list[~azure.ai.projects.models.VoiceAgentTranscriptionWord] + :ivar locale: The detected locale. + :vartype locale: str + :ivar confidence: The transcription confidence score. + :vartype confidence: float """ - type: Literal[ToolboxToolType.TOOLBOX_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH.""" + offset_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The phrase offset from the beginning of the audio, in milliseconds. Required.""" + duration_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The phrase duration in milliseconds. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed phrase text. Required.""" + words: Optional[list["_models.VoiceAgentTranscriptionWord"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Word-level timing details, when available.""" + locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The detected locale.""" + confidence: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcription confidence score.""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + offset_milliseconds: datetime.timedelta, + duration_milliseconds: datetime.timedelta, + text: str, + words: Optional[list["_models.VoiceAgentTranscriptionWord"]] = None, + locale: Optional[str] = None, + confidence: Optional[float] = None, ) -> None: ... @overload @@ -17150,44 +29290,38 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.TOOLBOX_SEARCH # type: ignore -class ToolSearchToolParam( - Tool, discriminator="tool_search" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Tool search tool. +class VoiceAgentTranscriptionWord(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A time-stamped word in an input-audio transcription. - :ivar type: The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH. - :vartype type: str or ~azure.ai.projects.models.TOOL_SEARCH - :ivar execution: Whether tool search is executed by the server or by the client. Known values - are: "server" and "client". - :vartype execution: str or ~azure.ai.projects.models.ToolSearchExecutionType - :ivar description: - :vartype description: str - :ivar parameters: - :vartype parameters: ~azure.ai.projects.models.EmptyModelParam + :ivar text: The transcribed word text. Required. + :vartype text: str + :ivar offset_milliseconds: The word offset from the beginning of the audio, in milliseconds. + Required. + :vartype offset_milliseconds: ~datetime.timedelta + :ivar duration_milliseconds: The word duration in milliseconds. Required. + :vartype duration_milliseconds: ~datetime.timedelta """ - type: Literal[ToolType.TOOL_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH.""" - execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed word text. Required.""" + offset_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" ) - """Whether tool search is executed by the server or by the client. Known values are: \"server\" - and \"client\".""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - parameters: Optional["_models.EmptyModelParam"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] + """The word offset from the beginning of the audio, in milliseconds. Required.""" + duration_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" ) + """The word duration in milliseconds. Required.""" @overload def __init__( self, *, - execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = None, - description: Optional[str] = None, - parameters: Optional["_models.EmptyModelParam"] = None, + text: str, + offset_milliseconds: datetime.timedelta, + duration_milliseconds: datetime.timedelta, ) -> None: ... @overload @@ -17199,37 +29333,83 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolType.TOOL_SEARCH # type: ignore -class ToolUseFineTuningDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="tool_use" -): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only - """The options for a data generation job with ToolUse type. Used only for fine-tuning scenarios. +class VoiceConversation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A persisted voice conversation. The Foundry envelope that owns a voice agent's stored + transcript, responses, per-turn metrics, and audio. It is the parent, retention, and delete + boundary: deleting it cascades to its responses, items, metrics, and audio. When finalization + fails, any partial persisted responses, items, and item audio remain readable. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is ToolUse for this model. Required. Tool - calling conversation between user and agent. - :vartype type: str or ~azure.ai.projects.models.TOOL_USE + :ivar id: The unique id of the conversation. Required. + :vartype id: str + :ivar object: The object type. Always ``voice.conversation``. Required. Default value is + "voice.conversation". + :vartype object: str + :ivar status: The lifecycle status of the conversation. Required. Known values are: + "in_progress", "completed", and "failed". + :vartype status: str or ~azure.ai.projects.models.VoiceConversationStatus + :ivar created_at: The Unix timestamp (in seconds) for when the conversation was created. + Required. + :vartype created_at: ~datetime.datetime + :ivar completed_at: The Unix timestamp (in seconds) for when session and persistence + finalization reached the terminal ``completed`` or ``failed`` status. Absent while ``status`` + is ``in_progress``. + :vartype completed_at: ~datetime.datetime + :ivar metadata: A set of key-value pairs attached to the conversation. + :vartype metadata: dict[str, str] + :ivar usage: Final aggregate token usage across all responses in this conversation. Absent + while ``status`` is ``in_progress`` and populated after successful ``completed`` finalization; + it may be absent when ``status`` is ``failed``, and values are not guaranteed to be reported + incrementally. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar last_error: The terminal error that prevented persistence finalization. Present only when + ``status`` is ``failed``. + :vartype last_error: ~azure.ai.projects.models.ApiError """ - type: Literal[DataGenerationJobType.TOOL_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is ToolUse for this model. Required. Tool calling - conversation between user and agent.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique id of the conversation. Required.""" + object: Literal["voice.conversation"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``voice.conversation``. Required. Default value is + \"voice.conversation\".""" + status: Union[str, "_models.VoiceConversationStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the conversation. Required. Known values are: \"in_progress\", + \"completed\", and \"failed\".""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the conversation was created. Required.""" + completed_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when session and persistence finalization reached the + terminal ``completed`` or ``failed`` status. Absent while ``status`` is ``in_progress``.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A set of key-value pairs attached to the conversation.""" + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Final aggregate token usage across all responses in this conversation. Absent while ``status`` + is ``in_progress`` and populated after successful ``completed`` finalization; it may be absent + when ``status`` is ``failed``, and values are not guaranteed to be reported incrementally.""" + last_error: Optional["_models.ApiError"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The terminal error that prevented persistence finalization. Present only when ``status`` is + ``failed``.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, + id: str, # pylint: disable=redefined-builtin + status: Union[str, "_models.VoiceConversationStatus"], + created_at: datetime.datetime, + completed_at: Optional[datetime.datetime] = None, + metadata: Optional[dict[str, str]] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + last_error: Optional["_models.ApiError"] = None, ) -> None: ... @overload @@ -17241,44 +29421,28 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.TOOL_USE # type: ignore + self.object: Literal["voice.conversation"] = "voice.conversation" -class TracesDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="traces" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a data generation job with Traces type. +class VoiceConversationEngine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An engine that owns conversation handling for a voice agent. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is Traces for this model. Required. Single turn - query and response from agent traces. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar redact_private_content: Whether to redact private content from traces. When omitted or - set to true, private content is redacted. Set to false to opt out of redaction. - :vartype redact_private_content: bool + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceHostedAgentConversationEngine + + :ivar type: The conversation engine type. Required. Default value is None. + :vartype type: str """ - type: Literal[DataGenerationJobType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is Traces for this model. Required. Single turn query and - response from agent traces.""" - redact_private_content: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether to redact private content from traces. When omitted or set to true, private content is - redacted. Set to false to opt out of redaction.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The conversation engine type. Required. Default value is None.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, - redact_private_content: Optional[bool] = None, + type: str, ) -> None: ... @overload @@ -17290,68 +29454,87 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.TRACES # type: ignore -class TracesDataGenerationJobSource( - DataGenerationJobSource, discriminator="traces" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Traces source for data generation jobs — conversation traces from Application Insights. +class VoiceGeneratedItemAudioResponse(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for a conversation item's generated audio. For bring-your-own-storage (BYOS), the + response includes ``blob_uri``, a direct customer-storage URI without a SAS token, that the + customer accesses with their own credentials. For Foundry-managed storage, ``blob_uri`` is + absent and the bytes are streamed through the item's ``/audio/generated/content`` route. - :ivar description: Optional description of what this source represents — helps the pipeline - interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core - capabilities'). - :vartype description: str - :ivar type: The source type for this source, which is Traces. Required. Traces source — - conversation traces from Application Insights. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_id: str - :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_name: str - :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent - are included within the time window. - :vartype agent_version: str - :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. - Required. - :vartype start_time: ~datetime.datetime - :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. - :vartype end_time: ~datetime.datetime + :ivar conversation_id: The id of the conversation the item belongs to. Required. + :vartype conversation_id: str + :ivar item_id: The id of the item this audio belongs to. Required. + :vartype item_id: str + :ivar role: The role the audio belongs to. Known values are: "user" and "agent". + :vartype role: str or ~azure.ai.projects.models.VoiceAudioRole + :ivar format: The container format of the audio. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar codec: The audio codec. Known values are: "pcm16", "pcmu", and "pcma". + :vartype codec: str or ~azure.ai.projects.models.VoiceAudioCodec + :ivar sample_rate: The sample rate in Hz. + :vartype sample_rate: int + :ivar channels: The number of audio channels. + :vartype channels: int + :ivar start_offset_ms: The offset from the session start at which this segment begins. + :vartype start_offset_ms: ~datetime.timedelta + :ivar duration_ms: The duration of the audio segment. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the generated + audio in the customer's own storage, without a SAS token. The customer downloads it using their + own storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via + the item's ``/audio/generated/content`` route instead. + :vartype blob_uri: str """ - type: Literal[DataGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The source type for this source, which is Traces. Required. Traces source — conversation traces - from Application Insights.""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at - least one is required.""" - agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least - one is required.""" - agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version. If not specified, traces for ALL versions of the agent are included within - the time window.""" - start_time: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation the item belongs to. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the item this audio belongs to. Required.""" + role: Optional[Union[str, "_models.VoiceAudioRole"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" - end_time: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + """The role the audio belongs to. Known values are: \"user\" and \"agent\".""" + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + """The container format of the audio. \"wav\"""" + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio codec. Known values are: \"pcm16\", \"pcmu\", and \"pcma\".""" + sample_rate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate in Hz.""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels.""" + start_offset_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The offset from the session start at which this segment begins.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The duration of the audio segment.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the generated audio in the + customer's own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the item's + ``/audio/generated/content`` route instead.""" @overload def __init__( self, *, - start_time: datetime.datetime, - description: Optional[str] = None, - agent_id: Optional[str] = None, - agent_name: Optional[str] = None, - agent_version: Optional[str] = None, - end_time: Optional[datetime.datetime] = None, + conversation_id: str, + item_id: str, + role: Optional[Union[str, "_models.VoiceAudioRole"]] = None, + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = None, + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = None, + sample_rate: Optional[int] = None, + channels: Optional[int] = None, + start_offset_ms: Optional[datetime.timedelta] = None, + duration_ms: Optional[datetime.timedelta] = None, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17363,71 +29546,43 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobSourceType.TRACES # type: ignore -class TracesEvaluatorGenerationJobSource( - EvaluatorGenerationJobSource, discriminator="traces" +class VoiceHostedAgentConversationEngine( + VoiceConversationEngine, discriminator="hosted_agent" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """Traces source for evaluator generation jobs — conversation traces from Application Insights. + """A closed reference to the hosted text agent that owns conversation handling for a voice agent. + The hosted agent is resolved within the same project and must support the ``invocations_ws`` + protocol, Voice Live compatibility, and Bridge Protocol 1.0. - :ivar description: Optional description of what this source represents — helps the pipeline - interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core - capabilities'). - :vartype description: str - :ivar type: The source type for this source, which is Traces. Required. Traces source — - conversation traces from Application Insights. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_id: str - :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_name: str - :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent - are included within the time window. - :vartype agent_version: str - :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + :ivar type: Selects a hosted Foundry agent as the conversation engine. Required. Default value + is "hosted_agent". + :vartype type: str + :ivar name: The non-empty DNS-like name of the target hosted text agent in the same project. Required. - :vartype start_time: ~datetime.datetime - :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. - :vartype end_time: ~datetime.datetime + :vartype name: str + :ivar version: The target agent version. Omit this property to select the latest version when + the voice session starts. When supplied, use a positive integer or + ``draft-{positive-unix-timestamp}`` whose numeric component fits in a signed 64-bit integer. + :vartype version: str """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Optional description of what this source represents — helps the pipeline interpret its content - (e.g., 'Company refund policy document' or 'Describes the agent's core capabilities').""" - type: Literal[EvaluatorGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The source type for this source, which is Traces. Required. Traces source — conversation traces - from Application Insights.""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at - least one is required.""" - agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least - one is required.""" - agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version. If not specified, traces for ALL versions of the agent are included within - the time window.""" - start_time: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" - end_time: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + type: Literal["hosted_agent"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Selects a hosted Foundry agent as the conversation engine. Required. Default value is + \"hosted_agent\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The non-empty DNS-like name of the target hosted text agent in the same project. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The target agent version. Omit this property to select the latest version when the voice + session starts. When supplied, use a positive integer or ``draft-{positive-unix-timestamp}`` + whose numeric component fits in a signed 64-bit integer.""" @overload def __init__( self, *, - start_time: datetime.datetime, - description: Optional[str] = None, - agent_id: Optional[str] = None, - agent_name: Optional[str] = None, - agent_version: Optional[str] = None, - end_time: Optional[datetime.datetime] = None, + name: str, + version: Optional[str] = None, ) -> None: ... @overload @@ -17439,29 +29594,88 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = EvaluatorGenerationJobSourceType.TRACES # type: ignore + self.type = "hosted_agent" # type: ignore -class UpdateModelVersionRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Request body for updating a model version. Only description and tags can be modified. +class VoiceItemAudioResponse(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for a single conversation item's audio segment. For bring-your-own-storage (BYOS), the + response includes ``blob_uri``, a direct customer-storage URI without a SAS token, that the + customer accesses with their own credentials. For Foundry-managed storage, ``blob_uri`` is + absent and the bytes are streamed through the item's ``/audio/content`` route. - :ivar description: The asset description text. - :vartype description: str - :ivar tags: Tag dictionary. Tags can be added, removed, and updated. - :vartype tags: dict[str, str] + :ivar conversation_id: The id of the conversation the item belongs to. Required. + :vartype conversation_id: str + :ivar item_id: The id of the item this audio belongs to. Required. + :vartype item_id: str + :ivar role: The role the audio belongs to. Known values are: "user" and "agent". + :vartype role: str or ~azure.ai.projects.models.VoiceAudioRole + :ivar format: The container format of the audio. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar codec: The audio codec. Known values are: "pcm16", "pcmu", and "pcma". + :vartype codec: str or ~azure.ai.projects.models.VoiceAudioCodec + :ivar sample_rate: The sample rate in Hz. + :vartype sample_rate: int + :ivar channels: The number of audio channels. + :vartype channels: int + :ivar start_offset_ms: The offset from the session start at which this segment begins. + :vartype start_offset_ms: ~datetime.timedelta + :ivar duration_ms: The duration of the audio segment. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the recording in + the customer's own storage, without a SAS token. The customer downloads it using their own + storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + item's ``/audio/content`` route instead. + :vartype blob_uri: str """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The asset description text.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Tag dictionary. Tags can be added, removed, and updated.""" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation the item belongs to. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the item this audio belongs to. Required.""" + role: Optional[Union[str, "_models.VoiceAudioRole"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The role the audio belongs to. Known values are: \"user\" and \"agent\".""" + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The container format of the audio. \"wav\"""" + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio codec. Known values are: \"pcm16\", \"pcmu\", and \"pcma\".""" + sample_rate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate in Hz.""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels.""" + start_offset_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The offset from the session start at which this segment begins.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The duration of the audio segment.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the recording in the customer's + own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the item's + ``/audio/content`` route instead.""" @overload def __init__( self, *, - description: Optional[str] = None, - tags: Optional[dict[str, str]] = None, + conversation_id: str, + item_id: str, + role: Optional[Union[str, "_models.VoiceAudioRole"]] = None, + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = None, + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = None, + sample_rate: Optional[int] = None, + channels: Optional[int] = None, + start_offset_ms: Optional[datetime.timedelta] = None, + duration_ms: Optional[datetime.timedelta] = None, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17475,23 +29689,92 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class UpdateToolboxRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """UpdateToolboxRequest. +class VoiceRecordingChannelLayout(_Model): # pylint: disable=docstring-missing-param + """The role assigned to each channel of a merged stereo voice recording. - :ivar default_version: The version identifier that the toolbox should point to. When set, the - toolbox's default version will resolve to this version instead of the latest. Required. - :vartype default_version: str + :ivar left: The role carried on the left channel. Always ``user``. Required. Default value is + "user". + :vartype left: str + :ivar right: The role carried on the right channel. Always ``agent``. Required. Default value + is "agent". + :vartype right: str """ - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier that the toolbox should point to. When set, the toolbox's default - version will resolve to this version instead of the latest. Required.""" + left: Literal["user"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The role carried on the left channel. Always ``user``. Required. Default value is \"user\".""" + right: Literal["agent"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The role carried on the right channel. Always ``agent``. Required. Default value is \"agent\".""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.left: Literal["user"] = "user" + self.right: Literal["agent"] = "agent" + + +class VoiceRecordingResponse(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for the merged, whole-call stereo recording of a voice conversation (user audio on the + left channel, agent audio on the right). Built once from the per-turn segments after the + session ends and durably cached. The common metadata (format, sample rate, channels, channel + layout, duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) + recordings. For BYOS the response also includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS token), which the customer downloads using their own storage + credentials. For Foundry-managed storage ``blob_uri`` is absent and the bytes are streamed via + the ``/audio/content`` route instead. + + :ivar conversation_id: The id of the conversation this recording belongs to. Required. + :vartype conversation_id: str + :ivar format: The container format of the recording. Required. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar sample_rate: The sample rate of the recording in Hz, e.g. 24000. Required. + :vartype sample_rate: int + :ivar channels: The number of audio channels. The merged recording is stereo (``2``). Required. + :vartype channels: int + :ivar channel_layout: The role assigned to each stereo channel. Required. + :vartype channel_layout: ~azure.ai.projects.models.VoiceRecordingChannelLayout + :ivar duration_ms: The total duration of the recording. Required. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the recording in + the customer's own storage, without a SAS token. The customer downloads it using their own + storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + ``/audio/content`` route instead. + :vartype blob_uri: str + """ + + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation this recording belongs to. Required.""" + format: Union[str, "_models.VoiceAudioContainerFormat"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The container format of the recording. Required. \"wav\"""" + sample_rate: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate of the recording in Hz, e.g. 24000. Required.""" + channels: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels. The merged recording is stereo (``2``). Required.""" + channel_layout: "_models.VoiceRecordingChannelLayout" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The role assigned to each stereo channel. Required.""" + duration_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The total duration of the recording. Required.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the recording in the customer's + own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + ``/audio/content`` route instead.""" @overload def __init__( self, *, - default_version: str, + conversation_id: str, + format: Union[str, "_models.VoiceAudioContainerFormat"], + sample_rate: int, + channels: int, + channel_layout: "_models.VoiceRecordingChannelLayout", + duration_ms: datetime.timedelta, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17505,37 +29788,94 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class UserProfileMemoryItem( - MemoryItem, discriminator="user_profile" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A memory item specifically containing user profile information extracted from conversations, - such as preferences, interests, and personal details. - - :ivar memory_id: The unique ID of the memory item. Required. - :vartype memory_id: str - :ivar updated_at: The last update time of the memory item. Required. - :vartype updated_at: ~datetime.datetime - :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :vartype scope: str - :ivar content: The content of the memory. Required. - :vartype content: str - :ivar kind: The kind of the memory item. Required. User profile information extracted from - conversations. - :vartype kind: str or ~azure.ai.projects.models.USER_PROFILE - """ +class VoiceResponseBase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Properties shared by persisted voice responses. - kind: Literal[MemoryItemKind.USER_PROFILE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The kind of the memory item. Required. User profile information extracted from conversations.""" + :ivar id: The unique ID of the response, will look like ``resp_1234``. + :vartype id: str + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar conversation_id: Which conversation the response is added to, determined by the + ``conversation`` field in the ``response.create`` event. If ``auto``, the response will be + added to the default conversation and the value of ``conversation_id`` will be an id like + ``conv_1234``. If ``none``, the response will not be added to any conversation and the value of + ``conversation_id`` will be ``null``. If responses are being triggered automatically by VAD the + response will be added to the default conversation. + :vartype conversation_id: str + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the response, will look like ``resp_1234``.""" + object: Optional[Literal["realtime.response"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The object type, must be ``realtime.response``. Default value is \"realtime.response\".""" + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The final status of the response (``completed``, ``cancelled``, ``failed``, or ``incomplete``, + ``in_progress``). Is one of the following types: Literal[\"completed\"], + Literal[\"cancelled\"], Literal[\"failed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + status_details: Optional["_models.RealtimeResponseStatusDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional details about the status.""" + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the Response, this will correspond to billing. A Realtime API session will + maintain a conversation context and append new Items to the Conversation, thus output from + previous turns (text and audio tokens) will become the input for later turns.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Which conversation the response is added to, determined by the ``conversation`` field in the + ``response.create`` event. If ``auto``, the response will be added to the default conversation + and the value of ``conversation_id`` will be an id like ``conv_1234``. If ``none``, the + response will not be added to any conversation and the value of ``conversation_id`` will be + ``null``. If responses are being triggered automatically by VAD the response will be added to + the default conversation.""" + output_modalities: Optional[list[Literal["text", "audio"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The set of modalities the model used to respond, currently the only possible values are + ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text transcript. Setting the + output to mode ``text`` will disable audio output from the model.""" + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls, that + was used in this response. Is either a int type or a Literal[\"inf\"] type.""" @overload def __init__( self, *, - memory_id: str, - updated_at: datetime.datetime, - scope: str, - content: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + conversation_id: Optional[str] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, ) -> None: ... @overload @@ -17547,28 +29887,105 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.kind = MemoryItemKind.USER_PROFILE # type: ignore -class VersionIndicator(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Version indicator determining which agent version backs the session. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - VersionRefIndicator +class VoiceResponse(VoiceResponseBase): # pylint: disable=docstring-keyword-should-match-keyword-only + """A persisted voice response representing one model inference turn within a conversation. In list + results the ``output`` projection may be omitted; retrieve the full response (``GET + .../responses/{response_id}``) or the paged response-items route (``GET + .../responses/{response_id}/items``) for its output items. ``created_at``/``completed_at`` are + Foundry durable ordering extensions. - :ivar type: The type of version indicator. Required. "version_ref" - :vartype type: str or ~azure.ai.projects.models.VersionIndicatorType + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar id: The unique id of the response. Required. + :vartype id: str + :ivar output: The output items produced by the response. May be omitted in list results; + retrieve the full response (GET .../responses/{response_id}) or use the paged response-items + route (GET .../responses/{response_id}/items) for its output items. Each item's ``response_id`` + also links it back to this response in the conversation-level items list. + :vartype output: list[~azure.ai.projects.models.RealtimeConversationItem] + :ivar conversation_id: The id of the conversation this response belongs to. Required. + :vartype conversation_id: str + :ivar audio: The audio configuration used for the response, including the voice and audio + format used for output. + :vartype audio: ~azure.ai.projects.models.VoiceResponseAudio + :ivar metadata: A set of key-value pairs attached to the response. + :vartype metadata: dict[str, str] + :ivar temperature: The sampling temperature used for the response. + :vartype temperature: float + :ivar created_at: The Unix timestamp (in seconds) for when the response was created. + :vartype created_at: ~datetime.datetime + :ivar completed_at: The Unix timestamp (in seconds) for when the response completed. + :vartype completed_at: ~datetime.datetime """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of version indicator. Required. \"version_ref\"""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) # type: ignore[reportIncompatibleVariableOverride] + """The unique id of the response. Required.""" + output: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output items produced by the response. May be omitted in list results; retrieve the full + response (GET .../responses/{response_id}) or use the paged response-items route (GET + .../responses/{response_id}/items) for its output items. Each item's ``response_id`` also links + it back to this response in the conversation-level items list.""" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) # type: ignore[reportIncompatibleVariableOverride] + """The id of the conversation this response belongs to. Required.""" + audio: Optional["_models.VoiceResponseAudio"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio configuration used for the response, including the voice and audio format used for + output.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A set of key-value pairs attached to the response.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature used for the response.""" + created_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the response was created.""" + completed_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the response completed.""" @overload def __init__( self, *, - type: str, + id: str, # pylint: disable=redefined-builtin + conversation_id: str, + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + output: Optional[list["_models.RealtimeConversationItem"]] = None, + audio: Optional["_models.VoiceResponseAudio"] = None, + metadata: Optional[dict[str, str]] = None, + temperature: Optional[float] = None, + created_at: Optional[datetime.datetime] = None, + completed_at: Optional[datetime.datetime] = None, ) -> None: ... @overload @@ -17582,28 +29999,23 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class VersionRefIndicator( - VersionIndicator, discriminator="version_ref" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Version indicator that references a specific agent version by name. +class VoiceResponseAudio(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Audio configuration for a response. Follows the OpenAI Realtime GA ``audio`` object shape. - :ivar type: Discriminator value for version_ref. Required. Direct reference to a specific agent - version. - :vartype type: str or ~azure.ai.projects.models.VERSION_REF - :ivar agent_version: The agent version identifier returned by the agent version APIs. Required. - :vartype agent_version: str + :ivar output: The audio output configuration used for the response. + :vartype output: ~azure.ai.projects.models.VoiceResponseAudioOutput """ - type: Literal[VersionIndicatorType.VERSION_REF] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Discriminator value for version_ref. Required. Direct reference to a specific agent version.""" - agent_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version identifier returned by the agent version APIs. Required.""" + output: Optional["_models.VoiceResponseAudioOutput"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio output configuration used for the response.""" @overload def __init__( self, *, - agent_version: str, + output: Optional["_models.VoiceResponseAudioOutput"] = None, ) -> None: ... @overload @@ -17615,26 +30027,47 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = VersionIndicatorType.VERSION_REF # type: ignore -class VersionSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """VersionSelector. +class VoiceResponseAudioOutput(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The flat response audio-output projection, with optional ``voice``, ``voice_type``, + ``voice_locale``, and ``format`` fields. - :ivar version_selection_rules: Required. - :vartype version_selection_rules: list[~azure.ai.projects.models.VersionSelectionRule] + :ivar voice: The voice name used for the response's audio output. + :vartype voice: str + :ivar voice_type: The extensible provider/type of the voice used for the response's audio + output. Known values are: "openai", "azure-standard", "azure-custom", "azure-personal", + "avatar-voice-sync", and "azure-realtime-native". + :vartype voice_type: str or ~azure.ai.projects.models.VoiceType + :ivar voice_locale: The BCP-47 locale of the voice used for the response's audio output. + :vartype voice_locale: str + :ivar format: The audio format used for the response's audio output. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats """ - version_selection_rules: list["_models.VersionSelectionRule"] = rest_field( + voice: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice name used for the response's audio output.""" + voice_type: Optional[Union[str, "_models.VoiceType"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Required.""" + """The extensible provider/type of the voice used for the response's audio output. Known values + are: \"openai\", \"azure-standard\", \"azure-custom\", \"azure-personal\", + \"avatar-voice-sync\", and \"azure-realtime-native\".""" + voice_locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The BCP-47 locale of the voice used for the response's audio output.""" + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio format used for the response's audio output.""" @overload def __init__( self, *, - version_selection_rules: list["_models.VersionSelectionRule"], + voice: Optional[str] = None, + voice_type: Optional[Union[str, "_models.VoiceType"]] = None, + voice_locale: Optional[str] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, ) -> None: ... @overload diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py index 6409215625eb..c315c4298613 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py @@ -56,6 +56,7 @@ [ _AgentDefinitionOptInKeys.WORKFLOW_AGENTS_V1_PREVIEW.value, _AgentDefinitionOptInKeys.EXTERNAL_AGENTS_V1_PREVIEW.value, + _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value, _AgentDefinitionOptInKeys.DRAFT_AGENTS_V1_PREVIEW.value, _FoundryFeaturesOptInKeys.AGENTS_OPTIMIZATION_V2_PREVIEW.value, _FoundryFeaturesOptInKeys.MODEL_ROUTER_CONTROLS_V1_PREVIEW.value, @@ -75,6 +76,13 @@ "skills": _FoundryFeaturesOptInKeys.SKILLS_V1_PREVIEW.value, "datasets": _FoundryFeaturesOptInKeys.DATA_GENERATION_JOBS_V1_PREVIEW.value, "agents": _AGENT_OPERATION_FEATURE_HEADERS, + # NOTE: `agent_endpoint_conversations` used to need an entry here (it lived as a nested + # `.beta` sub-client). Upstream has since merged it entirely into the top-level, stable + # `agent_endpoint_conversations` client attribute (all methods that used to live under + # `.beta.agent_endpoint_conversations` moved there), so it's no longer part of `.beta` at + # all and must NOT have an entry in this dict -- `BetaOperations.__init__` would raise + # AttributeError trying to `getattr(self, "agent_endpoint_conversations")` otherwise, since + # that attribute no longer exists on the generated `BetaOperations` base class. } """Foundry-Features header values keyed by beta sub-client property name.""" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/__init__.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/__init__.py index d6cf67b4d8cf..19d6ddc7b035 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/__init__.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/__init__.py @@ -19,6 +19,9 @@ from ._operations import DatasetsOperations # type: ignore from ._operations import DeploymentsOperations # type: ignore from ._operations import IndexesOperations # type: ignore +from ._operations import VoiceAgentWebSocketOperations # type: ignore +from ._operations import AgentEndpointConversationsOperations # type: ignore +from ._operations import AgentTelephonyOperations # type: ignore from ._operations import ToolboxesOperations # type: ignore from ._patch import __all__ as _patch_all @@ -33,6 +36,9 @@ "DatasetsOperations", "DeploymentsOperations", "IndexesOperations", + "VoiceAgentWebSocketOperations", + "AgentEndpointConversationsOperations", + "AgentTelephonyOperations", "ToolboxesOperations", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py index c48934cf5f7f..cadba5320db1 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -10,15 +10,16 @@ import datetime from io import IOBase import json -from typing import Any, Callable, IO, Iterator, Literal, Optional, TypeVar, Union, cast, overload +from typing import Any, Callable, IO, Iterator, Literal, Optional, TYPE_CHECKING, TypeVar, Union, cast, overload import urllib.parse import uuid -from azure.core import PipelineClient +from azure.core import MatchConditions, PipelineClient from azure.core.exceptions import ( ClientAuthenticationError, HttpResponseError, ResourceExistsError, + ResourceModifiedError, ResourceNotFoundError, ResourceNotModifiedError, StreamClosedError, @@ -37,8 +38,11 @@ from .._configuration import AIProjectClientConfiguration from .._utils.model_base import Model as _Model, SdkJSONEncoder, _deserialize, _failsafe_deserialize from .._utils.serialization import Deserializer, Serializer -from .._utils.utils import prepare_multipart_form_data +from .._utils.utils import prep_if_match, prep_if_none_match, prepare_multipart_form_data +from ..models._enums import _AgentDefinitionOptInKeys +if TYPE_CHECKING: + from .. import _unions JSON = MutableMapping[str, Any] _Unset: Any = object() T = TypeVar("T") @@ -73,6 +77,28 @@ def build_agents_get_request(agent_name: str, **kwargs: Any) -> HttpRequest: return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) +def build_agents_generate_agent_request(**kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents:generate" + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + def build_agents_delete_request(agent_name: str, *, force: Optional[bool] = None, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -653,8 +679,8 @@ def build_agents_get_microsoft365_publish_defaults_request( # pylint: disable=n return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_agents_upload_session_file_request( - agent_name: str, session_id: str, *, path: str, **kwargs: Any +def build_agents_create_telephony_binding_request( # pylint: disable=name-too-long + agent_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -664,59 +690,35 @@ def build_agents_upload_session_file_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files/content" + _url = "/agents/{agent_name}/telephony/bindings" path_format_arguments = { "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), - "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params["path"] = _SERIALIZER.query("path", path, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if "Repeatability-Request-ID" not in _headers: + _headers["Repeatability-Request-ID"] = str(uuid.uuid4()) + if "Repeatability-First-Sent" not in _headers: + _headers["Repeatability-First-Sent"] = _SERIALIZER.serialize_data( + datetime.datetime.now(datetime.timezone.utc), "rfc-1123" + ) if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) - - -def build_agents_download_session_file_request( # pylint: disable=name-too-long - agent_name: str, session_id: str, *, path: str, **kwargs: Any -) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/octet-stream") - - # Construct URL - _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files/content" - path_format_arguments = { - "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), - "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["path"] = _SERIALIZER.query("path", path, "str") - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_agents_list_session_files_request( +def build_agents_list_telephony_bindings_request( # pylint: disable=name-too-long agent_name: str, - session_id: str, *, - path: Optional[str] = None, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, after: Optional[str] = None, @@ -730,17 +732,18 @@ def build_agents_list_session_files_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files" + _url = "/agents/{agent_name}/telephony/bindings" path_format_arguments = { "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), - "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if path is not None: - _params["path"] = _SERIALIZER.query("path", path, "str") + if provider is not None: + _params["provider"] = _SERIALIZER.query("provider", provider, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") if limit is not None: _params["limit"] = _SERIALIZER.query("limit", limit, "int") if order is not None: @@ -757,41 +760,48 @@ def build_agents_list_session_files_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_agents_delete_session_file_request( - agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any +def build_agents_get_telephony_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, **kwargs: Any ) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files" + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" path_format_arguments = { "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), - "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - _params["path"] = _SERIALIZER.query("path", path, "str") - if recursive is not None: - _params["recursive"] = _SERIALIZER.query("recursive", recursive, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_evaluation_rules_get_request(id: str, **kwargs: Any) -> HttpRequest: + +def build_agents_update_telephony_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationrules/{id}" + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" path_format_arguments = { - "id": _SERIALIZER.url("id", id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -800,19 +810,31 @@ def build_evaluation_rules_get_request(id: str, **kwargs: Any) -> HttpRequest: _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + if_none_match = prep_if_none_match(etag, match_condition) + if if_none_match is not None: + _headers["if-none-match"] = _SERIALIZER.header("if_none_match", if_none_match, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_evaluation_rules_delete_request(id: str, **kwargs: Any) -> HttpRequest: +def build_agents_delete_telephony_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) # Construct URL - _url = "/evaluationrules/{id}" + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" path_format_arguments = { - "id": _SERIALIZER.url("id", id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -820,45 +842,70 @@ def build_evaluation_rules_delete_request(id: str, **kwargs: Any) -> HttpRequest # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + if_none_match = prep_if_none_match(etag, match_condition) + if if_none_match is not None: + _headers["if-none-match"] = _SERIALIZER.header("if_none_match", if_none_match, "str") + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_evaluation_rules_create_or_update_request( # pylint: disable=name-too-long - id: str, **kwargs: Any + +def build_agents_list_telephony_calls_request( # pylint: disable=name-too-long + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after: Optional[datetime.datetime] = None, + started_before: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationrules/{id}" + _url = "/agents/{agent_name}/telephony/calls" path_format_arguments = { - "id": _SERIALIZER.url("id", id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if provider is not None: + _params["provider"] = _SERIALIZER.query("provider", provider, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if started_after is not None: + _params["started_after"] = _SERIALIZER.query("started_after", started_after, "unix-time") + if started_before is not None: + _params["started_before"] = _SERIALIZER.query("started_before", started_before, "unix-time") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_evaluation_rules_list_request( - *, - action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, - agent_name: Optional[str] = None, - enabled: Optional[bool] = None, - **kwargs: Any -) -> HttpRequest: +def build_agents_get_telephony_call_request(agent_name: str, call_id: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -866,16 +913,16 @@ def build_evaluation_rules_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationrules" + _url = "/agents/{agent_name}/telephony/calls/{call_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if action_type is not None: - _params["actionType"] = _SERIALIZER.query("action_type", action_type, "str") - if agent_name is not None: - _params["agentName"] = _SERIALIZER.query("agent_name", agent_name, "str") - if enabled is not None: - _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -883,17 +930,21 @@ def build_evaluation_rules_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_connections_get_request(name: str, **kwargs: Any) -> HttpRequest: +def build_agents_transfer_telephony_call_request( # pylint: disable=name-too-long + agent_name: str, call_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/connections/{name}" + _url = "/agents/{agent_name}/telephony/calls/{call_id}:transfer" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -902,14 +953,14 @@ def build_connections_get_request(name: str, **kwargs: Any) -> HttpRequest: _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_connections_get_with_credentials_request( # pylint: disable=name-too-long - name: str, **kwargs: Any -) -> HttpRequest: +def build_agents_end_telephony_call_request(agent_name: str, call_id: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -917,9 +968,10 @@ def build_connections_get_with_credentials_request( # pylint: disable=name-too- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/connections/{name}/getConnectionWithCredentials" + _url = "/agents/{agent_name}/telephony/calls/{call_id}:end" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -933,11 +985,8 @@ def build_connections_get_with_credentials_request( # pylint: disable=name-too- return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_connections_list_request( - *, - connection_type: Optional[Union[str, _models.ConnectionType]] = None, - default_connection: Optional[bool] = None, - **kwargs: Any +def build_agents_get_telephony_transfer_targets_request( # pylint: disable=name-too-long + agent_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -946,14 +995,15 @@ def build_connections_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/connections" + _url = "/agents/{agent_name}/telephony/transfer_targets" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if connection_type is not None: - _params["connectionType"] = _SERIALIZER.query("connection_type", connection_type, "str") - if default_connection is not None: - _params["defaultConnection"] = _SERIALIZER.query("default_connection", default_connection, "bool") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -961,17 +1011,20 @@ def build_connections_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: +def build_agents_replace_telephony_transfer_targets_request( # pylint: disable=name-too-long + agent_name: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/datasets/{name}/versions" + _url = "/agents/{agent_name}/telephony/transfer_targets" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -980,47 +1033,70 @@ def build_datasets_list_versions_request(name: str, **kwargs: Any) -> HttpReques _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + if_none_match = prep_if_none_match(etag, match_condition) + if if_none_match is not None: + _headers["if-none-match"] = _SERIALIZER.header("if_none_match", if_none_match, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_list_request(**kwargs: Any) -> HttpRequest: +def build_agents_upload_session_file_request( + agent_name: str, session_id: str, *, path: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/datasets" + _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files/content" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + _params["path"] = _SERIALIZER.query("path", path, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_agents_download_session_file_request( # pylint: disable=name-too-long + agent_name: str, session_id: str, *, path: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") + accept = _headers.pop("Accept", "application/octet-stream") # Construct URL - _url = "/datasets/{name}/versions/{version}" + _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files/content" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + _params["path"] = _SERIALIZER.query("path", path, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -1029,38 +1105,86 @@ def build_datasets_get_request(name: str, version: str, **kwargs: Any) -> HttpRe return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_agents_list_session_files_request( + agent_name: str, + session_id: str, + *, + path: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/datasets/{name}/versions/{version}" + _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if path is not None: + _params["path"] = _SERIALIZER.query("path", path, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_agents_delete_session_file_request( + agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agents/{agent_name}/endpoint/sessions/{agent_session_id}/files" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "agent_session_id": _SERIALIZER.url("session_id", session_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["path"] = _SERIALIZER.query("path", path, "str") + if recursive is not None: + _params["recursive"] = _SERIALIZER.query("recursive", recursive, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_datasets_create_or_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_evaluation_rules_get_request(id: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/datasets/{name}/versions/{version}" + _url = "/evaluationrules/{id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "id": _SERIALIZER.url("id", id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1069,14 +1193,32 @@ def build_datasets_create_or_update_request(name: str, version: str, **kwargs: A _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_pending_upload_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_evaluation_rules_delete_request(id: str, **kwargs: Any) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/evaluationrules/{id}" + path_format_arguments = { + "id": _SERIALIZER.url("id", id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + + +def build_evaluation_rules_create_or_update_request( # pylint: disable=name-too-long + id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1085,10 +1227,9 @@ def build_datasets_pending_upload_request(name: str, version: str, **kwargs: Any accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/datasets/{name}/versions/{version}/startPendingUpload" + _url = "/evaluationrules/{id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "id": _SERIALIZER.url("id", id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1101,10 +1242,16 @@ def build_datasets_pending_upload_request(name: str, version: str, **kwargs: Any _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_datasets_get_credentials_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_evaluation_rules_list_request( + *, + action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, + agent_name: Optional[str] = None, + enabled: Optional[bool] = None, + **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1112,10 +1259,34 @@ def build_datasets_get_credentials_request(name: str, version: str, **kwargs: An accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/datasets/{name}/versions/{version}/credentials" + _url = "/evaluationrules" + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if action_type is not None: + _params["actionType"] = _SERIALIZER.query("action_type", action_type, "str") + if agent_name is not None: + _params["agentName"] = _SERIALIZER.query("agent_name", agent_name, "str") + if enabled is not None: + _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_connections_get_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/connections/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1126,10 +1297,12 @@ def build_datasets_get_credentials_request(name: str, version: str, **kwargs: An # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_deployments_get_request(name: str, **kwargs: Any) -> HttpRequest: +def build_connections_get_with_credentials_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1137,7 +1310,7 @@ def build_deployments_get_request(name: str, **kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/deployments/{name}" + _url = "/connections/{name}/getConnectionWithCredentials" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -1150,14 +1323,13 @@ def build_deployments_get_request(name: str, **kwargs: Any) -> HttpRequest: # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_deployments_list_request( +def build_connections_list_request( *, - model_publisher: Optional[str] = None, - model_name: Optional[str] = None, - deployment_type: Optional[Union[str, _models.DeploymentType]] = None, + connection_type: Optional[Union[str, _models.ConnectionType]] = None, + default_connection: Optional[bool] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -1167,16 +1339,14 @@ def build_deployments_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/deployments" + _url = "/connections" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if model_publisher is not None: - _params["modelPublisher"] = _SERIALIZER.query("model_publisher", model_publisher, "str") - if model_name is not None: - _params["modelName"] = _SERIALIZER.query("model_name", model_name, "str") - if deployment_type is not None: - _params["deploymentType"] = _SERIALIZER.query("deployment_type", deployment_type, "str") + if connection_type is not None: + _params["connectionType"] = _SERIALIZER.query("connection_type", connection_type, "str") + if default_connection is not None: + _params["defaultConnection"] = _SERIALIZER.query("default_connection", default_connection, "bool") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -1184,7 +1354,7 @@ def build_deployments_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_indexes_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: +def build_datasets_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1192,7 +1362,7 @@ def build_indexes_list_versions_request(name: str, **kwargs: Any) -> HttpRequest accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/indexes/{name}/versions" + _url = "/datasets/{name}/versions" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -1208,7 +1378,7 @@ def build_indexes_list_versions_request(name: str, **kwargs: Any) -> HttpRequest return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_indexes_list_request(**kwargs: Any) -> HttpRequest: +def build_datasets_list_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1216,7 +1386,7 @@ def build_indexes_list_request(**kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/indexes" + _url = "/datasets" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") @@ -1227,7 +1397,7 @@ def build_indexes_list_request(**kwargs: Any) -> HttpRequest: return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_indexes_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_datasets_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1235,7 +1405,7 @@ def build_indexes_get_request(name: str, version: str, **kwargs: Any) -> HttpReq accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/indexes/{name}/versions/{version}" + _url = "/datasets/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -1252,12 +1422,12 @@ def build_indexes_get_request(name: str, version: str, **kwargs: Any) -> HttpReq return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_indexes_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_datasets_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) # Construct URL - _url = "/indexes/{name}/versions/{version}" + _url = "/datasets/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -1271,7 +1441,7 @@ def build_indexes_delete_request(name: str, version: str, **kwargs: Any) -> Http return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_indexes_create_or_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_datasets_create_or_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1280,7 +1450,7 @@ def build_indexes_create_or_update_request(name: str, version: str, **kwargs: An accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/indexes/{name}/versions/{version}" + _url = "/datasets/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -1299,7 +1469,7 @@ def build_indexes_create_or_update_request(name: str, version: str, **kwargs: An return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_create_version_request(name: str, **kwargs: Any) -> HttpRequest: +def build_datasets_pending_upload_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1308,9 +1478,10 @@ def build_toolboxes_create_version_request(name: str, **kwargs: Any) -> HttpRequ accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes/{name}/versions" + _url = "/datasets/{name}/versions/{version}/startPendingUpload" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1326,7 +1497,7 @@ def build_toolboxes_create_version_request(name: str, **kwargs: Any) -> HttpRequ return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_get_request(name: str, **kwargs: Any) -> HttpRequest: +def build_datasets_get_credentials_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1334,9 +1505,10 @@ def build_toolboxes_get_request(name: str, **kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes/{name}" + _url = "/datasets/{name}/versions/{version}/credentials" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1347,17 +1519,10 @@ def build_toolboxes_get_request(name: str, **kwargs: Any) -> HttpRequest: # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_list_request( - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - **kwargs: Any -) -> HttpRequest: +def build_deployments_get_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1365,17 +1530,14 @@ def build_toolboxes_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes" + _url = "/deployments/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -1384,13 +1546,11 @@ def build_toolboxes_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_list_versions_request( - name: str, +def build_deployments_list_request( *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, + model_publisher: Optional[str] = None, + model_name: Optional[str] = None, + deployment_type: Optional[Union[str, _models.DeploymentType]] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -1400,23 +1560,16 @@ def build_toolboxes_list_versions_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes/{name}/versions" - path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/deployments" # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if model_publisher is not None: + _params["modelPublisher"] = _SERIALIZER.query("model_publisher", model_publisher, "str") + if model_name is not None: + _params["modelName"] = _SERIALIZER.query("model_name", model_name, "str") + if deployment_type is not None: + _params["deploymentType"] = _SERIALIZER.query("deployment_type", deployment_type, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -1424,7 +1577,7 @@ def build_toolboxes_list_versions_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_get_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_indexes_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1432,10 +1585,9 @@ def build_toolboxes_get_version_request(name: str, version: str, **kwargs: Any) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes/{name}/versions/{version}" + _url = "/indexes/{name}/versions" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1449,41 +1601,37 @@ def build_toolboxes_get_version_request(name: str, version: str, **kwargs: Any) return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_update_request(name: str, **kwargs: Any) -> HttpRequest: +def build_indexes_list_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/toolboxes/{name}" - path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/indexes" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_delete_request(name: str, **kwargs: Any) -> HttpRequest: +def build_indexes_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/toolboxes/{name}" + _url = "/indexes/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1491,15 +1639,18 @@ def build_toolboxes_delete_request(name: str, **kwargs: Any) -> HttpRequest: # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_toolboxes_delete_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + +def build_indexes_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) # Construct URL - _url = "/toolboxes/{name}/versions/{version}" + _url = "/indexes/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -1513,67 +1664,119 @@ def build_toolboxes_delete_version_request(name: str, version: str, **kwargs: An return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_agent_insight_monitors_list_request( # pylint: disable=name-too-long - *, - after: Optional[str] = None, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - agent_name: Optional[str] = None, - **kwargs: Any -) -> HttpRequest: +def build_indexes_create_or_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors" + _url = "/indexes/{name}/versions/{version}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if agent_name is not None: - _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_voice_agent_web_socket_connect_voice_agent_request( # pylint: disable=name-too-long + agent_name: str, + *, + foundry_features_query: Optional[Literal[_AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW]] = None, + transport: Optional[Union[str, _models.VoiceAgentTransport]] = None, + store: Optional[bool] = None, + structured_input: Optional[str] = None, + agent_version_override: Optional[str] = None, + websocket_subprotocol: Optional[Union[str, _models.VoiceAgentWebSocketSubprotocol]] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + if foundry_features_query is not None: + _params["foundry_features"] = _SERIALIZER.query("foundry_features_query", foundry_features_query, "str") + if transport is not None: + _params["transport"] = _SERIALIZER.query("transport", transport, "str") + if store is not None: + _params["store"] = _SERIALIZER.query("store", store, "bool") + if structured_input is not None: + _params["structured_input"] = _SERIALIZER.query("structured_input", structured_input, "str") + if agent_version_override is not None: + _params["x-agent-version-override"] = _SERIALIZER.query("agent_version_override", agent_version_override, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if websocket_subprotocol is not None: + _headers["Sec-WebSocket-Protocol"] = _SERIALIZER.header("websocket_subprotocol", websocket_subprotocol, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_create_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long +def build_agent_endpoint_conversations_list_agent_conversations_request( # pylint: disable=name-too-long + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_get_request( # pylint: disable=name-too-long - monitor_id: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1582,9 +1785,10 @@ def build_beta_agent_insight_monitors_get_request( # pylint: disable=name-too-l accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1598,16 +1802,17 @@ def build_beta_agent_insight_monitors_get_request( # pylint: disable=name-too-l return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_delete_request( # pylint: disable=name-too-long - monitor_id: str, **kwargs: Any +def build_agent_endpoint_conversations_delete_agent_conversation_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any ) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) # Construct URL - _url = "/agent_insight_monitors/{monitor_id}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1618,45 +1823,63 @@ def build_beta_agent_insight_monitors_delete_request( # pylint: disable=name-to return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_agent_insight_monitors_update_request( # pylint: disable=name-too-long - monitor_id: str, **kwargs: Any +def build_agent_endpoint_conversations_list_agent_conversation_responses_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_reset_request( # pylint: disable=name-too-long - monitor_id: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_response_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, response_id: str, **kwargs: Any ) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/agent_insight_monitors/{monitor_id}:reset" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses/{response_id}" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "response_id": _SERIALIZER.url("response_id", response_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1664,49 +1887,64 @@ def build_beta_agent_insight_monitors_reset_request( # pylint: disable=name-too # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="POST", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_create_run_request( # pylint: disable=name-too-long - monitor_id: str, *, operation_id: Optional[str] = None, **kwargs: Any + +def build_agent_endpoint_conversations_list_agent_conversation_response_items_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/runs" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses/{response_id}/items" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "response_id": _SERIALIZER.url("response_id", response_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if operation_id is not None: - _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_list_runs_request( # pylint: disable=name-too-long - monitor_id: str, +def build_agent_endpoint_conversations_list_agent_conversation_items_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, *, - after: Optional[str] = None, - before: Optional[str] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, + after: Optional[str] = None, + before: Optional[str] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -1716,26 +1954,23 @@ def build_beta_agent_insight_monitors_list_runs_request( # pylint: disable=name accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/runs" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") if limit is not None: _params["limit"] = _SERIALIZER.query("limit", limit, "int") if order is not None: _params["order"] = _SERIALIZER.query("order", order, "str") - if status is not None: - _params["status"] = _SERIALIZER.query("status", status, "str") - if trigger is not None: - _params["trigger"] = _SERIALIZER.query("trigger", trigger, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -1744,8 +1979,8 @@ def build_beta_agent_insight_monitors_list_runs_request( # pylint: disable=name return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_get_run_request( # pylint: disable=name-too-long - monitor_id: str, run_id: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1754,10 +1989,11 @@ def build_beta_agent_insight_monitors_get_run_request( # pylint: disable=name-t accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/runs/{run_id}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), - "run_id": _SERIALIZER.url("run_id", run_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1771,8 +2007,8 @@ def build_beta_agent_insight_monitors_get_run_request( # pylint: disable=name-t return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_cancel_run_request( # pylint: disable=name-too-long - monitor_id: str, run_id: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_item_audio_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1781,10 +2017,11 @@ def build_beta_agent_insight_monitors_cancel_run_request( # pylint: disable=nam accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/runs/{run_id}:cancel" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), - "run_id": _SERIALIZER.url("run_id", run_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1795,53 +2032,29 @@ def build_beta_agent_insight_monitors_cancel_run_request( # pylint: disable=nam # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_list_insights_request( # pylint: disable=name-too-long - monitor_id: str, - *, - after: Optional[str] = None, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - category: Optional[str] = None, - severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, - status: Optional[Union[str, _models.AgentInsightStatus]] = None, - include_details: Optional[bool] = None, - **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_item_audio_content_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") + accept = _headers.pop("Accept", "audio/wav") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/insights" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/content" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if category is not None: - _params["category"] = _SERIALIZER.query("category", category, "str") - if severity is not None: - _params["severity"] = _SERIALIZER.query("severity", severity, "str") - if status is not None: - _params["status"] = _SERIALIZER.query("status", status, "str") - if include_details is not None: - _params["include_details"] = _SERIALIZER.query("include_details", include_details, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -1850,8 +2063,8 @@ def build_beta_agent_insight_monitors_list_insights_request( # pylint: disable= return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_get_insight_request( # pylint: disable=name-too-long - monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1860,17 +2073,18 @@ def build_beta_agent_insight_monitors_get_insight_request( # pylint: disable=na accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/insights/{insight_id}" + _url = ( + "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated" + ) path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), - "insight_id": _SERIALIZER.url("insight_id", insight_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if include_details is not None: - _params["include_details"] = _SERIALIZER.query("include_details", include_details, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -1879,21 +2093,21 @@ def build_beta_agent_insight_monitors_get_insight_request( # pylint: disable=na return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agent_insight_monitors_update_insight_request( # pylint: disable=name-too-long - monitor_id: str, insight_id: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_content_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") + accept = _headers.pop("Accept", "audio/wav") # Construct URL - _url = "/agent_insight_monitors/{monitor_id}/insights/{insight_id}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content" path_format_arguments = { - "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), - "insight_id": _SERIALIZER.url("insight_id", insight_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1902,15 +2116,13 @@ def build_beta_agent_insight_monitors_update_insight_request( # pylint: disable _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluation_taxonomies_get_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_audio_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1919,9 +2131,10 @@ def build_beta_evaluation_taxonomies_get_request( # pylint: disable=name-too-lo accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationtaxonomies/{name}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/audio" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1935,24 +2148,26 @@ def build_beta_evaluation_taxonomies_get_request( # pylint: disable=name-too-lo return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluation_taxonomies_list_request( # pylint: disable=name-too-long - *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any +def build_agent_endpoint_conversations_get_agent_conversation_audio_content_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") + accept = _headers.pop("Accept", "audio/wav") # Construct URL - _url = "/evaluationtaxonomies" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/audio/content" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if input_name is not None: - _params["inputName"] = _SERIALIZER.query("input_name", input_name, "str") - if input_type is not None: - _params["inputType"] = _SERIALIZER.query("input_type", input_type, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -1960,16 +2175,20 @@ def build_beta_evaluation_taxonomies_list_request( # pylint: disable=name-too-l return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluation_taxonomies_delete_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_agent_telephony_create_telephony_call_job_request( # pylint: disable=name-too-long + agent_name: str, *, idempotency_key: str, **kwargs: Any ) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/evaluationtaxonomies/{name}" + _url = "/agents/{agent_name}/telephony/call_jobs" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -1977,23 +2196,29 @@ def build_beta_evaluation_taxonomies_delete_request( # pylint: disable=name-too # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Idempotency-Key"] = _SERIALIZER.header("idempotency_key", idempotency_key, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluation_taxonomies_create_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_agent_telephony_get_telephony_call_job_request( # pylint: disable=name-too-long + agent_name: str, call_job_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationtaxonomies/{name}" + _url = "/agents/{agent_name}/telephony/call_jobs/{call_job_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_job_id": _SERIALIZER.url("call_job_id", call_job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2002,15 +2227,46 @@ def build_beta_evaluation_taxonomies_create_request( # pylint: disable=name-too _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluation_taxonomies_update_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_agent_telephony_cancel_telephony_call_job_request( # pylint: disable=name-too-long + agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_job_id": _SERIALIZER.url("call_job_id", call_job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + if_none_match = prep_if_none_match(etag, match_condition) + if if_none_match is not None: + _headers["if-none-match"] = _SERIALIZER.header("if_none_match", if_none_match, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_agent_telephony_create_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2020,9 +2276,9 @@ def build_beta_evaluation_taxonomies_update_request( # pylint: disable=name-too accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluationtaxonomies/{name}" + _url = "/agents/{agent_name}/telephony/campaigns" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2035,15 +2291,11 @@ def build_beta_evaluation_taxonomies_update_request( # pylint: disable=name-too _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_list_versions_request( # pylint: disable=name-too-long - name: str, - *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, - limit: Optional[int] = None, - **kwargs: Any +def build_agent_telephony_get_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2052,19 +2304,16 @@ def build_beta_evaluators_list_versions_request( # pylint: disable=name-too-lon accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if type is not None: - _params["type"] = _SERIALIZER.query("type", type, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -2072,36 +2321,39 @@ def build_beta_evaluators_list_versions_request( # pylint: disable=name-too-lon return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_list_request( - *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, - limit: Optional[int] = None, - **kwargs: Any +def build_agent_telephony_import_telephony_campaign_recipients_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, *, idempotency_key: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}/recipients:import" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if type is not None: - _params["type"] = _SERIALIZER.query("type", type, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") # Construct headers + _headers["Idempotency-Key"] = _SERIALIZER.header("idempotency_key", idempotency_key, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_get_version_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_agent_telephony_get_telephony_campaign_recipient_import_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, import_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2110,10 +2362,11 @@ def build_beta_evaluators_get_version_request( # pylint: disable=name-too-long accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions/{version}" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}/recipient_imports/{import_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), + "import_id": _SERIALIZER.url("import_id", import_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2127,17 +2380,20 @@ def build_beta_evaluators_get_version_request( # pylint: disable=name-too-long return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_delete_version_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_agent_telephony_validate_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/evaluators/{name}/versions/{version}" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}:validate" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2145,11 +2401,14 @@ def build_beta_evaluators_delete_version_request( # pylint: disable=name-too-lo # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_create_version_request( # pylint: disable=name-too-long - name: str, **kwargs: Any + +def build_agent_telephony_publish_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2159,9 +2418,10 @@ def build_beta_evaluators_create_version_request( # pylint: disable=name-too-lo accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}:publish" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2177,21 +2437,20 @@ def build_beta_evaluators_create_version_request( # pylint: disable=name-too-lo return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_update_version_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_agent_telephony_pause_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions/{version}" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}:pause" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2200,28 +2459,25 @@ def build_beta_evaluators_update_version_request( # pylint: disable=name-too-lo _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_pending_upload_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_agent_telephony_resume_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions/{version}/startPendingUpload" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}:resume" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2230,28 +2486,25 @@ def build_beta_evaluators_pending_upload_request( # pylint: disable=name-too-lo _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_get_credentials_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_agent_telephony_cancel_telephony_campaign_request( # pylint: disable=name-too-long + agent_name: str, campaign_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluators/{name}/versions/{version}/credentials" + _url = "/agents/{agent_name}/telephony/campaigns/{campaign_id}:cancel" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "campaign_id": _SERIALIZER.url("campaign_id", campaign_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2260,32 +2513,58 @@ def build_beta_evaluators_get_credentials_request( # pylint: disable=name-too-l _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_create_generation_job_request( # pylint: disable=name-too-long - *, operation_id: Optional[str] = None, **kwargs: Any +def build_agent_telephony_get_telephony_operation_request( # pylint: disable=name-too-long + agent_name: str, operation_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/operations/{operation_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "operation_id": _SERIALIZER.url("operation_id", operation_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_toolboxes_create_version_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluator_generation_jobs" + _url = "/toolboxes/{name}/versions" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if operation_id is not None: - _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -2293,9 +2572,7 @@ def build_beta_evaluators_create_generation_job_request( # pylint: disable=name return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_get_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_toolboxes_get_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2303,9 +2580,9 @@ def build_beta_evaluators_get_generation_job_request( # pylint: disable=name-to accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluator_generation_jobs/{jobId}" + _url = "/toolboxes/{name}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2319,7 +2596,7 @@ def build_beta_evaluators_get_generation_job_request( # pylint: disable=name-to return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_list_generation_jobs_request( # pylint: disable=name-too-long +def build_toolboxes_list_request( *, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, @@ -2334,7 +2611,7 @@ def build_beta_evaluators_list_generation_jobs_request( # pylint: disable=name- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluator_generation_jobs" + _url = "/toolboxes" # Construct parameters if limit is not None: @@ -2353,8 +2630,14 @@ def build_beta_evaluators_list_generation_jobs_request( # pylint: disable=name- return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_cancel_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any +def build_toolboxes_list_versions_request( + name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2363,32 +2646,42 @@ def build_beta_evaluators_cancel_generation_job_request( # pylint: disable=name accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/evaluator_generation_jobs/{jobId}:cancel" + _url = "/toolboxes/{name}/versions" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_evaluators_delete_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_toolboxes_get_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/evaluator_generation_jobs/{jobId}" + _url = "/toolboxes/{name}/versions/{version}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2396,10 +2689,13 @@ def build_beta_evaluators_delete_generation_job_request( # pylint: disable=name # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_insights_generate_request(**kwargs: Any) -> HttpRequest: + +def build_toolboxes_update_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2408,60 +2704,68 @@ def build_beta_insights_generate_request(**kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/insights" + _url = "/toolboxes/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if "Repeatability-Request-ID" not in _headers: - _headers["Repeatability-Request-ID"] = str(uuid.uuid4()) - if "Repeatability-First-Sent" not in _headers: - _headers["Repeatability-First-Sent"] = _SERIALIZER.serialize_data( - datetime.datetime.now(datetime.timezone.utc), "rfc-1123" - ) if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_insights_get_request( - insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any -) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) +def build_toolboxes_delete_request(name: str, **kwargs: Any) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/insights/{id}" + _url = "/toolboxes/{name}" path_format_arguments = { - "id": _SERIALIZER.url("insight_id", insight_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if include_coordinates is not None: - _params["includeCoordinates"] = _SERIALIZER.query("include_coordinates", include_coordinates, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) +def build_toolboxes_delete_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) -def build_beta_insights_list_request( + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/toolboxes/{name}/versions/{version}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + + +def build_beta_agent_insight_monitors_list_request( # pylint: disable=name-too-long *, - type: Optional[Union[str, _models.InsightType]] = None, - eval_id: Optional[str] = None, - run_id: Optional[str] = None, + after: Optional[str] = None, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, agent_name: Optional[str] = None, - include_coordinates: Optional[bool] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -2471,19 +2775,19 @@ def build_beta_insights_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/insights" + _url = "/agent_insight_monitors" # Construct parameters - if type is not None: - _params["type"] = _SERIALIZER.query("type", type, "str") - if eval_id is not None: - _params["evalId"] = _SERIALIZER.query("eval_id", eval_id, "str") - if run_id is not None: - _params["runId"] = _SERIALIZER.query("run_id", run_id, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") if agent_name is not None: - _params["agentName"] = _SERIALIZER.query("agent_name", agent_name, "str") - if include_coordinates is not None: - _params["includeCoordinates"] = _SERIALIZER.query("include_coordinates", include_coordinates, "bool") + _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -2492,7 +2796,7 @@ def build_beta_insights_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_create_request(**kwargs: Any) -> HttpRequest: +def build_beta_agent_insight_monitors_create_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2501,7 +2805,7 @@ def build_beta_memory_stores_create_request(**kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores" + _url = "/agent_insight_monitors" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") @@ -2514,18 +2818,19 @@ def build_beta_memory_stores_create_request(**kwargs: Any) -> HttpRequest: return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_update_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_agent_insight_monitors_get_request( # pylint: disable=name-too-long + monitor_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}" + _url = "/agent_insight_monitors/{monitor_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2534,24 +2839,21 @@ def build_beta_memory_stores_update_request(name: str, **kwargs: Any) -> HttpReq _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_get_request(name: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) +def build_beta_agent_insight_monitors_delete_request( # pylint: disable=name-too-long + monitor_id: str, **kwargs: Any +) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/memory_stores/{name}" + _url = "/agent_insight_monitors/{monitor_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2559,57 +2861,48 @@ def build_beta_memory_stores_get_request(name: str, **kwargs: Any) -> HttpReques # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_memory_stores_list_request( - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - **kwargs: Any +def build_beta_agent_insight_monitors_update_request( # pylint: disable=name-too-long + monitor_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores" + _url = "/agent_insight_monitors/{monitor_id}" + path_format_arguments = { + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_delete_request(name: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) +def build_beta_agent_insight_monitors_reset_request( # pylint: disable=name-too-long + monitor_id: str, **kwargs: Any +) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/memory_stores/{name}" + _url = "/agent_insight_monitors/{monitor_id}:reset" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2617,14 +2910,11 @@ def build_beta_memory_stores_delete_request(name: str, **kwargs: Any) -> HttpReq # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, **kwargs) -def build_beta_memory_stores_search_memories_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_beta_agent_insight_monitors_create_run_request( # pylint: disable=name-too-long + monitor_id: str, *, operation_id: Optional[str] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2634,9 +2924,9 @@ def build_beta_memory_stores_search_memories_request( # pylint: disable=name-to accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}:search_memories" + _url = "/agent_insight_monitors/{monitor_id}/runs" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2645,6 +2935,8 @@ def build_beta_memory_stores_search_memories_request( # pylint: disable=name-to _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if operation_id is not None: + _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -2652,49 +2944,66 @@ def build_beta_memory_stores_search_memories_request( # pylint: disable=name-to return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_update_memories_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_beta_agent_insight_monitors_list_runs_request( # pylint: disable=name-too-long + monitor_id: str, + *, + after: Optional[str] = None, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}:update_memories" + _url = "/agent_insight_monitors/{monitor_id}/runs" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if trigger is not None: + _params["trigger"] = _SERIALIZER.query("trigger", trigger, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_delete_scope_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_beta_agent_insight_monitors_get_run_request( # pylint: disable=name-too-long + monitor_id: str, run_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}:delete_scope" + _url = "/agent_insight_monitors/{monitor_id}/runs/{run_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "run_id": _SERIALIZER.url("run_id", run_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2703,27 +3012,25 @@ def build_beta_memory_stores_delete_scope_request( # pylint: disable=name-too-l _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_create_memory_request( # pylint: disable=name-too-long - name: str, **kwargs: Any +def build_beta_agent_insight_monitors_cancel_run_request( # pylint: disable=name-too-long + monitor_id: str, run_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}/items" + _url = "/agent_insight_monitors/{monitor_id}/runs/{run_id}:cancel" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "run_id": _SERIALIZER.url("run_id", run_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2732,46 +3039,66 @@ def build_beta_memory_stores_create_memory_request( # pylint: disable=name-too- _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_update_memory_request( # pylint: disable=name-too-long - name: str, memory_id: str, **kwargs: Any +def build_beta_agent_insight_monitors_list_insights_request( # pylint: disable=name-too-long + monitor_id: str, + *, + after: Optional[str] = None, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + category: Optional[str] = None, + severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, + status: Optional[Union[str, _models.AgentInsightStatus]] = None, + include_details: Optional[bool] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}/items/{memory_id}" + _url = "/agent_insight_monitors/{monitor_id}/insights" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if category is not None: + _params["category"] = _SERIALIZER.query("category", category, "str") + if severity is not None: + _params["severity"] = _SERIALIZER.query("severity", severity, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if include_details is not None: + _params["include_details"] = _SERIALIZER.query("include_details", include_details, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_get_memory_request( # pylint: disable=name-too-long - name: str, memory_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_agent_insight_monitors_get_insight_request( # pylint: disable=name-too-long + monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2779,15 +3106,17 @@ def build_beta_memory_stores_get_memory_request( # pylint: disable=name-too-lon accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}/items/{memory_id}" + _url = "/agent_insight_monitors/{monitor_id}/insights/{insight_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "insight_id": _SERIALIZER.url("insight_id", insight_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if include_details is not None: + _params["include_details"] = _SERIALIZER.query("include_details", include_details, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -2796,15 +3125,8 @@ def build_beta_memory_stores_get_memory_request( # pylint: disable=name-too-lon return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_list_memories_request( # pylint: disable=name-too-long - name: str, - *, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - **kwargs: Any +def build_beta_agent_insight_monitors_update_insight_request( # pylint: disable=name-too-long + monitor_id: str, insight_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2814,24 +3136,15 @@ def build_beta_memory_stores_list_memories_request( # pylint: disable=name-too- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}/items:list" + _url = "/agent_insight_monitors/{monitor_id}/insights/{insight_id}" path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), + "monitor_id": _SERIALIZER.url("monitor_id", monitor_id, "str"), + "insight_id": _SERIALIZER.url("insight_id", insight_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if kind is not None: - _params["kind"] = _SERIALIZER.query("kind", kind, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -2839,11 +3152,11 @@ def build_beta_memory_stores_list_memories_request( # pylint: disable=name-too- _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_memory_stores_delete_memory_request( # pylint: disable=name-too-long - name: str, memory_id: str, **kwargs: Any +def build_beta_evaluation_taxonomies_get_request( # pylint: disable=name-too-long + name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2852,10 +3165,9 @@ def build_beta_memory_stores_delete_memory_request( # pylint: disable=name-too- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/memory_stores/{name}/items/{memory_id}" + _url = "/evaluationtaxonomies/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2866,10 +3178,12 @@ def build_beta_memory_stores_delete_memory_request( # pylint: disable=name-too- # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluation_taxonomies_list_request( # pylint: disable=name-too-long + *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -2877,7 +3191,29 @@ def build_beta_models_list_versions_request(name: str, **kwargs: Any) -> HttpReq accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models/{name}/versions" + _url = "/evaluationtaxonomies" + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if input_name is not None: + _params["inputName"] = _SERIALIZER.query("input_name", input_name, "str") + if input_type is not None: + _params["inputType"] = _SERIALIZER.query("input_type", input_type, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_evaluation_taxonomies_delete_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/evaluationtaxonomies/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -2887,43 +3223,52 @@ def build_beta_models_list_versions_request(name: str, **kwargs: Any) -> HttpReq # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_models_list_request(**kwargs: Any) -> HttpRequest: +def build_beta_evaluation_taxonomies_create_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models" + _url = "/evaluationtaxonomies/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluation_taxonomies_update_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models/{name}/versions/{version}" + _url = "/evaluationtaxonomies/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -2932,70 +3277,86 @@ def build_beta_models_get_request(name: str, version: str, **kwargs: Any) -> Htt _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluators_list_versions_request( # pylint: disable=name-too-long + name: str, + *, + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, + limit: Optional[int] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/models/{name}/versions/{version}" + _url = "/evaluators/{name}/versions" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if type is not None: + _params["type"] = _SERIALIZER.query("type", type, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + +def build_beta_evaluators_list_request( + *, + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, + limit: Optional[int] = None, + **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models/{name}/versions/{version}" - path_format_arguments = { - "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/evaluators" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if type is not None: + _params["type"] = _SERIALIZER.query("type", type, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_pending_create_version_request( # pylint: disable=name-too-long +def build_beta_evaluators_get_version_request( # pylint: disable=name-too-long name: str, version: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models/{name}/versions/{version}/createAsync" + _url = "/evaluators/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -3007,23 +3368,19 @@ def build_beta_models_pending_create_version_request( # pylint: disable=name-to _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_models_pending_upload_request(name: str, version: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) +def build_beta_evaluators_delete_version_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any +) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/models/{name}/versions/{version}/startPendingUpload" + _url = "/evaluators/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), "version": _SERIALIZER.url("version", version, "str"), @@ -3034,16 +3391,11 @@ def build_beta_models_pending_upload_request(name: str, version: str, **kwargs: # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_models_get_credentials_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_beta_evaluators_create_version_request( # pylint: disable=name-too-long + name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3053,10 +3405,9 @@ def build_beta_models_get_credentials_request( # pylint: disable=name-too-long accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/models/{name}/versions/{version}/credentials" + _url = "/evaluators/{name}/versions" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3072,17 +3423,21 @@ def build_beta_models_get_credentials_request( # pylint: disable=name-too-long return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_red_teams_get_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluators_update_version_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/redTeams/runs/{name}" + _url = "/evaluators/{name}/versions/{version}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3091,31 +3446,46 @@ def build_beta_red_teams_get_request(name: str, **kwargs: Any) -> HttpRequest: _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_red_teams_list_request(**kwargs: Any) -> HttpRequest: +def build_beta_evaluators_pending_upload_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/redTeams/runs" + _url = "/evaluators/{name}/versions/{version}/startPendingUpload" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_red_teams_create_request(**kwargs: Any) -> HttpRequest: +def build_beta_evaluators_get_credentials_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3124,7 +3494,13 @@ def build_beta_red_teams_create_request(**kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/redTeams/runs:run" + _url = "/evaluators/{name}/versions/{version}/credentials" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") @@ -3137,8 +3513,8 @@ def build_beta_red_teams_create_request(**kwargs: Any) -> HttpRequest: return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_routines_create_or_update_request( # pylint: disable=name-too-long - routine_name: str, **kwargs: Any +def build_beta_evaluators_create_generation_job_request( # pylint: disable=name-too-long + *, operation_id: Optional[str] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3148,25 +3524,24 @@ def build_beta_routines_create_or_update_request( # pylint: disable=name-too-lo accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/routines/{routine_name}" - path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/evaluator_generation_jobs" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if operation_id is not None: + _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_routines_get_request(routine_name: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluators_get_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3174,9 +3549,9 @@ def build_beta_routines_get_request(routine_name: str, **kwargs: Any) -> HttpReq accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/routines/{routine_name}" + _url = "/evaluator_generation_jobs/{jobId}" path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3190,59 +3565,12 @@ def build_beta_routines_get_request(routine_name: str, **kwargs: Any) -> HttpReq return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_routines_enable_request(routine_name: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - - # Construct URL - _url = "/routines/{routine_name}:enable" - path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - - -def build_beta_routines_disable_request(routine_name: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - - # Construct URL - _url = "/routines/{routine_name}:disable" - path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - - -def build_beta_routines_list_request( +def build_beta_evaluators_list_generation_jobs_request( # pylint: disable=name-too-long *, limit: Optional[int] = None, - after: Optional[str] = None, order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -3252,15 +3580,17 @@ def build_beta_routines_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/routines" + _url = "/evaluator_generation_jobs" # Construct parameters if limit is not None: _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") if order is not None: _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -3269,14 +3599,19 @@ def build_beta_routines_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_routines_delete_request(routine_name: str, **kwargs: Any) -> HttpRequest: +def build_beta_evaluators_cancel_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/routines/{routine_name}" + _url = "/evaluator_generation_jobs/{jobId}:cancel" path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3284,50 +3619,33 @@ def build_beta_routines_delete_request(routine_name: str, **kwargs: Any) -> Http # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_routines_list_runs_request( - routine_name: str, - *, - filter: Optional[str] = None, - limit: Optional[int] = None, - after: Optional[str] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - **kwargs: Any + +def build_beta_evaluators_delete_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any ) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/routines/{routine_name}/runs" + _url = "/evaluator_generation_jobs/{jobId}" path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if filter is not None: - _params["filter"] = _SERIALIZER.query("filter", filter, "str") - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_routines_dispatch_request(routine_name: str, **kwargs: Any) -> HttpRequest: +def build_beta_insights_generate_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3336,17 +3654,18 @@ def build_beta_routines_dispatch_request(routine_name: str, **kwargs: Any) -> Ht accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/routines/{routine_name}:dispatch_async" - path_format_arguments = { - "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/insights" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if "Repeatability-Request-ID" not in _headers: + _headers["Repeatability-Request-ID"] = str(uuid.uuid4()) + if "Repeatability-First-Sent" not in _headers: + _headers["Repeatability-First-Sent"] = _SERIALIZER.serialize_data( + datetime.datetime.now(datetime.timezone.utc), "rfc-1123" + ) if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -3354,25 +3673,9 @@ def build_beta_routines_dispatch_request(routine_name: str, **kwargs: Any) -> Ht return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_schedules_delete_request(schedule_id: str, **kwargs: Any) -> HttpRequest: - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - # Construct URL - _url = "/schedules/{id}" - path_format_arguments = { - "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) - - -def build_beta_schedules_get_request(schedule_id: str, **kwargs: Any) -> HttpRequest: +def build_beta_insights_get_request( + insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3380,14 +3683,16 @@ def build_beta_schedules_get_request(schedule_id: str, **kwargs: Any) -> HttpReq accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/schedules/{id}" + _url = "/insights/{id}" path_format_arguments = { - "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + "id": _SERIALIZER.url("insight_id", insight_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if include_coordinates is not None: + _params["includeCoordinates"] = _SERIALIZER.query("include_coordinates", include_coordinates, "bool") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -3396,8 +3701,14 @@ def build_beta_schedules_get_request(schedule_id: str, **kwargs: Any) -> HttpReq return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_schedules_list_request( - *, type: Optional[Union[str, _models.ScheduleTaskType]] = None, enabled: Optional[bool] = None, **kwargs: Any +def build_beta_insights_list_request( + *, + type: Optional[Union[str, _models.InsightType]] = None, + eval_id: Optional[str] = None, + run_id: Optional[str] = None, + agent_name: Optional[str] = None, + include_coordinates: Optional[bool] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3406,14 +3717,20 @@ def build_beta_schedules_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/schedules" + _url = "/insights" # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") if type is not None: _params["type"] = _SERIALIZER.query("type", type, "str") - if enabled is not None: - _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") + if eval_id is not None: + _params["evalId"] = _SERIALIZER.query("eval_id", eval_id, "str") + if run_id is not None: + _params["runId"] = _SERIALIZER.query("run_id", run_id, "str") + if agent_name is not None: + _params["agentName"] = _SERIALIZER.query("agent_name", agent_name, "str") + if include_coordinates is not None: + _params["includeCoordinates"] = _SERIALIZER.query("include_coordinates", include_coordinates, "bool") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -3421,9 +3738,7 @@ def build_beta_schedules_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_schedules_create_or_update_request( # pylint: disable=name-too-long - schedule_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_memory_stores_create_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3432,12 +3747,7 @@ def build_beta_schedules_create_or_update_request( # pylint: disable=name-too-l accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/schedules/{id}" - path_format_arguments = { - "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore + _url = "/memory_stores" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") @@ -3447,69 +3757,37 @@ def build_beta_schedules_create_or_update_request( # pylint: disable=name-too-l _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) - - -def build_beta_schedules_get_run_request(schedule_id: str, run_id: str, **kwargs: Any) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - - # Construct URL - _url = "/schedules/{schedule_id}/runs/{run_id}" - path_format_arguments = { - "schedule_id": _SERIALIZER.url("schedule_id", schedule_id, "str"), - "run_id": _SERIALIZER.url("run_id", run_id, "str"), - } - - _url: str = _url.format(**path_format_arguments) # type: ignore - - # Construct parameters - _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_schedules_list_runs_request( - schedule_id: str, - *, - type: Optional[Union[str, _models.ScheduleTaskType]] = None, - enabled: Optional[bool] = None, - **kwargs: Any -) -> HttpRequest: +def build_beta_memory_stores_update_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/schedules/{id}/runs" + _url = "/memory_stores/{name}" path_format_arguments = { - "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if type is not None: - _params["type"] = _SERIALIZER.query("type", type, "str") - if enabled is not None: - _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_get_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_get_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3517,7 +3795,7 @@ def build_beta_skills_get_request(name: str, **kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}" + _url = "/memory_stores/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3533,7 +3811,7 @@ def build_beta_skills_get_request(name: str, **kwargs: Any) -> HttpRequest: return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_list_request( +def build_beta_memory_stores_list_request( *, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, @@ -3548,7 +3826,7 @@ def build_beta_skills_list_request( accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills" + _url = "/memory_stores" # Construct parameters if limit is not None: @@ -3567,16 +3845,15 @@ def build_beta_skills_list_request( return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_update_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_delete_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}" + _url = "/memory_stores/{name}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3587,22 +3864,23 @@ def build_beta_skills_update_request(name: str, **kwargs: Any) -> HttpRequest: _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_delete_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_search_memories_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}" + _url = "/memory_stores/{name}:search_memories" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3613,12 +3891,16 @@ def build_beta_skills_delete_request(name: str, **kwargs: Any) -> HttpRequest: _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_create_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_update_memories_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3627,7 +3909,7 @@ def build_beta_skills_create_request(name: str, **kwargs: Any) -> HttpRequest: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions" + _url = "/memory_stores/{name}:update_memories" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3645,17 +3927,18 @@ def build_beta_skills_create_request(name: str, **kwargs: Any) -> HttpRequest: return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_create_from_files_request( # pylint: disable=name-too-long +def build_beta_memory_stores_delete_scope_request( # pylint: disable=name-too-long name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions" + _url = "/memory_stores/{name}:delete_scope" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3666,28 +3949,25 @@ def build_beta_skills_create_from_files_request( # pylint: disable=name-too-lon _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_list_versions_request( - name: str, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - **kwargs: Any +def build_beta_memory_stores_create_memory_request( # pylint: disable=name-too-long + name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions" + _url = "/memory_stores/{name}/items" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), } @@ -3695,34 +3975,31 @@ def build_beta_skills_list_versions_request( _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_get_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_update_memory_request( # pylint: disable=name-too-long + name: str, memory_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions/{version}" + _url = "/memory_stores/{name}/items/{memory_id}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3731,22 +4008,27 @@ def build_beta_skills_get_version_request(name: str, version: str, **kwargs: Any _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_download_request(name: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_get_memory_request( # pylint: disable=name-too-long + name: str, memory_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/zip") + accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/content" + _url = "/memory_stores/{name}/items/{memory_id}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), + "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3760,34 +4042,55 @@ def build_beta_skills_download_request(name: str, **kwargs: Any) -> HttpRequest: return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_download_version_request( # pylint: disable=name-too-long - name: str, version: str, **kwargs: Any +def build_beta_memory_stores_list_memories_request( # pylint: disable=name-too-long + name: str, + *, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/zip") + accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions/{version}/content" + _url = "/memory_stores/{name}/items:list" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if kind is not None: + _params["kind"] = _SERIALIZER.query("kind", kind, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_skills_delete_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: +def build_beta_memory_stores_delete_memory_request( # pylint: disable=name-too-long + name: str, memory_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3795,10 +4098,10 @@ def build_beta_skills_delete_version_request(name: str, version: str, **kwargs: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/skills/{name}/versions/{version}" + _url = "/memory_stores/{name}/items/{memory_id}" path_format_arguments = { "name": _SERIALIZER.url("name", name, "str"), - "version": _SERIALIZER.url("version", version, "str"), + "memory_id": _SERIALIZER.url("memory_id", memory_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3812,9 +4115,7 @@ def build_beta_skills_delete_version_request(name: str, version: str, **kwargs: return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_datasets_get_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_models_list_versions_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3822,9 +4123,9 @@ def build_beta_datasets_get_generation_job_request( # pylint: disable=name-too- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/data_generation_jobs/{jobId}" + _url = "/models/{name}/versions" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3838,14 +4139,7 @@ def build_beta_datasets_get_generation_job_request( # pylint: disable=name-too- return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_datasets_list_generation_jobs_request( # pylint: disable=name-too-long - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - **kwargs: Any -) -> HttpRequest: +def build_beta_models_list_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3853,17 +4147,9 @@ def build_beta_datasets_list_generation_jobs_request( # pylint: disable=name-to accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/data_generation_jobs" + _url = "/models" # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -3872,45 +4158,40 @@ def build_beta_datasets_list_generation_jobs_request( # pylint: disable=name-to return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_datasets_create_generation_job_request( # pylint: disable=name-too-long - *, operation_id: Optional[str] = None, **kwargs: Any -) -> HttpRequest: +def build_beta_models_get_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/data_generation_jobs" + _url = "/models/{name}/versions/{version}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if operation_id is not None: - _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_datasets_cancel_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) +def build_beta_models_delete_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - accept = _headers.pop("Accept", "application/json") - # Construct URL - _url = "/data_generation_jobs/{jobId}:cancel" + _url = "/models/{name}/versions/{version}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3918,22 +4199,22 @@ def build_beta_datasets_cancel_generation_job_request( # pylint: disable=name-t # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - # Construct headers - _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_datasets_delete_generation_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_models_update_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/data_generation_jobs/{jobId}" + _url = "/models/{name}/versions/{version}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3941,11 +4222,16 @@ def build_beta_datasets_delete_generation_job_request( # pylint: disable=name-t # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_create_optimization_job_request( # pylint: disable=name-too-long - *, operation_id: Optional[str] = None, **kwargs: Any + +def build_beta_models_pending_create_version_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3955,14 +4241,18 @@ def build_beta_agents_create_optimization_job_request( # pylint: disable=name-t accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs" + _url = "/models/{name}/versions/{version}/createAsync" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if operation_id is not None: - _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") if content_type is not None: _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -3970,19 +4260,19 @@ def build_beta_agents_create_optimization_job_request( # pylint: disable=name-t return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_models_pending_upload_request(name: str, version: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs/{jobId}" + _url = "/models/{name}/versions/{version}/startPendingUpload" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3991,54 +4281,44 @@ def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too- _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-too-long - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - after: Optional[str] = None, - before: Optional[str] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - agent_name: Optional[str] = None, - **kwargs: Any +def build_beta_models_get_credentials_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs" + _url = "/models/{name}/versions/{version}/credentials" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if limit is not None: - _params["limit"] = _SERIALIZER.query("limit", limit, "int") - if order is not None: - _params["order"] = _SERIALIZER.query("order", order, "str") - if after is not None: - _params["after"] = _SERIALIZER.query("after", after, "str") - if before is not None: - _params["before"] = _SERIALIZER.query("before", before, "str") - if status is not None: - _params["status"] = _SERIALIZER.query("status", status, "str") - if agent_name is not None: - _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_red_teams_get_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -4046,9 +4326,9 @@ def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-t accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs/{jobId}:cancel" + _url = "/redTeams/runs/{name}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "name": _SERIALIZER.url("name", name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -4059,1745 +4339,1057 @@ def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-t # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_delete_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any -) -> HttpRequest: +def build_beta_red_teams_list_request(**kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) - # Construct URL - _url = "/agent_optimization_jobs/{jobId}" - path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), - } + accept = _headers.pop("Accept", "application/json") - _url: str = _url.format(**path_format_arguments) # type: ignore + # Construct URL + _url = "/redTeams/runs" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -class BetaOperations: # pylint: disable=docstring-missing-param,too-many-instance-attributes - """ - .. warning:: - **DO NOT** instantiate this class directly. - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`beta` attribute. - """ +def build_beta_red_teams_create_request(**kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( - self._client, self._config, self._serialize, self._deserialize - ) - self.evaluation_taxonomies = BetaEvaluationTaxonomiesOperations( - self._client, self._config, self._serialize, self._deserialize - ) - self.evaluators = BetaEvaluatorsOperations(self._client, self._config, self._serialize, self._deserialize) - self.insights = BetaInsightsOperations(self._client, self._config, self._serialize, self._deserialize) - self.memory_stores = BetaMemoryStoresOperations(self._client, self._config, self._serialize, self._deserialize) - self.models = BetaModelsOperations(self._client, self._config, self._serialize, self._deserialize) - self.red_teams = BetaRedTeamsOperations(self._client, self._config, self._serialize, self._deserialize) - self.routines = BetaRoutinesOperations(self._client, self._config, self._serialize, self._deserialize) - self.schedules = BetaSchedulesOperations(self._client, self._config, self._serialize, self._deserialize) - self.skills = BetaSkillsOperations(self._client, self._config, self._serialize, self._deserialize) - self.datasets = BetaDatasetsOperations(self._client, self._config, self._serialize, self._deserialize) - self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + # Construct URL + _url = "/redTeams/runs:run" + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") -class AgentsOperations: # pylint: disable=docstring-missing-param,too-many-public-methods - """ - .. warning:: - **DO NOT** instantiate this class directly. + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`agents` attribute. - """ + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def get(self, agent_name: str, **kwargs: Any) -> _models.AgentDetails: - """Get an agent. +def build_beta_routines_create_or_update_request( # pylint: disable=name-too-long + routine_name: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Retrieves an agent definition by its unique name. + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct URL + _url = "/routines/{routine_name}" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + _url: str = _url.format(**path_format_arguments) # type: ignore - cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _request = build_agents_get_request( - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) - response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) +def build_beta_routines_get_request(routine_name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentDetails, response.json()) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct URL + _url = "/routines/{routine_name}" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - return deserialized # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - @distributed_trace - def delete(self, agent_name: str, *, force: Optional[bool] = None, **kwargs: Any) -> _models.DeleteAgentResponse: - """Delete an agent. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Deletes an agent. For hosted agents, if any version has active sessions, the request is - rejected with HTTP 409 unless ``force`` is set to true. When force is true, all associated - sessions are cascade-deleted along with the agent and its versions. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to delete. Required. - :type agent_name: str - :keyword force: For Hosted Agents, if ``true``, force-deletes the agent even if its versions - have active sessions, cascading deletion to all associated sessions. The service defaults to - ``false`` if a value is not specified by the caller. This value is not relevant for other Agent - types. Default value is None. - :paramtype force: bool - :return: DeleteAgentResponse. The DeleteAgentResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteAgentResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteAgentResponse] = kwargs.pop("cls", None) +def build_beta_routines_enable_request(routine_name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _request = build_agents_delete_request( - agent_name=agent_name, - force=force, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct URL + _url = "/routines/{routine_name}:enable" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - response = pipeline_response.http_response + _url: str = _url.format(**path_format_arguments) # type: ignore - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DeleteAgentResponse, response.json()) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - kind: Optional[Union[str, _models.AgentKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.AgentDetails"]: - """List agents. +def build_beta_routines_disable_request(routine_name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Returns a paged collection of agent resources. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values - are: "prompt", "hosted", "workflow", and "external". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.AgentKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of AgentDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentDetails] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + # Construct URL + _url = "/routines/{routine_name}:disable" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - cls: ClsType[List[_models.AgentDetails]] = kwargs.pop("cls", None) + _url: str = _url.format(**path_format_arguments) # type: ignore - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - def prepare_request(_continuation_token=None): + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _request = build_agents_list_request( - kind=kind, - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) +def build_beta_routines_list_request( + *, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct URL + _url = "/routines" - return pipeline_response + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return ItemPaged(get_next, extract_data) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - @overload - def create_version( - self, - agent_name: str, - *, - definition: _models.AgentDefinition, - content_type: str = "application/json", - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - blueprint_reference: Optional[_models.AgentBlueprintReference] = None, - digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, - draft: Optional[bool] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - Creates a new version for the specified agent and returns the created version resource. - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. +def build_beta_routines_delete_request(routine_name: str, **kwargs: Any) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or - voice agent definition. Required. - :paramtype definition: ~azure.ai.projects.models.AgentDefinition - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/routines/{routine_name}" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. - :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference - :keyword digital_worker_type: (Preview) The type of digital worker (previously known as - ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. - :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType - :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a - release. The service defaults to ``false`` if a value is not specified by the caller. Draft - versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. - Default value is None. - :paramtype draft: bool - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + _url: str = _url.format(**path_format_arguments) # type: ignore - @overload - def create_version( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Creates a new version for the specified agent and returns the created version resource. + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ +def build_beta_routines_list_runs_request( + routine_name: str, + *, + filter: Optional[str] = None, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - @overload - def create_version( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - Creates a new version for the specified agent and returns the created version resource. + # Construct URL + _url = "/routines/{routine_name}/runs" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + _url: str = _url.format(**path_format_arguments) # type: ignore - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + # Construct parameters + if filter is not None: + _params["filter"] = _SERIALIZER.query("filter", filter, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - @distributed_trace - def create_version( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - definition: _models.AgentDefinition = _Unset, - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - blueprint_reference: Optional[_models.AgentBlueprintReference] = None, - digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, - draft: Optional[bool] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - Creates a new version for the specified agent and returns the created version resource. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or - voice agent definition. Required. - :paramtype definition: ~azure.ai.projects.models.AgentDefinition - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. +def build_beta_routines_dispatch_request(routine_name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. - :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference - :keyword digital_worker_type: (Preview) The type of digital worker (previously known as - ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. - :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType - :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a - release. The service defaults to ``false`` if a value is not specified by the caller. Draft - versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. - Default value is None. - :paramtype draft: bool - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + # Construct URL + _url = "/routines/{routine_name}:dispatch_async" + path_format_arguments = { + "routine_name": _SERIALIZER.url("routine_name", routine_name, "str"), + } - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + _url: str = _url.format(**path_format_arguments) # type: ignore - if body is _Unset: - if definition is _Unset: - raise TypeError("missing required argument: definition") - body = { - "blueprint_reference": blueprint_reference, - "definition": definition, - "description": description, - "digital_worker_type": digital_worker_type, - "draft": draft, - "metadata": metadata, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _request = build_agents_create_version_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) +def build_beta_schedules_delete_request(schedule_id: str, **kwargs: Any) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/schedules/{id}" + path_format_arguments = { + "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + } - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - return deserialized # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - @overload - def create_version_from_manifest( - self, - agent_name: str, - *, - manifest_id: str, - parameter_values: dict[str, Any], - content_type: str = "application/json", - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) - Imports the provided manifest to create a new version for the specified agent. - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. +def build_beta_schedules_get_request(schedule_id: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :keyword manifest_id: The manifest ID to import the agent version from. Required. - :paramtype manifest_id: str - :keyword parameter_values: The inputs to the manifest that will result in a fully materialized - Agent. Required. - :paramtype parameter_values: dict[str, any] - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + # Construct URL + _url = "/schedules/{id}" + path_format_arguments = { + "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + } - @overload - def create_version_from_manifest( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. + _url: str = _url.format(**path_format_arguments) # type: ignore - Imports the provided manifest to create a new version for the specified agent. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - @overload - def create_version_from_manifest( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. - Imports the provided manifest to create a new version for the specified agent. +def build_beta_schedules_list_request( + *, type: Optional[Union[str, _models.ScheduleTaskType]] = None, enabled: Optional[bool] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + # Construct URL + _url = "/schedules" - @distributed_trace - def create_version_from_manifest( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - manifest_id: str = _Unset, - parameter_values: dict[str, Any] = _Unset, - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if type is not None: + _params["type"] = _SERIALIZER.query("type", type, "str") + if enabled is not None: + _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") - Imports the provided manifest to create a new version for the specified agent. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword manifest_id: The manifest ID to import the agent version from. Required. - :paramtype manifest_id: str - :keyword parameter_values: The inputs to the manifest that will result in a fully materialized - Agent. Required. - :paramtype parameter_values: dict[str, any] - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) +def build_beta_schedules_create_or_update_request( # pylint: disable=name-too-long + schedule_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + # Construct URL + _url = "/schedules/{id}" + path_format_arguments = { + "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + } - if body is _Unset: - if manifest_id is _Unset: - raise TypeError("missing required argument: manifest_id") - if parameter_values is _Unset: - raise TypeError("missing required argument: parameter_values") - body = { - "description": description, - "manifest_id": manifest_id, - "metadata": metadata, - "parameter_values": parameter_values, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - _request = build_agents_create_version_from_manifest_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - response = pipeline_response.http_response + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) +def build_beta_schedules_get_run_request(schedule_id: str, run_id: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - return deserialized # type: ignore + # Construct URL + _url = "/schedules/{schedule_id}/runs/{run_id}" + path_format_arguments = { + "schedule_id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + "run_id": _SERIALIZER.url("run_id", run_id, "str"), + } - @distributed_trace - def get_version(self, agent_name: str, agent_version: str, **kwargs: Any) -> _models.AgentVersionDetails: - """Get an agent version. + _url: str = _url.format(**path_format_arguments) # type: ignore - Retrieves the specified version of an agent by its agent name and version identifier. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :param agent_version: The version of the agent to retrieve. Required. - :type agent_version: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) - _request = build_agents_get_version_request( - agent_name=agent_name, - agent_version=agent_version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) +def build_beta_schedules_list_runs_request( + schedule_id: str, + *, + type: Optional[Union[str, _models.ScheduleTaskType]] = None, + enabled: Optional[bool] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - response = pipeline_response.http_response + # Construct URL + _url = "/schedules/{id}/runs" + path_format_arguments = { + "id": _SERIALIZER.url("schedule_id", schedule_id, "str"), + } - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + _url: str = _url.format(**path_format_arguments) # type: ignore - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if type is not None: + _params["type"] = _SERIALIZER.query("type", type, "str") + if enabled is not None: + _params["enabled"] = _SERIALIZER.query("enabled", enabled, "bool") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return deserialized # type: ignore + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - @distributed_trace - def delete_version( - self, agent_name: str, agent_version: str, *, force: Optional[bool] = None, **kwargs: Any - ) -> _models.DeleteAgentVersionResponse: - """Delete an agent version. - Deletes a specific version of an agent. For hosted agents, if the version has active sessions, - the request is rejected with HTTP 409 unless ``force`` is set to true. When force is true, all - sessions associated with this version are cascade-deleted. +def build_beta_skills_get_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The name of the agent to delete. Required. - :type agent_name: str - :param agent_version: The version of the agent to delete. Required. - :type agent_version: str - :keyword force: For Hosted Agents, if ``true``, force-deletes the version even if it has active - sessions, cascading deletion to all associated sessions. The service defaults to ``false`` if a - value is not specified by the caller. This value is not relevant for other Agent types. Default - value is None. - :paramtype force: bool - :return: DeleteAgentVersionResponse. The DeleteAgentVersionResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.DeleteAgentVersionResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + # Construct URL + _url = "/skills/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - cls: ClsType[_models.DeleteAgentVersionResponse] = kwargs.pop("cls", None) + _url: str = _url.format(**path_format_arguments) # type: ignore - _request = build_agents_delete_version_request( - agent_name=agent_name, - agent_version=agent_version, - force=force, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - response = pipeline_response.http_response + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DeleteAgentVersionResponse, response.json()) +def build_beta_skills_list_request( + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - return deserialized # type: ignore + # Construct URL + _url = "/skills" - @distributed_trace - def list_versions( - self, - agent_name: str, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - include_drafts: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.AgentVersionDetails"]: - """List agent versions. + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Returns a paged collection of versions for the specified agent. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to retrieve versions for. Required. - :type agent_name: str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword include_drafts: (Preview) Whether to include draft versions in the listing. The - service defaults to ``false`` if a value is not specified by the caller (only non-draft - versions are returned). Default value is None. - :paramtype include_drafts: bool - :return: An iterator like instance of AgentVersionDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentVersionDetails] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - cls: ClsType[List[_models.AgentVersionDetails]] = kwargs.pop("cls", None) - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) +def build_beta_skills_update_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - def prepare_request(_continuation_token=None): + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _request = build_agents_list_versions_request( - agent_name=agent_name, - limit=limit, - order=order, - after=_continuation_token, - before=before, - include_drafts=include_drafts, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + # Construct URL + _url = "/skills/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentVersionDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + _url: str = _url.format(**path_format_arguments) # type: ignore - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - return pipeline_response - return ItemPaged(get_next, extract_data) +def build_beta_skills_delete_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - @overload - def update_details( - self, - agent_name: str, - *, - content_type: str = "application/merge-patch+json", - agent_endpoint: Optional[_models.AgentEndpointConfig] = None, - agent_card: Optional[_models.AgentCard] = None, - **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - Applies a merge-patch update to the specified agent endpoint configuration. + # Construct URL + _url = "/skills/{name}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. - :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig - :keyword agent_card: Optional agent card for the agent. Default value is None. - :paramtype agent_card: ~azure.ai.projects.models.AgentCard - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + _url: str = _url.format(**path_format_arguments) # type: ignore - @overload - def update_details( - self, agent_name: str, body: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Applies a merge-patch update to the specified agent endpoint configuration. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) - @overload - def update_details( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. - - Applies a merge-patch update to the specified agent endpoint configuration. - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ +def build_beta_skills_create_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - @distributed_trace - def update_details( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - agent_endpoint: Optional[_models.AgentEndpointConfig] = None, - agent_card: Optional[_models.AgentCard] = None, - **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - Applies a merge-patch update to the specified agent endpoint configuration. + # Construct URL + _url = "/skills/{name}/versions" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. - :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig - :keyword agent_card: Optional agent card for the agent. Default value is None. - :paramtype agent_card: ~azure.ai.projects.models.AgentCard - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + _url: str = _url.format(**path_format_arguments) # type: ignore - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - if body is _Unset: - body = {"agent_card": agent_card, "agent_endpoint": agent_endpoint} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - _request = build_agents_update_details_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) +def build_beta_skills_create_from_files_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - response = pipeline_response.http_response + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct URL + _url = "/skills/{name}/versions" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentDetails, response.json()) + _url: str = _url.format(**path_format_arguments) # type: ignore - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return deserialized # type: ignore + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - @overload - def _create_version_from_code( - self, - agent_name: str, - content: _models._models._CreateAgentVersionFromCodeContent, - *, - code_zip_sha256: str, - **kwargs: Any - ) -> _models.AgentVersionDetails: ... - @overload - def _create_version_from_code( - self, agent_name: str, content: JSON, *, code_zip_sha256: str, **kwargs: Any - ) -> _models.AgentVersionDetails: ... + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - @distributed_trace - def _create_version_from_code( - self, - agent_name: str, - content: Union[_models._models._CreateAgentVersionFromCodeContent, JSON], - *, - code_zip_sha256: str, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from code. - Creates a new agent version from code. Uploads the code zip and creates a new version for an - existing agent. The SHA-256 hex digest of the zip is provided in the ``x-ms-code-zip-sha256`` - header for integrity and dedup. The request body is multipart/form-data with a JSON metadata - part and a binary code part (part order is irrelevant). Maximum upload size is 250 MB. +def build_beta_skills_list_versions_request( + name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param content: The content multipart request content. Is either a - _CreateAgentVersionFromCodeContent type or a JSON type. Required. - :type content: ~azure.ai.projects.models._models._CreateAgentVersionFromCodeContent or JSON - :keyword code_zip_sha256: SHA-256 hex digest of the uploaded code zip. Used for change - detection (dedup) and integrity verification. Required. - :paramtype code_zip_sha256: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct URL + _url = "/skills/{name}/versions" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + _url: str = _url.format(**path_format_arguments) # type: ignore - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _body = content.as_dict() if isinstance(content, _Model) else content - _file_fields: list[str] = ["code"] - _data_fields: list[str] = ["metadata"] - _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _request = build_agents_create_version_from_code_request( - agent_name=agent_name, - code_zip_sha256=code_zip_sha256, - api_version=self._config.api_version, - files=_files, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response +def build_beta_skills_get_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + # Construct URL + _url = "/skills/{name}/versions/{version}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - return deserialized # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - @distributed_trace - def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, **kwargs: Any) -> Iterator[bytes]: - """Download agent code. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - Downloads the code zip for a code-based hosted agent. - Returns the previously-uploaded zip (``application/zip``). + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - If ``agent_version`` is supplied, returns that version's code zip; otherwise - returns the latest version's code zip. - The SHA-256 digest of the returned bytes matches the ``content_hash`` on the - resolved version's ``code_configuration``. +def build_beta_skills_download_request(name: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The name of the agent. Required. - :type agent_name: str - :keyword agent_version: The version of the agent whose code zip should be downloaded. - If omitted, the latest version's code zip is returned. Default value is None. - :paramtype agent_version: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/zip") - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + # Construct URL + _url = "/skills/{name}/content" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + _url: str = _url.format(**path_format_arguments) # type: ignore - _request = build_agents_download_code_request( - agent_name=agent_name, - agent_version=agent_version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - response = pipeline_response.http_response + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["x-ms-agent-version"] = self._deserialize("str", response.headers.get("x-ms-agent-version")) - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) +def build_beta_skills_download_version_request( # pylint: disable=name-too-long + name: str, version: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/zip") - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + # Construct URL + _url = "/skills/{name}/versions/{version}/content" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } - return deserialized # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - @distributed_trace - def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Enable an agent. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Enables the specified agent, allowing it to accept new sessions and process requests. This - operation is idempotent — enabling an already-enabled agent returns success with no side - effects. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to enable. Required. - :type agent_name: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) +def build_beta_skills_delete_version_request(name: str, version: str, **kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _request = build_agents_enable_request( - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct URL + _url = "/skills/{name}/versions/{version}" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + "version": _SERIALIZER.url("version", version, "str"), + } - response = pipeline_response.http_response + _url: str = _url.format(**path_format_arguments) # type: ignore - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if cls: - return cls(pipeline_response, None, {}) # type: ignore + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - @distributed_trace - def disable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Disable an agent. + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) - Disables the specified agent, preventing it from accepting new sessions or processing requests. - Existing active sessions are allowed to drain gracefully but no new sessions can be created. - This operation is idempotent — disabling an already-disabled agent returns success with no side - effects. - :param agent_name: The name of the agent to disable. Required. - :type agent_name: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) +def build_beta_datasets_get_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - cls: ClsType[None] = kwargs.pop("cls", None) + # Construct URL + _url = "/data_generation_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } - _request = build_agents_disable_request( - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _url: str = _url.format(**path_format_arguments) # type: ignore - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - response = pipeline_response.http_response + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - if cls: - return cls(pipeline_response, None, {}) # type: ignore - @overload - def create_session( - self, - agent_name: str, - *, - version_indicator: _models.VersionIndicator, - content_type: str = "application/json", - agent_session_id: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. +def build_beta_datasets_list_generation_jobs_request( # pylint: disable=name-too-long + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :param agent_name: The name of the agent to create a session for. Required. - :type agent_name: str - :keyword version_indicator: Determines which agent version backs the session. Required. - :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique - within the agent endpoint. Auto-generated if omitted. Default value is None. - :paramtype agent_session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource - :raises ~azure.core.exceptions.HttpResponseError: - """ + # Construct URL + _url = "/data_generation_jobs" - @overload - def create_session( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to create a session for. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource - :raises ~azure.core.exceptions.HttpResponseError: - """ + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - @overload - def create_session( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. +def build_beta_datasets_create_generation_job_request( # pylint: disable=name-too-long + *, operation_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The name of the agent to create a session for. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource - :raises ~azure.core.exceptions.HttpResponseError: - """ + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - @distributed_trace - def create_session( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - version_indicator: _models.VersionIndicator = _Unset, - agent_session_id: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + # Construct URL + _url = "/data_generation_jobs" - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - :param agent_name: The name of the agent to create a session for. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword version_indicator: Determines which agent version backs the session. Required. - :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator - :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique - within the agent endpoint. Auto-generated if omitted. Default value is None. - :paramtype agent_session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct headers + if operation_id is not None: + _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) - if body is _Unset: - if version_indicator is _Unset: - raise TypeError("missing required argument: version_indicator") - body = {"agent_session_id": agent_session_id, "version_indicator": version_indicator} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore +def build_beta_datasets_cancel_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _request = build_agents_create_session_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct URL + _url = "/data_generation_jobs/{jobId}:cancel" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } - response = pipeline_response.http_response + _url: str = _url.format(**path_format_arguments) # type: ignore - if response.status_code not in [201]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentSessionResource, response.json()) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - return deserialized # type: ignore - @distributed_trace - def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _models.AgentSessionResource: - """Get a session. +def build_beta_datasets_delete_generation_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Retrieves the details of a hosted agent session by agent name and session identifier. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/data_generation_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + _url: str = _url.format(**path_format_arguments) # type: ignore - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) - _request = build_agents_get_session_request( - agent_name=agent_name, - session_id=session_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) +def build_beta_agents_create_optimization_job_request( # pylint: disable=name-too-long + *, operation_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - response = pipeline_response.http_response + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct URL + _url = "/agent_optimization_jobs" - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentSessionResource, response.json()) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct headers + if operation_id is not None: + _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return deserialized # type: ignore + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-too-long + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + agent_name: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs" + + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if agent_name is not None: + _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs/{jobId}:cancel" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_delete_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agent_optimization_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + + +class BetaOperations: # pylint: disable=docstring-missing-param,too-many-instance-attributes + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`beta` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.evaluation_taxonomies = BetaEvaluationTaxonomiesOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.evaluators = BetaEvaluatorsOperations(self._client, self._config, self._serialize, self._deserialize) + self.insights = BetaInsightsOperations(self._client, self._config, self._serialize, self._deserialize) + self.memory_stores = BetaMemoryStoresOperations(self._client, self._config, self._serialize, self._deserialize) + self.models = BetaModelsOperations(self._client, self._config, self._serialize, self._deserialize) + self.red_teams = BetaRedTeamsOperations(self._client, self._config, self._serialize, self._deserialize) + self.routines = BetaRoutinesOperations(self._client, self._config, self._serialize, self._deserialize) + self.schedules = BetaSchedulesOperations(self._client, self._config, self._serialize, self._deserialize) + self.skills = BetaSkillsOperations(self._client, self._config, self._serialize, self._deserialize) + self.datasets = BetaDatasetsOperations(self._client, self._config, self._serialize, self._deserialize) + self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + + +class AgentsOperations: # pylint: disable=docstring-missing-param,too-many-public-methods + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`agents` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace - def delete_session( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, **kwargs: Any - ) -> None: - """Delete a session. + def get(self, agent_name: str, **kwargs: Any) -> _models.AgentDetails: + """Get an agent. - Deletes a session synchronously. Returns 204 No Content when the session is deleted or does not - exist. + Retrieves an agent definition by its unique name. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str - :return: None - :rtype: None + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5811,11 +5403,10 @@ def delete_session( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) - _request = build_agents_delete_session_request( + _request = build_agents_get_request( agent_name=agent_name, - session_id=session_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5825,14 +5416,20 @@ def delete_session( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -5840,24 +5437,107 @@ def delete_session( # pylint: disable=inconsistent-return-statements ) raise HttpResponseError(response=response, model=error) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentDetails, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def stop_session( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, **kwargs: Any - ) -> None: - """Stop a session. + def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: + """Generate an agent. - Terminates the specified hosted agent session and returns 204 No Content when the request - succeeds. + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str - :return: None - :rtype: None + :param body: The kind-specific inputs for generating and creating an agent. Is one of the + following types: GenerateVoiceAgentRequest Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_generate_agent_request( + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, agent_name: str, *, force: Optional[bool] = None, **kwargs: Any) -> _models.DeleteAgentResponse: + """Delete an agent. + + Deletes an agent. For hosted agents, if any version has active sessions, the request is + rejected with HTTP 409 unless ``force`` is set to true. When force is true, all associated + sessions are cascade-deleted along with the agent and its versions. + + :param agent_name: The name of the agent to delete. Required. + :type agent_name: str + :keyword force: For Hosted Agents, if ``true``, force-deletes the agent even if its versions + have active sessions, cascading deletion to all associated sessions. The service defaults to + ``false`` if a value is not specified by the caller. This value is not relevant for other Agent + types. Default value is None. + :paramtype force: bool + :return: DeleteAgentResponse. The DeleteAgentResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteAgentResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5871,11 +5551,11 @@ def stop_session( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.DeleteAgentResponse] = kwargs.pop("cls", None) - _request = build_agents_stop_session_request( + _request = build_agents_delete_request( agent_name=agent_name, - session_id=session_id, + force=force, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5885,14 +5565,20 @@ def stop_session( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -5900,25 +5586,33 @@ def stop_session( # pylint: disable=inconsistent-return-statements ) raise HttpResponseError(response=response, model=error) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteAgentResponse, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def list_sessions( + def list( self, - agent_name: str, *, + kind: Optional[Union[str, _models.AgentKind]] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.AgentSessionResource"]: - """List sessions for an agent. + ) -> ItemPaged["_models.AgentDetails"]: + """List agents. - Returns a paged collection of sessions associated with the specified agent endpoint. + Returns a paged collection of agent resources. - :param agent_name: The name of the agent. Required. - :type agent_name: str + :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values + are: "prompt", "hosted", "workflow", "external", and "voice". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.AgentKind :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -5933,14 +5627,14 @@ def list_sessions( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of AgentSessionResource - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentSessionResource] + :return: An iterator like instance of AgentDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentDetails] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentSessionResource]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.AgentDetails]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -5952,8 +5646,8 @@ def list_sessions( def prepare_request(_continuation_token=None): - _request = build_agents_list_sessions_request( - agent_name=agent_name, + _request = build_agents_list_request( + kind=kind, limit=limit, order=order, after=_continuation_token, @@ -5971,7 +5665,7 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.AgentSessionResource], + List[_models.AgentDetails], deserialized.get("data", []), ) if cls: @@ -5999,69 +5693,204 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) - @distributed_trace - def get_session_log_stream( - self, agent_name: str, agent_version: str, session_id: str, **kwargs: Any - ) -> _models.SessionLogEvent: - """Stream console logs for a hosted agent session. - - Streams console logs (stdout / stderr) for a specific hosted agent session - as a Server-Sent Events (SSE) stream. - - Each SSE frame contains: - - * `event`: always `"log"` - * `data`: a plain-text log line (currently JSON-formatted, but the schema is not contractual and may include additional keys or change format over time; clients should treat it as an opaque string) + @overload + def create_version( + self, + agent_name: str, + *, + definition: _models.AgentDefinition, + content_type: str = "application/json", + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[_models.AgentBlueprintReference] = None, + digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, + draft: Optional[bool] = None, + **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. - Example SSE frames: + Creates a new version for the specified agent and returns the created version resource. - .. code-block:: + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. - event: log - data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting FoundryCBAgent server on port 8088"} + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or + voice agent definition. Required. + :paramtype definition: ~azure.ai.projects.models.AgentDefinition + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. - event: log - data: {"timestamp":"2026-03-10T09:33:17.130Z","stream":"stderr","message":"INFO: Application startup complete."} + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. + :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference + :keyword digital_worker_type: (Preview) The type of digital worker (previously known as + ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. + :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType + :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a + release. The service defaults to ``false`` if a value is not specified by the caller. Draft + versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. + Default value is None. + :paramtype draft: bool + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ - event: log - data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + @overload + def create_version( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. - event: log - data: {"timestamp":"2026-03-10T09:35:52.714Z","stream":"status","message":"No logs since last 60 seconds"} + Creates a new version for the specified agent and returns the created version resource. - The stream remains open until the client disconnects or the server - terminates the connection. Clients should handle reconnection as needed. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. - :param agent_name: The name of the hosted agent. Required. + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str - :param agent_version: The version of the agent. Required. - :type agent_version: str - :param session_id: The session ID (maps to an ADC sandbox). Required. - :type session_id: str - :return: SessionLogEvent. The SessionLogEvent is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionLogEvent + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + @overload + def create_version( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. - cls: ClsType[_models.SessionLogEvent] = kwargs.pop("cls", None) + Creates a new version for the specified agent and returns the created version resource. - _request = build_agents_get_session_log_stream_request( - agent_name=agent_name, - agent_version=agent_version, - session_id=session_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_version( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + definition: _models.AgentDefinition = _Unset, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[_models.AgentBlueprintReference] = None, + digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, + draft: Optional[bool] = None, + **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. + + Creates a new version for the specified agent and returns the created version resource. + + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or + voice agent definition. Required. + :paramtype definition: ~azure.ai.projects.models.AgentDefinition + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. + :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference + :keyword digital_worker_type: (Preview) The type of digital worker (previously known as + ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. + :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType + :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a + release. The service defaults to ``false`` if a value is not specified by the caller. Draft + versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. + Default value is None. + :paramtype draft: bool + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + + if body is _Unset: + if definition is _Unset: + raise TypeError("missing required argument: definition") + body = { + "blueprint_reference": blueprint_reference, + "definition": definition, + "description": description, + "digital_worker_type": digital_worker_type, + "draft": draft, + "metadata": metadata, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_create_version_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, ) path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), @@ -6069,7 +5898,7 @@ def get_session_log_stream( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -6089,285 +5918,5768 @@ def get_session_log_stream( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SessionLogEvent, response.text()) + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def publish_to_microsoft365( + def create_version_from_manifest( self, agent_name: str, *, - publish_scope: Union[str, _models.Microsoft365PublishScope], + manifest_id: str, + parameter_values: dict[str, Any], content_type: str = "application/json", - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Imports the provided manifest to create a new version for the specified agent. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword manifest_id: The manifest ID to import the agent version from. Required. + :paramtype manifest_id: str + :keyword parameter_values: The inputs to the manifest that will result in a fully materialized + Agent. Required. + :paramtype parameter_values: dict[str, any] :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. - Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def publish_to_microsoft365( + def create_version_from_manifest( self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Imports the provided manifest to create a new version for the specified agent. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def publish_to_microsoft365( + def create_version_from_manifest( self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Imports the provided manifest to create a new version for the specified agent. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def publish_to_microsoft365( # pylint: disable=too-many-locals + def create_version_from_manifest( self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, + manifest_id: str = _Unset, + parameter_values: dict[str, Any] = _Unset, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Imports the provided manifest to create a new version for the specified agent. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. - Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :keyword manifest_id: The manifest ID to import the agent version from. Required. + :paramtype manifest_id: str + :keyword parameter_values: The inputs to the manifest that will result in a fully materialized + Agent. Required. + :paramtype parameter_values: dict[str, any] + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + + if body is _Unset: + if manifest_id is _Unset: + raise TypeError("missing required argument: manifest_id") + if parameter_values is _Unset: + raise TypeError("missing required argument: parameter_values") + body = { + "description": description, + "manifest_id": manifest_id, + "metadata": metadata, + "parameter_values": parameter_values, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_create_version_from_manifest_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_version(self, agent_name: str, agent_version: str, **kwargs: Any) -> _models.AgentVersionDetails: + """Get an agent version. + + Retrieves the specified version of an agent by its agent name and version identifier. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :param agent_version: The version of the agent to retrieve. Required. + :type agent_version: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + + _request = build_agents_get_version_request( + agent_name=agent_name, + agent_version=agent_version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete_version( + self, agent_name: str, agent_version: str, *, force: Optional[bool] = None, **kwargs: Any + ) -> _models.DeleteAgentVersionResponse: + """Delete an agent version. + + Deletes a specific version of an agent. For hosted agents, if the version has active sessions, + the request is rejected with HTTP 409 unless ``force`` is set to true. When force is true, all + sessions associated with this version are cascade-deleted. + + :param agent_name: The name of the agent to delete. Required. + :type agent_name: str + :param agent_version: The version of the agent to delete. Required. + :type agent_version: str + :keyword force: For Hosted Agents, if ``true``, force-deletes the version even if it has active + sessions, cascading deletion to all associated sessions. The service defaults to ``false`` if a + value is not specified by the caller. This value is not relevant for other Agent types. Default + value is None. + :paramtype force: bool + :return: DeleteAgentVersionResponse. The DeleteAgentVersionResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.DeleteAgentVersionResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DeleteAgentVersionResponse] = kwargs.pop("cls", None) + + _request = build_agents_delete_version_request( + agent_name=agent_name, + agent_version=agent_version, + force=force, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteAgentVersionResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_versions( + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + include_drafts: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentVersionDetails"]: + """List agent versions. + + Returns a paged collection of versions for the specified agent. + + :param agent_name: The name of the agent to retrieve versions for. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword include_drafts: (Preview) Whether to include draft versions in the listing. The + service defaults to ``false`` if a value is not specified by the caller (only non-draft + versions are returned). Default value is None. + :paramtype include_drafts: bool + :return: An iterator like instance of AgentVersionDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentVersionDetails] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentVersionDetails]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_versions_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + include_drafts=include_drafts, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentVersionDetails], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @overload + def update_details( + self, + agent_name: str, + *, + content_type: str = "application/merge-patch+json", + agent_endpoint: Optional[_models.AgentEndpointConfig] = None, + agent_card: Optional[_models.AgentCard] = None, + **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. + + Applies a merge-patch update to the specified agent endpoint configuration. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. + :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig + :keyword agent_card: Optional agent card for the agent. Default value is None. + :paramtype agent_card: ~azure.ai.projects.models.AgentCard + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_details( + self, agent_name: str, body: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. + + Applies a merge-patch update to the specified agent endpoint configuration. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_details( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. + + Applies a merge-patch update to the specified agent endpoint configuration. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def update_details( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + agent_endpoint: Optional[_models.AgentEndpointConfig] = None, + agent_card: Optional[_models.AgentCard] = None, + **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. + + Applies a merge-patch update to the specified agent endpoint configuration. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. + :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig + :keyword agent_card: Optional agent card for the agent. Default value is None. + :paramtype agent_card: ~azure.ai.projects.models.AgentCard + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + + if body is _Unset: + body = {"agent_card": agent_card, "agent_endpoint": agent_endpoint} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_update_details_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def _create_version_from_code( + self, + agent_name: str, + content: _models._models._CreateAgentVersionFromCodeContent, + *, + code_zip_sha256: str, + **kwargs: Any + ) -> _models.AgentVersionDetails: ... + @overload + def _create_version_from_code( + self, agent_name: str, content: JSON, *, code_zip_sha256: str, **kwargs: Any + ) -> _models.AgentVersionDetails: ... + + @distributed_trace + def _create_version_from_code( + self, + agent_name: str, + content: Union[_models._models._CreateAgentVersionFromCodeContent, JSON], + *, + code_zip_sha256: str, + **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version from code. + + Creates a new agent version from code. Uploads the code zip and creates a new version for an + existing agent. The SHA-256 hex digest of the zip is provided in the ``x-ms-code-zip-sha256`` + header for integrity and dedup. The request body is multipart/form-data with a JSON metadata + part and a binary code part (part order is irrelevant). Maximum upload size is 250 MB. + + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :param content: The content multipart request content. Is either a + _CreateAgentVersionFromCodeContent type or a JSON type. Required. + :type content: ~azure.ai.projects.models._models._CreateAgentVersionFromCodeContent or JSON + :keyword code_zip_sha256: SHA-256 hex digest of the uploaded code zip. Used for change + detection (dedup) and integrity verification. Required. + :paramtype code_zip_sha256: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + + _body = content.as_dict() if isinstance(content, _Model) else content + _file_fields: list[str] = ["code"] + _data_fields: list[str] = ["metadata"] + _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + + _request = build_agents_create_version_from_code_request( + agent_name=agent_name, + code_zip_sha256=code_zip_sha256, + api_version=self._config.api_version, + files=_files, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, **kwargs: Any) -> Iterator[bytes]: + """Download agent code. + + Downloads the code zip for a code-based hosted agent. + Returns the previously-uploaded zip (``application/zip``). + + If ``agent_version`` is supplied, returns that version's code zip; otherwise + returns the latest version's code zip. + + The SHA-256 digest of the returned bytes matches the ``content_hash`` on the + resolved version's ``code_configuration``. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword agent_version: The version of the agent whose code zip should be downloaded. + If omitted, the latest version's code zip is returned. Default value is None. + :paramtype agent_version: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agents_download_code_request( + agent_name=agent_name, + agent_version=agent_version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["x-ms-agent-version"] = self._deserialize("str", response.headers.get("x-ms-agent-version")) + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Enable an agent. + + Enables the specified agent, allowing it to accept new sessions and process requests. This + operation is idempotent — enabling an already-enabled agent returns success with no side + effects. + + :param agent_name: The name of the agent to enable. Required. + :type agent_name: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_enable_request( + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def disable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Disable an agent. + + Disables the specified agent, preventing it from accepting new sessions or processing requests. + Existing active sessions are allowed to drain gracefully but no new sessions can be created. + This operation is idempotent — disabling an already-disabled agent returns success with no side + effects. + + :param agent_name: The name of the agent to disable. Required. + :type agent_name: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_disable_request( + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_session( + self, + agent_name: str, + *, + version_indicator: _models.VersionIndicator, + content_type: str = "application/json", + agent_session_id: Optional[str] = None, + **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :keyword version_indicator: Determines which agent version backs the session. Required. + :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique + within the agent endpoint. Auto-generated if omitted. Default value is None. + :paramtype agent_session_id: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_session( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_session( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_session( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + version_indicator: _models.VersionIndicator = _Unset, + agent_session_id: Optional[str] = None, + **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword version_indicator: Determines which agent version backs the session. Required. + :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator + :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique + within the agent endpoint. Auto-generated if omitted. Default value is None. + :paramtype agent_session_id: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) + + if body is _Unset: + if version_indicator is _Unset: + raise TypeError("missing required argument: version_indicator") + body = {"agent_session_id": agent_session_id, "version_indicator": version_indicator} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_create_session_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentSessionResource, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _models.AgentSessionResource: + """Get a session. + + Retrieves the details of a hosted agent session by agent name and session identifier. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session identifier. Required. + :type session_id: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) + + _request = build_agents_get_session_request( + agent_name=agent_name, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentSessionResource, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete_session( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, **kwargs: Any + ) -> None: + """Delete a session. + + Deletes a session synchronously. Returns 204 No Content when the session is deleted or does not + exist. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session identifier. Required. + :type session_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_delete_session_request( + agent_name=agent_name, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def stop_session( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, **kwargs: Any + ) -> None: + """Stop a session. + + Terminates the specified hosted agent session and returns 204 No Content when the request + succeeds. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session identifier. Required. + :type session_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_stop_session_request( + agent_name=agent_name, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_sessions( + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentSessionResource"]: + """List sessions for an agent. + + Returns a paged collection of sessions associated with the specified agent endpoint. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of AgentSessionResource + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentSessionResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentSessionResource]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_sessions_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentSessionResource], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get_session_log_stream( + self, agent_name: str, agent_version: str, session_id: str, **kwargs: Any + ) -> _models.SessionLogEvent: + """Stream console logs for a hosted agent session. + + Streams console logs (stdout / stderr) for a specific hosted agent session + as a Server-Sent Events (SSE) stream. + + Each SSE frame contains: + + * `event`: always `"log"` + * `data`: a plain-text log line (currently JSON-formatted, but the schema is not contractual and may include additional keys or change format over time; clients should treat it as an opaque string) + + Example SSE frames: + + .. code-block:: + + event: log + data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting FoundryCBAgent server on port 8088"} + + event: log + data: {"timestamp":"2026-03-10T09:33:17.130Z","stream":"stderr","message":"INFO: Application startup complete."} + + event: log + data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + + event: log + data: {"timestamp":"2026-03-10T09:35:52.714Z","stream":"status","message":"No logs since last 60 seconds"} + + The stream remains open until the client disconnects or the server + terminates the connection. Clients should handle reconnection as needed. + + :param agent_name: The name of the hosted agent. Required. + :type agent_name: str + :param agent_version: The version of the agent. Required. + :type agent_version: str + :param session_id: The session ID (maps to an ADC sandbox). Required. + :type session_id: str + :return: SessionLogEvent. The SessionLogEvent is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionLogEvent + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.SessionLogEvent] = kwargs.pop("cls", None) + + _request = build_agents_get_session_log_stream_request( + agent_name=agent_name, + agent_version=agent_version, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + kwargs.pop("stream", None) # must always stream; discard any caller override + _stream = True + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.SessionLogEvent, response.text()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def publish_to_microsoft365( + self, + agent_name: str, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope], + content_type: str = "application/json", + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. + + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. + + :param agent_name: The name of the agent to publish. Required. + :type agent_name: str + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def publish_to_microsoft365( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. + + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. + + :param agent_name: The name of the agent to publish. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def publish_to_microsoft365( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. + + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. + + :param agent_name: The name of the agent to publish. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def publish_to_microsoft365( # pylint: disable=too-many-locals + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. + + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. + + :param agent_name: The name of the agent to publish. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Microsoft365PublishResult] = kwargs.pop("cls", None) + + if body is _Unset: + if publish_scope is _Unset: + raise TypeError("missing required argument: publish_scope") + body = { + "accessBoundaries": access_boundaries, + "agentDisplayName": agent_display_name, + "appVersion": app_version, + "botServiceArmId": bot_service_arm_id, + "canRespondWithoutMention": can_respond_without_mention, + "colorIconBase64": color_icon_base64, + "developerName": developer_name, + "developerWebsiteUrl": developer_website_url, + "fullDescription": full_description, + "optionalPermissionScopes": optional_permission_scopes, + "outlineIconBase64": outline_icon_base64, + "privacyUrl": privacy_url, + "publishAsAutopilot": publish_as_autopilot, + "publishScope": publish_scope, + "shortDescription": short_description, + "termsOfUseUrl": terms_of_use_url, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_publish_to_microsoft365_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Microsoft365PublishResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def get_microsoft365_package( + self, + agent_name: str, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope], + content_type: str = "application/json", + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def get_microsoft365_package( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def get_microsoft365_package( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def get_microsoft365_package( # pylint: disable=too-many-locals + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + if body is _Unset: + if publish_scope is _Unset: + raise TypeError("missing required argument: publish_scope") + body = { + "accessBoundaries": access_boundaries, + "agentDisplayName": agent_display_name, + "appVersion": app_version, + "botServiceArmId": bot_service_arm_id, + "canRespondWithoutMention": can_respond_without_mention, + "colorIconBase64": color_icon_base64, + "developerName": developer_name, + "developerWebsiteUrl": developer_website_url, + "fullDescription": full_description, + "optionalPermissionScopes": optional_permission_scopes, + "outlineIconBase64": outline_icon_base64, + "privacyUrl": privacy_url, + "publishAsAutopilot": publish_as_autopilot, + "publishScope": publish_scope, + "shortDescription": short_description, + "termsOfUseUrl": terms_of_use_url, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_get_microsoft365_package_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_microsoft365_publish_defaults( + self, agent_name: str, *, publish_as_digital_worker: Optional[bool] = None, **kwargs: Any + ) -> _models.Microsoft365PublishDefaults: + """Get Microsoft 365 publish defaults. + + Returns default and previously-published values used to pre-populate a Microsoft 365 publish + request for a Foundry agent. + + :param agent_name: The name of the agent to get publish defaults for. Required. + :type agent_name: str + :keyword publish_as_digital_worker: When true, returns defaults for publishing the agent as an + autopilot (digital worker) agent. Default value is None. + :paramtype publish_as_digital_worker: bool + :return: Microsoft365PublishDefaults. The Microsoft365PublishDefaults is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishDefaults + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Microsoft365PublishDefaults] = kwargs.pop("cls", None) + + _request = build_agents_get_microsoft365_publish_defaults_request( + agent_name=agent_name, + publish_as_digital_worker=publish_as_digital_worker, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Microsoft365PublishDefaults, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def create_telephony_binding( + self, + agent_name: str, + body: _models.CreateTelephonyBindingRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_telephony_binding( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_telephony_binding( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_telephony_binding( + self, agent_name: str, body: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Is one of the following types: + CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_create_telephony_binding_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyBinding, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_telephony_bindings( + self, + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. + + Returns the telephony bindings owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent whose bindings are listed. Required. + :type agent_name: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyBindingListItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.TelephonyBindingListItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_telephony_bindings_request( + agent_name=agent_name, + provider=provider, + status=status, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.TelephonyBindingListItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get_telephony_binding(self, agent_name: str, binding_id: str, **kwargs: Any) -> _models.TelephonyBinding: + """Get an agent telephony binding. + + Retrieves a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) + + _request = build_agents_get_telephony_binding_request( + agent_name=agent_name, + binding_id=binding_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyBinding, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_update_telephony_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyBinding, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete_telephony_binding( # pylint: disable=inconsistent-return-statements + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. + + Deletes a telephony binding owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_delete_telephony_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_telephony_calls( + self, + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after: Optional[datetime.datetime] = None, + started_before: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. + + Returns the durable inbound call history for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", "success", + and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after: Includes calls that started at or after this Unix timestamp in seconds. + Default value is None. + :paramtype started_after: ~datetime.datetime + :keyword started_before: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before: ~datetime.datetime + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyCallSummary] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.TelephonyCallSummary]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_telephony_calls_request( + agent_name=agent_name, + provider=provider, + status=status, + started_after=started_after, + started_before=started_before, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.TelephonyCallSummary], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get_telephony_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """Get an agent telephony call. + + Retrieves a durable inbound call record owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) + + _request = build_agents_get_telephony_call_request( + agent_name=agent_name, + call_id=call_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def transfer_telephony_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def transfer_telephony_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def transfer_telephony_call( + self, agent_name: str, call_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + target: str = _Unset, + **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) + + if body is _Unset: + if target is _Unset: + raise TypeError("missing required argument: target") + body = {"target": target} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_transfer_telephony_call_request( + agent_name=agent_name, + call_id=call_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def end_telephony_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """End an active agent telephony call. + + Ends an active inbound call owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) + + _request = build_agents_end_telephony_call_request( + agent_name=agent_name, + call_id=call_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_telephony_transfer_targets(self, agent_name: str, **kwargs: Any) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. + + Returns all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) + + _request = build_agents_get_telephony_transfer_targets_request( + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + transfer_targets: List[_models.TelephonyTransferTarget], + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) + + if body is _Unset: + if transfer_targets is _Unset: + raise TypeError("missing required argument: transfer_targets") + body = {"transfer_targets": transfer_targets} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_replace_telephony_transfer_targets_request( + agent_name=agent_name, + etag=etag, + match_condition=match_condition, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def upload_session_file( + self, + agent_name: str, + session_id: str, + content: bytes, + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: bytes + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def upload_session_file( + self, + agent_name: str, + session_id: str, + content: IO[bytes], + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def upload_session_file( + self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Is either a bytes type or a IO[bytes] type. Required. + :type content: bytes or IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) + + content_type = content_type or "application/octet-stream" + _content = content + + _request = build_agents_upload_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def download_session_file(self, agent_name: str, session_id: str, *, path: str, **kwargs: Any) -> Iterator[bytes]: + """Download a session file. + + Downloads the file at the specified sandbox path as a binary stream. The path is resolved + relative to the session home directory. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file path to download from the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agents_download_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_session_files( + self, + agent_name: str, + session_id: str, + *, + path: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.SessionDirectoryEntry"]: + """List session files. + + Returns files and directories at the specified path in the session sandbox. The response + includes only the immediate children of the target directory and defaults to the session home + directory when no path is supplied. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The directory path to list, relative to the session home directory. Defaults to + the home directory if not provided. Default value is None. + :paramtype path: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SessionDirectoryEntry + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_session_files_request( + agent_name=agent_name, + session_id=session_id, + path=path, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.SessionDirectoryEntry], + deserialized.get("entries", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def delete_session_file( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any + ) -> None: + """Delete a session file. + + Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, + deleting a non-empty directory returns 409 Conflict. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file or directory path to delete, relative to the session home directory. + Required. + :paramtype path: str + :keyword recursive: Whether to recursively delete directory contents. The service defaults to + ``false`` if a value is not specified by the caller. Default value is None. + :paramtype recursive: bool + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_delete_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + recursive=recursive, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + +class EvaluationRulesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`evaluation_rules` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: + """Get an evaluation rule. + + Retrieves the specified evaluation rule and its configuration. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + + _request = build_evaluation_rules_get_request( + id=id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationRule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete an evaluation rule. + + Removes the specified evaluation rule from the project. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_evaluation_rules_delete_request( + id=id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_or_update( + self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Is one of the following types: + EvaluationRule, JSON, IO[bytes] Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(evaluation_rule, (IOBase, bytes)): + _content = evaluation_rule + else: + _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_evaluation_rules_create_or_update_request( + id=id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationRule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, + agent_name: Optional[str] = None, + enabled: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.EvaluationRule"]: + """List evaluation rules. + + Returns the evaluation rules configured for the project, optionally filtered by action type, + agent name, or enabled state. + + :keyword action_type: Filter by the type of evaluation rule. Known values are: + "continuousEvaluation" and "humanEvaluationPreview". Default value is None. + :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType + :keyword agent_name: Filter by the agent name. Default value is None. + :paramtype agent_name: str + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of EvaluationRule + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationRule] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_evaluation_rules_list_request( + action_type=action_type, + agent_name=agent_name, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluationRule], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class ConnectionsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`connections` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def _get(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection. + + Retrieves the specified connection and its configuration details without including credential + values. + + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + + _request = build_connections_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection with credentials. + + Retrieves the specified connection together with its credential values. + + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + + _request = build_connections_get_with_credentials_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + connection_type: Optional[Union[str, _models.ConnectionType]] = None, + default_connection: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.Connection"]: + """List connections. + + Returns the connections available in the current project, optionally filtered by type or + default status. + + :keyword connection_type: Lists connections of this specific type. Known values are: + "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", + "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. + :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType + :keyword default_connection: Lists connections that are default connections. Default value is + None. + :paramtype default_connection: bool + :return: An iterator like instance of Connection + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Connection] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_connections_list_request( + connection_type=connection_type, + default_connection=default_connection, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Connection], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class DatasetsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`datasets` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: + """List versions. + + List all versions of the given DatasetVersion. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: + """List latest versions. + + List the latest version of each DatasetVersion. + + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: + """Get a version. + + Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the + DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to retrieve. Required. + :type version: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + _request = build_datasets_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a version. + + Delete the specific version of the DatasetVersion. The service returns 204 No Content if the + DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the DatasetVersion to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_datasets_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: _models.DatasetVersion, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_or_update( + self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Is one of the following types: + DatasetVersion, JSON, IO[bytes] Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(dataset_version, (IOBase, bytes)): + _content = dataset_version + else: + _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_create_or_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Is one of the following + types: PendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + IO[bytes] + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request + else: + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_pending_upload_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: + """Get dataset credentials. + + Retrieves the SAS credential to access the storage account associated with a dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + + _request = build_datasets_get_credentials_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetCredential, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class DeploymentsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`deployments` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def get(self, name: str, **kwargs: Any) -> _models.Deployment: + """Get a deployment. + + Retrieves a deployed model. + + :param name: Name of the deployment. Required. + :type name: str + :return: Deployment. The Deployment is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Deployment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + + _request = build_deployments_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Deployment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + model_publisher: Optional[str] = None, + model_name: Optional[str] = None, + deployment_type: Optional[Union[str, _models.DeploymentType]] = None, + **kwargs: Any + ) -> ItemPaged["_models.Deployment"]: + """List deployments. + + Returns the deployed models available in the current project, optionally filtered by publisher, + model name, or deployment type. + + :keyword model_publisher: Model publisher to filter models by. Default value is None. + :paramtype model_publisher: str + :keyword model_name: Model name (the publisher specific name) to filter models by. Default + value is None. + :paramtype model_name: str + :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value + is None. + :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType + :return: An iterator like instance of Deployment + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Deployment] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_deployments_list_request( + model_publisher=model_publisher, + model_name=model_name, + deployment_type=deployment_type, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Deployment], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class IndexesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`indexes` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.Index"]: + """List versions. + + List all versions of the given Index. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of Index + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged["_models.Index"]: + """List latest versions. + + List the latest version of each Index. + + :return: An iterator like instance of Index + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: + """Get a version. + + Get the specific version of the Index. The service returns 404 Not Found error if the Index + does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to retrieve. Required. + :type version: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6378,46 +11690,15 @@ def publish_to_microsoft365( # pylint: disable=too-many-locals } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Microsoft365PublishResult] = kwargs.pop("cls", None) - - if body is _Unset: - if publish_scope is _Unset: - raise TypeError("missing required argument: publish_scope") - body = { - "accessBoundaries": access_boundaries, - "agentDisplayName": agent_display_name, - "appVersion": app_version, - "botServiceArmId": bot_service_arm_id, - "canRespondWithoutMention": can_respond_without_mention, - "colorIconBase64": color_icon_base64, - "developerName": developer_name, - "developerWebsiteUrl": developer_website_url, - "fullDescription": full_description, - "optionalPermissionScopes": optional_permission_scopes, - "outlineIconBase64": outline_icon_base64, - "privacyUrl": privacy_url, - "publishAsAutopilot": publish_as_autopilot, - "publishScope": publish_scope, - "shortDescription": short_description, - "termsOfUseUrl": terms_of_use_url, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.Index] = kwargs.pop("cls", None) - _request = build_agents_publish_to_microsoft365_request( - agent_name=agent_name, - content_type=content_type, + _request = build_indexes_get_request( + name=name, + version=version, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -6441,331 +11722,193 @@ def publish_to_microsoft365( # pylint: disable=too-many-locals except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Microsoft365PublishResult, response.json()) + deserialized = _deserialize(_models.Index, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - def get_microsoft365_package( - self, - agent_name: str, - *, - publish_scope: Union[str, _models.Microsoft365PublishScope], - content_type: str = "application/json", - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, - **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + @distributed_trace + def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a version. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Delete the specific version of the Index. The service returns 204 No Content if the Index was + deleted successfully or if the Index does not exist. - :param agent_name: The name of the agent to generate the app package for. Required. - :type agent_name: str - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. - Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the Index to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_indexes_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, + name: str, + version: str, + index: _models.Index, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: ~azure.ai.projects.models.Index + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_microsoft365_package( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + def create_or_update( + self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.Index: + """Create or update a version. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Create a new or update an existing Index with the given version id. - :param agent_name: The name of the agent to generate the app package for. Required. - :type agent_name: str - :param body: Required. - :type body: JSON + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_microsoft365_package( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + def create_or_update( + self, + name: str, + version: str, + index: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Create a new or update an existing Index with the given version id. - :param agent_name: The name of the agent to generate the app package for. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def get_microsoft365_package( # pylint: disable=too-many-locals - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, - **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + def create_or_update( + self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Index: + """Create or update a version. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Create a new or update an existing Index with the given version id. - :param agent_name: The name of the agent to generate the app package for. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. - Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Is one of the following types: Index, JSON, + IO[bytes] Required. + :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - if body is _Unset: - if publish_scope is _Unset: - raise TypeError("missing required argument: publish_scope") - body = { - "accessBoundaries": access_boundaries, - "agentDisplayName": agent_display_name, - "appVersion": app_version, - "botServiceArmId": bot_service_arm_id, - "canRespondWithoutMention": can_respond_without_mention, - "colorIconBase64": color_icon_base64, - "developerName": developer_name, - "developerWebsiteUrl": developer_website_url, - "fullDescription": full_description, - "optionalPermissionScopes": optional_permission_scopes, - "outlineIconBase64": outline_icon_base64, - "privacyUrl": privacy_url, - "publishAsAutopilot": publish_as_autopilot, - "publishScope": publish_scope, - "shortDescription": short_description, - "termsOfUseUrl": terms_of_use_url, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Index] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(index, (IOBase, bytes)): + _content = index else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_get_microsoft365_package_request( - agent_name=agent_name, + _request = build_indexes_create_or_update_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -6778,53 +11921,135 @@ def get_microsoft365_package( # pylint: disable=too-many-locals _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [200, 201]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + raise HttpResponseError(response=response) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Index, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def get_microsoft365_publish_defaults( - self, agent_name: str, *, publish_as_digital_worker: Optional[bool] = None, **kwargs: Any - ) -> _models.Microsoft365PublishDefaults: - """Get Microsoft 365 publish defaults. - Returns default and previously-published values used to pre-populate a Microsoft 365 publish - request for a Foundry agent. +class VoiceAgentWebSocketOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - :param agent_name: The name of the agent to get publish defaults for. Required. + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`voice_agent_web_socket` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def connect_voice_agent( # pylint: disable=inconsistent-return-statements + self, + agent_name: str, + *, + foundry_features_query: Optional[Literal[_AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW]] = None, + transport: Optional[Union[str, _models.VoiceAgentTransport]] = None, + store: Optional[bool] = None, + structured_input: Optional[str] = None, + agent_version_override: Optional[str] = None, + websocket_subprotocol: Optional[Union[str, _models.VoiceAgentWebSocketSubprotocol]] = None, + **kwargs: Any + ) -> None: + """Connect to a voice agent. + + Connects to a voice agent over WebSocket. The client must send an HTTP GET with ``Upgrade: + websocket`` + headers. The optional ``realtime`` subprotocol is the only accepted subprotocol value. Supply + the + ``VoiceAgents=V1Preview`` opt-in through either the ``Foundry-Features`` header or the + ``foundry_features`` + query parameter. + + Handshake failures are evaluated in the following order, independent of the requested + ``transport``: + + + + 1. Agent enablement (any transport): if the target agent is disabled, the handshake fails + before the + `101 Switching Protocols` upgrade with `409 Conflict`, using the shared Foundry + `ApiErrorResponse` shape + with `error.code = agent_disabled`. This failure is terminal until the caller enables the + agent, and it + takes precedence over the WebRTC-specific checks below. + 2. WebRTC availability (only when `transport=webrtc`, and only once the agent itself is + enabled): the agent + must have the WebRTC transport capability configured. If the agent is enabled but WebRTC is not + available + for it, the handshake fails with `404 Not Found`. This is distinct from the `409 + agent_disabled` case + above, which concerns the agent itself rather than its WebRTC capability. + 3. WebRTC compatibility (only when `transport=webrtc`): WebRTC does not support + bring-your-own-model (BYOM) + or hosted-agent voice agents; those requests fail with `400 Bad Request`. + + :param agent_name: The name of the voice agent. Required. :type agent_name: str - :keyword publish_as_digital_worker: When true, returns defaults for publishing the agent as an - autopilot (digital worker) agent. Default value is None. - :paramtype publish_as_digital_worker: bool - :return: Microsoft365PublishDefaults. The Microsoft365PublishDefaults is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishDefaults + :keyword foundry_features_query: A query alternative to the ``Foundry-Features`` header for + clients that cannot set headers during a + WebSocket handshake. Set this to ``VoiceAgents=V1Preview``. Either this query parameter or the + header is + required. VOICE_AGENTS_V1_PREVIEW. Default value is None. + :paramtype foundry_features_query: str or ~azure.ai.projects.models.VOICE_AGENTS_V1_PREVIEW + :keyword transport: Selects the connection transport. Omit or send ``websocket`` for the + default, where signaling and audio are + exchanged as JSON events over this WebSocket. Send ``webrtc`` to negotiate a WebRTC + connection: the WebSocket + then carries only SDP signaling (``rtc.call.sdp.create`` / ``rtc.call.sdp.created``) while + media and the data + channel are peer-to-peer. Known values are: "websocket" and "webrtc". Default value is None. + :paramtype transport: str or ~azure.ai.projects.models.VoiceAgentTransport + :keyword store: Whether to persist the conversation created by this WebSocket session. If + omitted, the service honors the + persisted voice agent definition's configured ``store`` value. If supplied, this value + overrides the + definition's ``store`` setting for this session only. Default value is None. + :paramtype store: bool + :keyword structured_input: Per-session values for the voice agent's declared + ``structured_inputs``, serialized as a JSON object and + URL-encoded as this query parameter. Supplied values override definition defaults when + rendering the + agent's instructions and session-start greeting for this session only. The decoded value must + be a JSON + object no larger than 32 KiB with a maximum nesting depth of 16. Default value is None. + :paramtype structured_input: str + :keyword agent_version_override: Selects a specific version of the voice agent for this + session. Default value is None. + :paramtype agent_version_override: str + :keyword websocket_subprotocol: The requested WebSocket subprotocol. Omit this header or + request exactly ``realtime``. "realtime" Default value is None. + :paramtype websocket_subprotocol: str or + ~azure.ai.projects.models.VoiceAgentWebSocketSubprotocol + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6838,11 +12063,16 @@ def get_microsoft365_publish_defaults( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Microsoft365PublishDefaults] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_agents_get_microsoft365_publish_defaults_request( + _request = build_voice_agent_web_socket_connect_voice_agent_request( agent_name=agent_name, - publish_as_digital_worker=publish_as_digital_worker, + foundry_features_query=foundry_features_query, + transport=transport, + store=store, + structured_input=structured_input, + agent_version_override=agent_version_override, + websocket_subprotocol=websocket_subprotocol, api_version=self._config.api_version, headers=_headers, params=_params, @@ -6852,20 +12082,14 @@ def get_microsoft365_publish_defaults( } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [101]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -6873,102 +12097,143 @@ def get_microsoft365_publish_defaults( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Microsoft365PublishDefaults, response.json()) + response_headers = {} + response_headers["Sec-WebSocket-Protocol"] = self._deserialize( + "str", response.headers.get("Sec-WebSocket-Protocol") + ) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, None, response_headers) # type: ignore - return deserialized # type: ignore - @overload - def upload_session_file( - self, - agent_name: str, - session_id: str, - content: bytes, - *, - path: str, - content_type: str = "application/octet-stream", - **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. +class AgentEndpointConversationsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`agent_endpoint_conversations` attribute. + """ - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: bytes - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". - :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult - :raises ~azure.core.exceptions.HttpResponseError: - """ + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - def upload_session_file( + @distributed_trace + def list_agent_conversations( self, agent_name: str, - session_id: str, - content: IO[bytes], *, - path: str, - content_type: str = "application/octet-stream", + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. + ) -> ItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. :param agent_name: The name of the agent. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". - :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceConversation] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace - def upload_session_file( - self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. + cls: ClsType[List[_models.VoiceConversation]] = kwargs.pop("cls", None) - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Is either a bytes type or a IO[bytes] type. Required. - :type content: bytes or IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversations_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.VoiceConversation], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get_agent_conversation(self, agent_name: str, conversation_id: str, **kwargs: Any) -> _models.VoiceConversation: + """Get a voice agent conversation. + + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6979,22 +12244,15 @@ def upload_session_file( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) - - content_type = content_type or "application/octet-stream" - _content = content + cls: ClsType[_models.VoiceConversation] = kwargs.pop("cls", None) - _request = build_agents_upload_session_file_request( + _request = build_agent_endpoint_conversations_get_agent_conversation_request( agent_name=agent_name, - session_id=session_id, - path=path, - content_type=content_type, + conversation_id=conversation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -7011,7 +12269,7 @@ def upload_session_file( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -7027,7 +12285,7 @@ def upload_session_file( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) + deserialized = _deserialize(_models.VoiceConversation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -7035,21 +12293,20 @@ def upload_session_file( return deserialized # type: ignore @distributed_trace - def download_session_file(self, agent_name: str, session_id: str, *, path: str, **kwargs: Any) -> Iterator[bytes]: - """Download a session file. + def delete_agent_conversation( # pylint: disable=inconsistent-return-statements + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> None: + """Delete a voice agent conversation. - Downloads the file at the specified sandbox path as a binary stream. The path is resolved - relative to the session home directory. + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. :param agent_name: The name of the agent. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file path to download from the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7063,12 +12320,11 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_agents_download_session_file_request( + _request = build_agent_endpoint_conversations_delete_agent_conversation_request( agent_name=agent_name, - session_id=session_id, - path=path, + conversation_id=conversation_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7078,20 +12334,14 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -7099,38 +12349,31 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, ) raise HttpResponseError(response=response, model=error) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def list_session_files( + def list_agent_conversation_responses( self, agent_name: str, - session_id: str, + conversation_id: str, *, - path: Optional[str] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.SessionDirectoryEntry"]: - """List session files. + ) -> ItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. - Returns files and directories at the specified path in the session sandbox. The response - includes only the immediate children of the target directory and defaults to the session home - directory when no path is supplied. + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). :param agent_name: The name of the agent. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The directory path to list, relative to the session home directory. Defaults to - the home directory if not provided. Default value is None. - :paramtype path: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -7145,14 +12388,14 @@ def list_session_files( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of SessionDirectoryEntry - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceResponse] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.VoiceResponse]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -7164,10 +12407,9 @@ def list_session_files( def prepare_request(_continuation_token=None): - _request = build_agents_list_session_files_request( + _request = build_agent_endpoint_conversations_list_agent_conversation_responses_request( agent_name=agent_name, - session_id=session_id, - path=path, + conversation_id=conversation_id, limit=limit, order=order, after=_continuation_token, @@ -7185,8 +12427,8 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.SessionDirectoryEntry], - deserialized.get("entries", []), + List[_models.VoiceResponse], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore @@ -7214,26 +12456,23 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) @distributed_trace - def delete_session_file( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any - ) -> None: - """Delete a session file. + def get_agent_conversation_response( + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. - Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, - deleting a non-empty directory returns 409 Conflict. + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). :param agent_name: The name of the agent. Required. :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file or directory path to delete, relative to the session home directory. - Required. - :paramtype path: str - :keyword recursive: Whether to recursively delete directory contents. The service defaults to - ``false`` if a value is not specified by the caller. Default value is None. - :paramtype recursive: bool - :return: None - :rtype: None + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7247,13 +12486,12 @@ def delete_session_file( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceResponse] = kwargs.pop("cls", None) - _request = build_agents_delete_session_file_request( + _request = build_agent_endpoint_conversations_get_agent_conversation_response_request( agent_name=agent_name, - session_id=session_id, - path=path, - recursive=recursive, + conversation_id=conversation_id, + response_id=response_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7263,52 +12501,267 @@ def delete_session_file( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_agent_conversation_response_items( + self, + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. + + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversation_response_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list_agent_conversation_items( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. + + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agent_endpoint_conversations_list_agent_conversation_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), ) - raise HttpResponseError(response=response, model=error) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - if cls: - return cls(pipeline_response, None, {}) # type: ignore + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response -class EvaluationRulesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`evaluation_rules` attribute. - """ + return pipeline_response - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return ItemPaged(get_next, extract_data) @distributed_trace - def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: - """Get an evaluation rule. + def get_agent_conversation_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. - Retrieves the specified evaluation rule and its configuration. + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7322,10 +12775,12 @@ def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + cls: ClsType[_models.RealtimeConversationItem] = kwargs.pop("cls", None) - _request = build_evaluation_rules_get_request( - id=id, + _request = build_agent_endpoint_conversations_get_agent_conversation_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7350,12 +12805,16 @@ def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) + deserialized = _deserialize(_models.RealtimeConversationItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -7363,15 +12822,27 @@ def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: return deserialized # type: ignore @distributed_trace - def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete an evaluation rule. - - Removes the specified evaluation rule from the project. + def get_agent_conversation_item_audio( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceItemAudioResponse: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :return: None - :rtype: None + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceItemAudioResponse. The VoiceItemAudioResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceItemAudioResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7385,10 +12856,12 @@ def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsisten _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceItemAudioResponse] = kwargs.pop("cls", None) - _request = build_evaluation_rules_delete_request( - id=id, + _request = build_agent_endpoint_conversations_get_agent_conversation_item_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7398,95 +12871,58 @@ def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsisten } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - def create_or_update( - self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @overload - def create_or_update( - self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceItemAudioResponse, response.json()) - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace - def create_or_update( - self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. + def get_agent_conversation_item_audio_content( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's audio. - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Is one of the following types: - EvaluationRule, JSON, IO[bytes] Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7497,24 +12933,16 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(evaluation_rule, (IOBase, bytes)): - _content = evaluation_rule - else: - _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_evaluation_rules_create_or_update_request( - id=id, - content_type=content_type, + _request = build_agent_endpoint_conversations_get_agent_conversation_item_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -7524,62 +12952,60 @@ def create_or_update( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @distributed_trace - def list( - self, - *, - action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, - agent_name: Optional[str] = None, - enabled: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.EvaluationRule"]: - """List evaluation rules. + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - Returns the evaluation rules configured for the project, optionally filtered by action type, - agent name, or enabled state. + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - :keyword action_type: Filter by the type of evaluation rule. Known values are: - "continuousEvaluation" and "humanEvaluationPreview". Default value is None. - :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType - :keyword agent_name: Filter by the agent name. Default value is None. - :paramtype agent_name: str - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of EvaluationRule - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationRule] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) + return deserialized # type: ignore + + @distributed_trace + def get_agent_conversation_item_generated_audio( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedItemAudioResponse: + """Get a voice agent conversation item's generated audio metadata. + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedItemAudioResponse. The VoiceGeneratedItemAudioResponse is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -7588,105 +13014,77 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_evaluation_rules_list_request( - action_type=action_type, - agent_name=agent_name, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[_models.VoiceGeneratedItemAudioResponse] = kwargs.pop("cls", None) - return _request + _request = build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.EvaluationRule], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - + raise HttpResponseError(response=response, model=error) -class ConnectionsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceGeneratedItemAudioResponse, response.json()) - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`connections` attribute. - """ + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore @distributed_trace - def _get(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection. + def get_agent_conversation_item_generated_audio_content( # pylint: disable=name-too-long + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's generated audio. - Retrieves the specified connection and its configuration details without including credential - values. + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7700,10 +13098,12 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_connections_get_request( - name=name, + _request = build_agent_endpoint_conversations_get_agent_conversation_item_generated_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7714,7 +13114,7 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -7728,17 +13128,16 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -7746,15 +13145,31 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: return deserialized # type: ignore @distributed_trace - def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection with credentials. - - Retrieves the specified connection together with its credential values. + def get_agent_conversation_audio( + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceRecordingResponse: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecordingResponse. The VoiceRecordingResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecordingResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7768,10 +13183,11 @@ def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceRecordingResponse] = kwargs.pop("cls", None) - _request = build_connections_get_with_credentials_request( - name=name, + _request = build_agent_endpoint_conversations_get_agent_conversation_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7796,52 +13212,48 @@ def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = _deserialize(_models.VoiceRecordingResponse, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @distributed_trace - def list( - self, - *, - connection_type: Optional[Union[str, _models.ConnectionType]] = None, - default_connection: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.Connection"]: - """List connections. - - Returns the connections available in the current project, optionally filtered by type or - default status. + def get_agent_conversation_audio_content( + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. - :keyword connection_type: Lists connections of this specific type. Known values are: - "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", - "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. - :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType - :keyword default_connection: Lists connections that are default connections. Default value is - None. - :paramtype default_connection: bool - :return: An iterator like instance of Connection - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Connection] + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -7850,84 +13262,63 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_connections_list_request( - connection_type=connection_type, - default_connection=default_connection, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Connection], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - def get_next(next_link=None): - _request = prepare_request(next_link) + _request = build_agent_endpoint_conversations_get_agent_conversation_audio_content_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - return pipeline_response + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - return ItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore -class DatasetsOperations: # pylint: disable=docstring-missing-param +class AgentTelephonyOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`datasets` attribute. + :attr:`agent_telephony` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -7937,114 +13328,122 @@ def __init__(self, *args, **kwargs) -> None: self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: - """List versions. + @overload + def create_telephony_call_job( + self, + agent_name: str, + body: _models.CreateTelephonyCallJobRequest, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - List all versions of the given DatasetVersion. + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_datasets_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + @overload + def create_telephony_call_job( + self, + agent_name: str, + body: JSON, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - def get_next(next_link=None): - _request = prepare_request(next_link) + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: JSON + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + @overload + def create_telephony_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - return pipeline_response + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - return ItemPaged(get_next, extract_data) + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: - """List latest versions. + def create_telephony_call_job( + self, + agent_name: str, + body: Union[_models.CreateTelephonyCallJobRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - List the latest version of each DatasetVersion. + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Is one of the following types: + CreateTelephonyCallJobRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest or JSON or IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8053,86 +13452,81 @@ def list(self, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_datasets_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_create_telephony_call_job_request( + agent_name=agent_name, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - return _request + response = pipeline_response.http_response - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), + if response.status_code not in [202]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) + raise HttpResponseError(response=response, model=error) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) - return pipeline_response + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - return ItemPaged(get_next, extract_data) + return deserialized # type: ignore @distributed_trace - def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: - """Get a version. + def get_telephony_call_job(self, agent_name: str, call_job_id: str, **kwargs: Any) -> _models.TelephonyCallJob: + """Get an outbound telephony call job. - Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the - DatasetVersion does not exist. + Retrieves a durable direct or campaign-created outbound call job. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to retrieve. Required. - :type version: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8146,11 +13540,11 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_datasets_get_request( - name=name, - version=version, + _request = build_agent_telephony_get_telephony_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8175,31 +13569,43 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a version. + def cancel_telephony_call_job( + self, agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> _models.TelephonyCallJob: + """Cancel an outbound telephony call job. - Delete the specific version of the DatasetVersion. The service returns 204 No Content if the - DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + Requests cancellation of a durable outbound call job. A connected call is allowed to finish. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the DatasetVersion to delete. Required. - :type version: str - :return: None - :rtype: None + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8208,16 +13614,24 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis 409: ResourceExistsError, 304: ResourceNotModifiedError, } + if match_condition == MatchConditions.IfNotModified: + error_map[412] = ResourceModifiedError + elif match_condition == MatchConditions.IfPresent: + error_map[412] = ResourceNotFoundError + elif match_condition == MatchConditions.IfMissing: + error_map[412] = ResourceExistsError error_map.update(kwargs.pop("error_map", {}) or {}) _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_datasets_delete_request( - name=name, - version=version, + _request = build_agent_telephony_cancel_telephony_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8227,121 +13641,215 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200, 202]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + if response.status_code == 200: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if response.status_code == 202: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @overload - def create_or_update( + def create_telephony_campaign( self, - name: str, - version: str, - dataset_version: _models.DatasetVersion, + agent_name: str, + body: _models.CreateTelephonyCampaignRequest, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. - Create a new or update an existing DatasetVersion with the given version id. + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCampaignRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_or_update( - self, - name: str, - version: str, - dataset_version: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + def create_telephony_campaign( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. - Create a new or update an existing DatasetVersion with the given version id. + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: JSON + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_or_update( - self, - name: str, - version: str, - dataset_version: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + def create_telephony_campaign( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. - Create a new or update an existing DatasetVersion with the given version id. + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: IO[bytes] + :param agent_name: Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_telephony_campaign( + self, agent_name: str, body: Union[_models.CreateTelephonyCampaignRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyCampaign: + """Create an outbound telephony campaign. + + Creates a draft outbound campaign. Recipients are imported and validated before the campaign + can be published. + + :param agent_name: Required. + :type agent_name: str + :param body: Is one of the following types: CreateTelephonyCampaignRequest, JSON, IO[bytes] + Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCampaignRequest or JSON or IO[bytes] + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_create_telephony_campaign_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @distributed_trace - def create_or_update( - self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + def get_telephony_campaign(self, agent_name: str, campaign_id: str, **kwargs: Any) -> _models.TelephonyCampaign: + """Get an outbound telephony campaign. - Create a new or update an existing DatasetVersion with the given version id. + Retrieves an outbound campaign, including configuration, execution state, and aggregate + call-job counts. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Is one of the following types: - DatasetVersion, JSON, IO[bytes] Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8352,25 +13860,15 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(dataset_version, (IOBase, bytes)): - _content = dataset_version - else: - _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - _request = build_datasets_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_agent_telephony_get_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -8387,207 +13885,312 @@ def create_or_update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + def _import_telephony_campaign_recipients_initial( # pylint: disable=name-too-long + self, + agent_name: str, + campaign_id: str, + body: Union[_models.ImportTelephonyCampaignRecipientsRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> Iterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agent_telephony_import_telephony_campaign_recipients_request( + agent_name=agent_name, + campaign_id=campaign_id, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + @overload - def pending_upload( + def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long self, - name: str, - version: str, - pending_upload_request: _models.PendingUploadRequest, + agent_name: str, + campaign_id: str, + body: _models.ImportTelephonyCampaignRecipientsRequest, *, + idempotency_key: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> LROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: ~azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest + :keyword idempotency_key: Required. + :paramtype idempotency_key: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( + def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long self, - name: str, - version: str, - pending_upload_request: JSON, + agent_name: str, + campaign_id: str, + body: JSON, *, + idempotency_key: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> LROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: JSON + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: JSON + :keyword idempotency_key: Required. + :paramtype idempotency_key: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( + def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long self, - name: str, - version: str, - pending_upload_request: IO[bytes], + agent_name: str, + campaign_id: str, + body: IO[bytes], *, + idempotency_key: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> LROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: IO[bytes] + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: IO[bytes] + :keyword idempotency_key: Required. + :paramtype idempotency_key: str :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def pending_upload( + def begin_import_telephony_campaign_recipients( # pylint: disable=name-too-long self, - name: str, - version: str, - pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + agent_name: str, + campaign_id: str, + body: Union[_models.ImportTelephonyCampaignRecipientsRequest, JSON, IO[bytes]], + *, + idempotency_key: str, **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> LROPoller[_models.TelephonyOperationResource]: + """Import outbound telephony campaign recipients. - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + Starts an asynchronous import of campaign recipients from a Dataset CSV, JSON array, or JSONL + file. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Is one of the following - types: PendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Is one of the following types: ImportTelephonyCampaignRecipientsRequest, JSON, + IO[bytes] Required. + :type body: ~azure.ai.projects.models.ImportTelephonyCampaignRecipientsRequest or JSON or IO[bytes] - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :keyword idempotency_key: Required. + :paramtype idempotency_key: str + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request - else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_datasets_pending_upload_request( - name=name, - version=version, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._import_telephony_campaign_recipients_initial( + agent_name=agent_name, + campaign_id=campaign_id, + body=body, + idempotency_key=idempotency_key, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return deserialized # type: ignore + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: - """Get dataset credentials. + def get_telephony_campaign_recipient_import( + self, agent_name: str, campaign_id: str, import_id: str, **kwargs: Any + ) -> _models.TelephonyCampaignRecipientImport: + """Get an outbound telephony campaign recipient import. - Retrieves the SAS credential to access the storage account associated with a dataset version. + Retrieves the durable status and counters for a campaign recipient import. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param import_id: Required. + :type import_id: str + :return: TelephonyCampaignRecipientImport. The TelephonyCampaignRecipientImport is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaignRecipientImport :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8601,11 +14204,12 @@ def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.Dat _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCampaignRecipientImport] = kwargs.pop("cls", None) - _request = build_datasets_get_credentials_request( - name=name, - version=version, + _request = build_agent_telephony_get_telephony_campaign_recipient_import_request( + agent_name=agent_name, + campaign_id=campaign_id, + import_id=import_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8630,48 +14234,23 @@ def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.Dat except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + deserialized = _deserialize(_models.TelephonyCampaignRecipientImport, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class DeploymentsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`deployments` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - - @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.Deployment: - """Get a deployment. - - Retrieves a deployed model. - - :param name: Name of the deployment. Required. - :type name: str - :return: Deployment. The Deployment is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Deployment - :raises ~azure.core.exceptions.HttpResponseError: - """ + def _validate_telephony_campaign_initial(self, agent_name: str, campaign_id: str, **kwargs: Any) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8683,10 +14262,11 @@ def get(self, name: str, **kwargs: Any) -> _models.Deployment: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_deployments_get_request( - name=name, + _request = build_agent_telephony_validate_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8697,31 +14277,30 @@ def get(self, name: str, **kwargs: Any) -> _models.Deployment: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [202]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Deployment, response.json()) + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -8729,149 +14308,86 @@ def get(self, name: str, **kwargs: Any) -> _models.Deployment: return deserialized # type: ignore @distributed_trace - def list( - self, - *, - model_publisher: Optional[str] = None, - model_name: Optional[str] = None, - deployment_type: Optional[Union[str, _models.DeploymentType]] = None, - **kwargs: Any - ) -> ItemPaged["_models.Deployment"]: - """List deployments. + def begin_validate_telephony_campaign( + self, agent_name: str, campaign_id: str, **kwargs: Any + ) -> LROPoller[_models.TelephonyOperationResource]: + """Validate an outbound telephony campaign. - Returns the deployed models available in the current project, optionally filtered by publisher, - model name, or deployment type. + Starts asynchronous validation of the current campaign draft and imported recipient snapshot. - :keyword model_publisher: Model publisher to filter models by. Default value is None. - :paramtype model_publisher: str - :keyword model_name: Model name (the publisher specific name) to filter models by. Default - value is None. - :paramtype model_name: str - :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value - is None. - :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType - :return: An iterator like instance of Deployment - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Deployment] + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_deployments_list_request( - model_publisher=model_publisher, - model_name=model_name, - deployment_type=deployment_type, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Deployment], - deserialized.get("value", []), + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._validate_telephony_campaign_initial( + agent_name=agent_name, + campaign_id=campaign_id, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + def get_long_running_output(pipeline_response): + response_headers = {} response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - - -class IndexesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`indexes` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.Index"]: - """List versions. - - List all versions of the given Index. + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of Index - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + def _publish_telephony_campaign_initial( + self, + agent_name: str, + campaign_id: str, + body: Union[_models.PublishTelephonyCampaignRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8880,177 +14396,245 @@ def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.Index"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_indexes_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - return _request + _request = build_agent_telephony_publish_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Index], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [202]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) - return pipeline_response + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - return ItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.Index"]: - """List latest versions. + return deserialized # type: ignore - List the latest version of each Index. + @overload + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: _models.PublishTelephonyCampaignRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. - :return: An iterator like instance of Index - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: ~azure.ai.projects.models.PublishTelephonyCampaignRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + @overload + def begin_publish_telephony_campaign( + self, agent_name: str, campaign_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. - def prepare_request(next_link=None): - if not next_link: + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ - _request = build_indexes_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + @overload + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. - return _request + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Index], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + @distributed_trace + def begin_publish_telephony_campaign( + self, + agent_name: str, + campaign_id: str, + body: Union[_models.PublishTelephonyCampaignRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> LROPoller[_models.TelephonyOperationResource]: + """Publish an outbound telephony campaign. - def get_next(next_link=None): - _request = prepare_request(next_link) + Permanently locks the validated campaign draft and starts asynchronous call-job + materialization. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :param body: Is one of the following types: PublishTelephonyCampaignRequest, JSON, IO[bytes] + Required. + :type body: ~azure.ai.projects.models.PublishTelephonyCampaignRequest or JSON or IO[bytes] + :return: An instance of LROPoller that returns TelephonyOperationResource. The + TelephonyOperationResource is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.TelephonyOperationResource] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyOperationResource] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._publish_telephony_campaign_initial( + agent_name=agent_name, + campaign_id=campaign_id, + body=body, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + deserialized = _deserialize(_models.TelephonyOperationResource, response.json().get("resource", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - return pipeline_response + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return ItemPaged(get_next, extract_data) + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.TelephonyOperationResource].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.TelephonyOperationResource]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: - """Get a version. + def pause_telephony_campaign(self, agent_name: str, campaign_id: str, **kwargs: Any) -> _models.TelephonyCampaign: + """Pause an outbound telephony campaign. - Get the specific version of the Index. The service returns 404 Not Found error if the Index - does not exist. + Pauses dispatch of call jobs owned by a published campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to retrieve. Required. - :type version: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9064,11 +14648,11 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Index] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - _request = build_indexes_get_request( - name=name, - version=version, + _request = build_agent_telephony_pause_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -9093,12 +14677,16 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -9106,18 +14694,17 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: return deserialized # type: ignore @distributed_trace - def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a version. + def resume_telephony_campaign(self, agent_name: str, campaign_id: str, **kwargs: Any) -> _models.TelephonyCampaign: + """Resume an outbound telephony campaign. - Delete the specific version of the Index. The service returns 204 No Content if the Index was - deleted successfully or if the Index does not exist. + Resumes dispatch of call jobs owned by a paused campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the Index to delete. Required. - :type version: str - :return: None - :rtype: None + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9131,11 +14718,11 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - _request = build_indexes_delete_request( - name=name, - version=version, + _request = build_agent_telephony_resume_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -9145,115 +14732,119 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore - @overload - def create_or_update( - self, - name: str, - version: str, - index: _models.Index, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.Index: - """Create or update a version. + return deserialized # type: ignore - Create a new or update an existing Index with the given version id. + @distributed_trace + def cancel_telephony_campaign(self, agent_name: str, campaign_id: str, **kwargs: Any) -> _models.TelephonyCampaign: + """Cancel an outbound telephony campaign. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: ~azure.ai.projects.models.Index - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + Cancels a campaign and prevents any further call-job dispatch. + + :param agent_name: Required. + :type agent_name: str + :param campaign_id: Required. + :type campaign_id: str + :return: TelephonyCampaign. The TelephonyCampaign is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCampaign :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - def create_or_update( - self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.Index: - """Create or update a version. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Create a new or update an existing Index with the given version id. + cls: ClsType[_models.TelephonyCampaign] = kwargs.pop("cls", None) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_agent_telephony_cancel_telephony_campaign_request( + agent_name=agent_name, + campaign_id=campaign_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - @overload - def create_or_update( - self, - name: str, - version: str, - index: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.Index: - """Create or update a version. + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - Create a new or update an existing Index with the given version id. + response = pipeline_response.http_response - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCampaign, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def create_or_update( - self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any - ) -> _models.Index: - """Create or update a version. + def get_telephony_operation(self, agent_name: str, operation_id: str, **kwargs: Any) -> _models.TelephonyOperation: + """Get an outbound telephony operation. - Create a new or update an existing Index with the given version id. + Retrieves an asynchronous outbound campaign operation. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Is one of the following types: Index, JSON, - IO[bytes] Required. - :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param agent_name: Required. + :type agent_name: str + :param operation_id: Required. + :type operation_id: str + :return: TelephonyOperation. The TelephonyOperation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyOperation :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9264,25 +14855,15 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Index] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(index, (IOBase, bytes)): - _content = index - else: - _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyOperation] = kwargs.pop("cls", None) - _request = build_indexes_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_agent_telephony_get_telephony_operation_request( + agent_name=agent_name, + operation_id=operation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -9299,19 +14880,23 @@ def create_or_update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.TelephonyOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py index 4231ea89f96a..624ebf36e119 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py @@ -13,6 +13,7 @@ from typing import Any, Callable, List from ..models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _BETA_OPERATION_FEATURE_HEADERS, _has_header_case_insensitive from ._patch_agents import AgentsOperations, BetaAgentsOperations +from ._patch_agent_endpoint_conversations import AgentEndpointConversationsOperations from ._patch_agent_insights import BetaAgentInsightMonitorsOperations from ._patch_datasets import BetaDatasetsOperations, DatasetsOperations from ._patch_evaluators import BetaEvaluatorsOperations @@ -147,6 +148,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: __all__: List[str] = [ "AgentsOperations", + "AgentEndpointConversationsOperations", "BetaAgentInsightMonitorsOperations", "BetaAgentsOperations", "BetaDatasetsOperations", diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agent_endpoint_conversations.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agent_endpoint_conversations.py new file mode 100644 index 000000000000..d336c3dedfd3 --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agent_endpoint_conversations.py @@ -0,0 +1,755 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" + +from typing import Any, Iterator, Optional, Union +from azure.core.exceptions import HttpResponseError +from azure.core.paging import ItemPaged +from azure.core.tracing.decorator import distributed_trace +from ._operations import AgentEndpointConversationsOperations as GeneratedAgentEndpointConversationsOperations +from .. import models as _models +from ..models._enums import _AgentDefinitionOptInKeys +from ..models._patch import ( + _FOUNDRY_FEATURES_HEADER_NAME, + _has_header_case_insensitive, + _PREVIEW_FEATURE_REQUIRED_CODE, + _PREVIEW_FEATURE_ADDED_ERROR_MESSAGE, +) + +# All methods on this class always require the VoiceAgents=V1Preview opt-in (voice-agent +# conversation reads), regardless of `allow_preview` -- this class used to live entirely as a +# nested `.beta.agent_endpoint_conversations` sub-client (whose methods were unconditionally +# wrapped with this same header by `_OperationMethodHeaderProxy` in `operations/_patch.py`, since +# merely accessing `.beta` was itself the opt-in signal). Upstream has since merged it entirely +# into this top-level, stable client attribute, but the *service* still requires the same opt-in +# header for every one of these methods -- confirmed empirically: an unauthenticated (no header) +# call to `list_agent_conversations` returns 403 with error.code="preview_feature_required" even +# though the generated SDK surface no longer marks this class as beta. So every method here still +# needs the same `allow_preview`-gated header injection (and, for non-paged methods, the same +# friendlier error message on 403) as every other "optional preview feature on an otherwise-stable +# operation" elsewhere in this SDK (see e.g. `AgentsOperations.generate_agent`). +_VOICE_AGENTS_HEADER_VALUE = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + + +class AgentEndpointConversationsOperations(GeneratedAgentEndpointConversationsOperations): + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`agent_endpoint_conversations` attribute. + """ + + @distributed_trace + def list_agent_conversations( # type: ignore[override] + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> ItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. + + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. When the client is constructed + with ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceConversation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversations(agent_name, limit=limit, order=order, before=before, **kwargs) + + @distributed_trace + def get_agent_conversation( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceConversation: + """Get a voice agent conversation. + + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. + When the client is constructed with ``allow_preview=True``, the required preview opt-in header + is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def delete_agent_conversation( # pylint: disable=inconsistent-return-statements # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> None: + """Delete a voice agent conversation. + + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. When the client + is constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().delete_agent_conversation(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_agent_conversation_responses( # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> ItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. + + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). When the client is constructed with ``allow_preview=True``, + the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceResponse] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_responses( + agent_name, conversation_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace + def get_agent_conversation_response( # type: ignore[override] + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. + + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). When the client is constructed with ``allow_preview=True``, the + required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_response(agent_name, conversation_id, response_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_agent_conversation_response_items( # pylint: disable=name-too-long # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. + + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_response_items( + agent_name, conversation_id, response_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace + def list_agent_conversation_items( # type: ignore[override] + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. + + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + return super().list_agent_conversation_items( + agent_name, conversation_id, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace + def get_agent_conversation_item( # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. + + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_item(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_item_audio( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceItemAudioResponse: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. When the client is constructed with ``allow_preview=True``, the required preview + opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceItemAudioResponse. The VoiceItemAudioResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_item_audio(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_item_audio_content( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's audio. + + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_item_audio_content(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_item_generated_audio( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedItemAudioResponse: + """Get a voice agent conversation item's generated audio metadata. + + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedItemAudioResponse. The VoiceGeneratedItemAudioResponse is compatible + with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedItemAudioResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = { + _FOUNDRY_FEATURES_HEADER_NAME: _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + } + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_item_generated_audio(agent_name, conversation_id, item_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_item_generated_audio_content( # pylint: disable=name-too-long # type: ignore[override] + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's generated audio. + + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. When the client is constructed with ``allow_preview=True``, the required preview + opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = { + _FOUNDRY_FEATURES_HEADER_NAME: _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + } + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_item_generated_audio_content( + agent_name, conversation_id, item_id, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_audio( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> _models.VoiceRecordingResponse: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. When the client is constructed with + ``allow_preview=True``, the required preview opt-in header is added automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecordingResponse. The VoiceRecordingResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecordingResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_audio(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_agent_conversation_audio_content( # type: ignore[override] + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENTS_HEADER_VALUE} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _VOICE_AGENTS_HEADER_VALUE + kwargs["headers"] = headers + + try: + return super().get_agent_conversation_audio_content(agent_name, conversation_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agents.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agents.py index 36f226417afa..b901cb3143a9 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agents.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_agents.py @@ -1,4 +1,4 @@ -# pylint: disable=line-too-long,useless-suppression,pointless-string-statement +# pylint: disable=line-too-long,useless-suppression,pointless-string-statement,too-many-lines # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -8,10 +8,13 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize """ +import datetime import hashlib from io import IOBase -from typing import Union, Optional, Any, IO, cast, overload +from typing import Union, Optional, Any, IO, List, cast, overload, TYPE_CHECKING +from azure.core import MatchConditions from azure.core.exceptions import HttpResponseError +from azure.core.paging import ItemPaged from azure.core.polling import NoPolling, PollingMethod from azure.core.polling.base_polling import LROBasePolling from azure.core.tracing.decorator import distributed_trace @@ -33,6 +36,9 @@ _PREVIEW_FEATURE_ADDED_ERROR_MESSAGE, ) +if TYPE_CHECKING: + from .. import _unions + def _compute_sha256_from_stream(stream: IO[bytes], *, chunk_size: int = 1024 * 1024) -> str: if not isinstance(stream, IOBase) or not stream.seekable(): @@ -61,7 +67,7 @@ class AgentsOperations(GeneratedAgentsOperations): :attr:`agents` attribute. """ - @overload + @overload # type: ignore[override] def create_version( self, agent_name: str, @@ -163,7 +169,7 @@ def create_version( """ @distributed_trace - def create_version( + def create_version( # type: ignore[override] self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, @@ -222,9 +228,9 @@ def create_version( kwargs["headers"] = headers try: - return super().create_version( + return super().create_version( # type: ignore[misc] agent_name, - body, + body, # type: ignore[arg-type] definition=definition, metadata=metadata, description=description, @@ -359,42 +365,1000 @@ def create_version_from_code( raise new_exc from exc raise + @distributed_trace + def generate_agent(self, body: _models.GenerateVoiceAgentRequest, **kwargs: Any) -> _models.AgentDetails: # type: ignore[override] + """Generate an agent. -class BetaAgentsOperations(BetaAgentsOperationsGenerated): - """Custom operations for beta agent optimization jobs.""" + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. - @overload - def begin_create_optimization_job( + :param body: The kind-specific inputs for generating and creating an agent. Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().generate_agent(body, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + def create_telephony_binding( self, - job: _models.AgentOptimizationJob, + agent_name: str, + body: _models.CreateTelephonyBindingRequest, *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any, - ) -> AgentOptimizationLROPoller: ... + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @overload - def begin_create_optimization_job( + def create_telephony_binding( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_telephony_binding( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_telephony_binding( # type: ignore[override] + self, agent_name: str, body: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param body: The provider-specific binding to create. Is one of the following types: + CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().create_telephony_binding(agent_name, body, **kwargs) # type: ignore[arg-type] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_telephony_bindings( # type: ignore[override] self, - job: JSON, + agent_name: str, *, - operation_id: Optional[str] = None, - content_type: str = "application/json", + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any, - ) -> AgentOptimizationLROPoller: ... + ) -> ItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. + + Returns the telephony bindings owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent whose bindings are listed. Required. + :type agent_name: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :keyword limit: A limit on the number of objects to be returned. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. Known values are: + "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyBindingListItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + # Add Foundry-Features header if not already present + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + return super().list_telephony_bindings( + agent_name, provider=provider, status=status, limit=limit, order=order, before=before, **kwargs + ) + + @distributed_trace + def get_telephony_binding( # type: ignore[override] + self, agent_name: str, binding_id: str, **kwargs: Any + ) -> _models.TelephonyBinding: + """Get an agent telephony binding. + + Retrieves a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().get_telephony_binding(agent_name, binding_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @overload - def begin_create_optimization_job( + def update_telephony_binding( self, - job: IO[bytes], + agent_name: str, + binding_id: str, + body: JSON, *, - operation_id: Optional[str] = None, - content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", **kwargs: Any, - ) -> AgentOptimizationLROPoller: ... + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_telephony_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def begin_create_optimization_job( + def update_telephony_binding( # type: ignore[override] + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any, + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. + + Updates a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().update_telephony_binding( # type: ignore[arg-type] + agent_name, binding_id, body, etag=etag, match_condition=match_condition, **kwargs + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def delete_telephony_binding( # type: ignore[override] # pylint: disable=inconsistent-return-statements + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. + + Deletes a telephony binding owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().delete_telephony_binding(agent_name, binding_id, etag=etag, match_condition=match_condition, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def list_telephony_calls( # type: ignore[override] + self, + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after: Optional[datetime.datetime] = None, + started_before: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any, + ) -> ItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. + + Returns the durable inbound call history for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", + "success", and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after: Includes calls that started at or after this Unix timestamp in + seconds. Default value is None. + :paramtype started_after: ~datetime.datetime + :keyword started_before: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before: ~datetime.datetime + :keyword limit: A limit on the number of objects to be returned. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. Known values are: + "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. Default value is None. + :paramtype before: str + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyCallSummary] + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + return super().list_telephony_calls( + agent_name, + provider=provider, + status=status, + started_after=started_after, + started_before=started_before, + limit=limit, + order=order, + before=before, + **kwargs, + ) + + @distributed_trace + def get_telephony_call( # type: ignore[override] + self, agent_name: str, call_id: str, **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Get an agent telephony call. + + Retrieves a durable inbound call record owned by the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().get_telephony_call(agent_name, call_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + def transfer_telephony_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def transfer_telephony_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def transfer_telephony_call( + self, + agent_name: str, + call_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def transfer_telephony_call( # type: ignore[override] + self, + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + target: str = _Unset, + **kwargs: Any, + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. + + Transfers an active inbound call to a configured target for the voice agent named in the + path. When the client is constructed with ``allow_preview=True``, the required preview opt-in + header is added automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().transfer_telephony_call(agent_name, call_id, body, target=target, **kwargs) # type: ignore[misc] + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def end_telephony_call( # type: ignore[override] + self, agent_name: str, call_id: str, **kwargs: Any + ) -> _models.TelephonyCallRecord: + """End an active agent telephony call. + + Ends an active inbound call owned by the voice agent named in the path. When the client is + constructed with ``allow_preview=True``, the required preview opt-in header is added + automatically. + + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().end_telephony_call(agent_name, call_id, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @distributed_trace + def get_telephony_transfer_targets( # type: ignore[override] + self, agent_name: str, **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. + + Returns all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().get_telephony_transfer_targets(agent_name, **kwargs) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + @overload # type: ignore[override] + def replace_telephony_transfer_targets( + self, + agent_name: str, + *, + transfer_targets: List[_models.TelephonyTransferTarget], + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def replace_telephony_transfer_targets( + self, + agent_name: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def replace_telephony_transfer_targets( # type: ignore[override] + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, + etag: str, + match_condition: MatchConditions, + **kwargs: Any, + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. + + Replaces all transfer targets configured for the voice agent named in the path. When the + client is constructed with ``allow_preview=True``, the required preview opt-in header is + added automatically. + + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ + if getattr(self._config, "allow_preview", False): + headers = kwargs.get("headers") + if headers is None: + kwargs["headers"] = {_FOUNDRY_FEATURES_HEADER_NAME: _AGENT_OPERATION_FEATURE_HEADERS} + elif not _has_header_case_insensitive(headers, _FOUNDRY_FEATURES_HEADER_NAME): + headers[_FOUNDRY_FEATURES_HEADER_NAME] = _AGENT_OPERATION_FEATURE_HEADERS + kwargs["headers"] = headers + + try: + return super().replace_telephony_transfer_targets( # type: ignore[arg-type] + agent_name, + body, + transfer_targets=transfer_targets, + etag=etag, + match_condition=match_condition, + **kwargs, + ) + except HttpResponseError as exc: + if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: + api_error_response = exc.model + if hasattr(api_error_response, "error") and api_error_response.error is not None: + if api_error_response.error.code == _PREVIEW_FEATURE_REQUIRED_CODE: + new_exc = HttpResponseError( + message=f"{exc.message} {_PREVIEW_FEATURE_ADDED_ERROR_MESSAGE}", + ) + new_exc.status_code = exc.status_code + new_exc.reason = exc.reason + new_exc.response = exc.response + new_exc.model = exc.model + raise new_exc from exc + raise + + +class BetaAgentsOperations(BetaAgentsOperationsGenerated): + """Custom operations for beta agent optimization jobs.""" + + @overload # type: ignore[override] + def begin_create_optimization_job( + self, + job: _models.AgentOptimizationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AgentOptimizationLROPoller: ... + + @overload + def begin_create_optimization_job( + self, + job: JSON, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AgentOptimizationLROPoller: ... + + @overload + def begin_create_optimization_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any, + ) -> AgentOptimizationLROPoller: ... + + @distributed_trace + def begin_create_optimization_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], *, @@ -423,7 +1387,7 @@ def begin_create_optimization_job( raw_result = None if continuation_token is None: raw_result = self._create_optimization_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_datasets.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_datasets.py index be33b5a2763d..ba17a78777d7 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_datasets.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_datasets.py @@ -12,7 +12,6 @@ import re import logging from typing import Any, IO, Tuple, Optional, Union, cast, overload -from collections.abc import MutableMapping from pathlib import Path from urllib.parse import urlsplit from azure.storage.blob import ContainerClient @@ -23,6 +22,7 @@ from ._operations import ( BetaDatasetsOperations as BetaDatasetsOperationsGenerated, DatasetsOperations as DatasetsOperationsGenerated, + JSON, ) from .. import models as _models from .._utils.model_base import _deserialize @@ -37,13 +37,11 @@ logger = logging.getLogger(__name__) -JSON = MutableMapping[str, Any] - class BetaDatasetsOperations(BetaDatasetsOperationsGenerated): """Custom operations for beta data generation jobs.""" - @overload + @overload # type: ignore[override] def begin_create_generation_job( self, job: _models.DataGenerationJob, @@ -74,7 +72,7 @@ def begin_create_generation_job( ) -> DatasetGenerationLROPoller: ... @distributed_trace - def begin_create_generation_job( + def begin_create_generation_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.DataGenerationJob, JSON, IO[bytes]], *, @@ -103,7 +101,7 @@ def begin_create_generation_job( raw_result = None if continuation_token is None: raw_result = self._create_generation_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluation_rules.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluation_rules.py index 859bea44b87b..76cec35bffe7 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluation_rules.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluation_rules.py @@ -32,7 +32,7 @@ class EvaluationRulesOperations(GeneratedEvaluationRulesOperations): :attr:`evaluation_rules` attribute. """ - @overload + @overload # type: ignore[override] def create_or_update( self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any ) -> _models.EvaluationRule: @@ -90,7 +90,7 @@ def create_or_update( ... @distributed_trace - def create_or_update( + def create_or_update( # type: ignore[override] self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any ) -> _models.EvaluationRule: """Create or update an evaluation rule. @@ -117,7 +117,7 @@ def create_or_update( kwargs["headers"] = headers try: - return super().create_or_update(id, evaluation_rule, **kwargs) + return super().create_or_update(id, evaluation_rule, **kwargs) # type: ignore[arg-type] except HttpResponseError as exc: if exc.status_code == 403 and not self._config.allow_preview and exc.model is not None: api_error_response = exc.model diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluators.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluators.py index 240e6afef83c..3e79ef035f1f 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluators.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluators.py @@ -5,7 +5,6 @@ # ------------------------------------ """Custom evaluator operations.""" -from collections.abc import MutableMapping from typing import Any, IO, Optional, Union, cast, overload from azure.core.polling import NoPolling, PollingMethod @@ -13,18 +12,16 @@ from azure.core.tracing.decorator import distributed_trace from azure.core.utils import case_insensitive_dict -from ._operations import BetaEvaluatorsOperations as BetaEvaluatorsOperationsGenerated +from ._operations import BetaEvaluatorsOperations as BetaEvaluatorsOperationsGenerated, JSON from .. import models as _models from .._utils.model_base import _deserialize from ..models import EvaluatorGenerationLROPoller -JSON = MutableMapping[str, Any] - class BetaEvaluatorsOperations(BetaEvaluatorsOperationsGenerated): """Custom operations for beta evaluator generation jobs.""" - @overload + @overload # type: ignore[override] def begin_create_generation_job( self, job: _models.EvaluatorGenerationJob, @@ -55,7 +52,7 @@ def begin_create_generation_job( ) -> EvaluatorGenerationLROPoller: ... @distributed_trace - def begin_create_generation_job( + def begin_create_generation_job( # type: ignore[reportIncompatibleMethodOverride, override] self, job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], *, @@ -84,7 +81,7 @@ def begin_create_generation_job( raw_result = None if continuation_token is None: raw_result = self._create_generation_job_initial( - job=job, + job=job, # type: ignore[reportArgumentType, arg-type] operation_id=operation_id, content_type=content_type, cls=lambda x, y, z: x, diff --git a/sdk/ai/azure-ai-projects/dev_requirements.txt b/sdk/ai/azure-ai-projects/dev_requirements.txt index 6641c1e8f14a..a8928e8a7c9b 100644 --- a/sdk/ai/azure-ai-projects/dev_requirements.txt +++ b/sdk/ai/azure-ai-projects/dev_requirements.txt @@ -14,6 +14,7 @@ azure-monitor-query jsonref opentelemetry-sdk python-dotenv +websockets>=13.0 black # Can't include those, because they are not supported in Python 3.9. Samples that use these package # cannot be run as pytest, because the pipeline will fail on Python 3.9 jobs. diff --git a/sdk/ai/azure-ai-projects/docs/public-methods.md b/sdk/ai/azure-ai-projects/docs/public-methods.md index c057b80a9581..31296cc83ea0 100644 --- a/sdk/ai/azure-ai-projects/docs/public-methods.md +++ b/sdk/ai/azure-ai-projects/docs/public-methods.md @@ -6,17 +6,19 @@ This document lists all public methods available on `AIProjectClient` and its su ## Summary -There are a total of 157 unique public methods: +There are a total of 196 unique public methods: - 5 stable methods on the client -- 58 stable methods on top-level sub-clients +- 97 stable methods on top-level sub-clients - 94 beta methods on nested beta sub-clients ### Top-level sub-clients (stable operations) | Subclient | Class Name | Methods Count | | --- | --- | --- | -| `agents` | AgentsOperations | 26 | +| `agent_endpoint_conversations` | AgentEndpointConversationsOperations | 14 | +| `agent_telephony` | AgentTelephonyOperations | 13 | +| `agents` | AgentsOperations | 38 | | `connections` | ConnectionsOperations | 3 | | `datasets` | DatasetsOperations | 9 | | `deployments` | DeploymentsOperations | 2 | @@ -59,31 +61,72 @@ Alphabetically sorted. An asterisk at the end of the method name means it is a h Alphabetically sorted. An asterisk at the end of the method name means it is a hand-written method. ```text +.agent_endpoint_conversations.delete_agent_conversation* +.agent_endpoint_conversations.get_agent_conversation* +.agent_endpoint_conversations.get_agent_conversation_audio* +.agent_endpoint_conversations.get_agent_conversation_audio_content* +.agent_endpoint_conversations.get_agent_conversation_item* +.agent_endpoint_conversations.get_agent_conversation_item_audio* +.agent_endpoint_conversations.get_agent_conversation_item_audio_content* +.agent_endpoint_conversations.get_agent_conversation_item_generated_audio* +.agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content* +.agent_endpoint_conversations.get_agent_conversation_response* +.agent_endpoint_conversations.list_agent_conversation_items* +.agent_endpoint_conversations.list_agent_conversation_response_items* +.agent_endpoint_conversations.list_agent_conversation_responses* +.agent_endpoint_conversations.list_agent_conversations* + +.agent_telephony.begin_import_telephony_campaign_recipients +.agent_telephony.begin_publish_telephony_campaign +.agent_telephony.begin_validate_telephony_campaign +.agent_telephony.cancel_telephony_call_job +.agent_telephony.cancel_telephony_campaign +.agent_telephony.create_telephony_call_job +.agent_telephony.create_telephony_campaign +.agent_telephony.get_telephony_call_job +.agent_telephony.get_telephony_campaign +.agent_telephony.get_telephony_campaign_recipient_import +.agent_telephony.get_telephony_operation +.agent_telephony.pause_telephony_campaign +.agent_telephony.resume_telephony_campaign + .agents.create_session +.agents.create_telephony_binding* .agents.create_version* .agents.create_version_from_code* .agents.create_version_from_manifest .agents.delete .agents.delete_session .agents.delete_session_file +.agents.delete_telephony_binding* .agents.delete_version .agents.disable .agents.download_code .agents.download_session_file .agents.enable +.agents.end_telephony_call* +.agents.generate_agent* .agents.get .agents.get_microsoft365_package .agents.get_microsoft365_publish_defaults .agents.get_session .agents.get_session_log_stream +.agents.get_telephony_binding* +.agents.get_telephony_call* +.agents.get_telephony_transfer_targets* .agents.get_version .agents.list .agents.list_session_files .agents.list_sessions +.agents.list_telephony_bindings* +.agents.list_telephony_calls* .agents.list_versions .agents.publish_to_microsoft365 +.agents.replace_telephony_transfer_targets* .agents.stop_session +.agents.transfer_telephony_call* .agents.update_details +.agents.update_telephony_binding* .agents.upload_session_file .connections.get* diff --git a/sdk/ai/azure-ai-projects/pyproject.toml b/sdk/ai/azure-ai-projects/pyproject.toml index dea352a19763..df190df7ce31 100644 --- a/sdk/ai/azure-ai-projects/pyproject.toml +++ b/sdk/ai/azure-ai-projects/pyproject.toml @@ -17,7 +17,7 @@ authors = [ description = "Microsoft Corporation Azure AI Projects Client Library for Python" license = "MIT" classifiers = [ - "Development Status :: 5 - Production/Stable", + "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", @@ -42,6 +42,12 @@ dynamic = [ "version", "readme" ] +[project.optional-dependencies] +realtime = [ + "websockets>=13.0", + "aiohttp>=3.9.0,<4.0.0", +] + [project.urls] repository = "https://aka.ms/azsdk/azure-ai-projects-v2/python/code" diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_async.py b/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_async.py index 8673b7ac284d..c9f48d485b41 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_async.py @@ -161,9 +161,9 @@ async def main(): print(f"Event {event.sequence_number} type '{event.type}'", end="") if ( event.type in ("response.output_item.added", "response.output_item.done") - ) and event.item.type == "workflow_action": # pyright: ignore [reportAttributeAccessIssue] + ) and event.item.type == "workflow_action": # type: ignore[union-attr] # pyright: ignore [reportAttributeAccessIssue] print( - f": item action ID '{event.item.action_id}' is '{event.item.status}' (previous action ID: '{event.item.previous_action_id}')", # pyright: ignore [reportAttributeAccessIssue] + f": item action ID '{event.item.action_id}' is '{event.item.status}' (previous action ID: '{event.item.previous_action_id}')", # type: ignore[union-attr] # pyright: ignore [reportAttributeAccessIssue] end="", ) elif event.type == "response.completed": diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_with_mcp_approval.py b/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_with_mcp_approval.py index 2ef0109250c5..666cfb2bea32 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_with_mcp_approval.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_with_mcp_approval.py @@ -181,9 +181,9 @@ print(f"Event {event.sequence_number} type '{event.type}'", end="") if ( event.type in ("response.output_item.added", "response.output_item.done") - ) and event.item.type == "workflow_action": # pyright: ignore [reportAttributeAccessIssue] + ) and event.item.type == "workflow_action": # type: ignore[union-attr] # pyright: ignore [reportAttributeAccessIssue] print( - f": item action ID '{event.item.action_id}' is '{event.item.status}' (previous action ID: '{event.item.previous_action_id}')", # pyright: ignore [reportAttributeAccessIssue] + f": item action ID '{event.item.action_id}' is '{event.item.status}' (previous action ID: '{event.item.previous_action_id}')", # type: ignore[union-attr] # pyright: ignore [reportAttributeAccessIssue] end="", ) elif ( diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py new file mode 100644 index 000000000000..165e0c86d6a5 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py @@ -0,0 +1,107 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the voice-agent management lifecycle using the + unified Agents API in the Microsoft Foundry Python SDK (azure-ai-projects): + creating a voice agent (with an audio/voice configuration and conversation + storage enabled), retrieving it, listing the voice agents in the project, + creating a new version, disabling/enabling it, and deleting it. + + Voice agents are exposed through `project_client.agents` with + `kind="voice"`, the same surface used for prompt, workflow, hosted, and + external agents. + +USAGE: + python sample_voice_agent_basic.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview + page of your Microsoft Foundry portal. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyVoiceAgent". +""" + +import os +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + AgentKind, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgent" + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + try: + definition = VoiceAgentDefinition( + # `managed` uses a service-hosted model; use `self_deployed` with a Foundry + # deployment name to bring your own model. + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + # Persist conversations so the transcript and audio can be read back later + # (see sample_voice_agent_read_conversation.py). Defaults to False, which stores nothing. + store=True, + ) + + created_version = project_client.agents.create_version(agent_name=agent_name, definition=definition) + print(f"Created voice agent '{agent_name}', version: {created_version.version}") + + agent = project_client.agents.get(agent_name=agent_name) + print(f"Retrieved voice agent: {agent.name} (state={agent.state})") + + print("Voice agents in this project:") + for item in project_client.agents.list(kind=AgentKind.VOICE): + print(f" - {item.name}") + + # Each update produces a new immutable version. + updated_version = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Always greet the caller warmly.", + audio=definition.audio, + output_modalities=definition.output_modalities, + store=definition.store, + ), + description="Updated instructions.", + ) + print(f"Updated voice agent to version: {updated_version.version}") + + # Disable the agent so its endpoint rejects new requests, then re-enable it. + project_client.agents.disable(agent_name=agent_name) + print("Disabled voice agent") + project_client.agents.enable(agent_name=agent_name) + print("Enabled voice agent") + finally: + project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py new file mode 100644 index 000000000000..dcb227097034 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py @@ -0,0 +1,73 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the voice-agent management lifecycle using the + asynchronous AIProjectClient: creating a voice agent, retrieving it, + listing the voice agents in the project, and deleting it. + +USAGE: + python sample_voice_agent_basic_async.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" aiohttp python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview + page of your Microsoft Foundry portal. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyVoiceAgentAsync". +""" + +import asyncio +import os +from dotenv import load_dotenv +from azure.identity.aio import DefaultAzureCredential +from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import AgentKind, VoiceAgentDefinition, VoiceModelType + +load_dotenv() + + +async def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgentAsync" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + try: + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + # Persist conversations so they can be read back later. Defaults to False. + store=True, + ), + ) + print(f"Created voice agent '{agent_name}', version: {created_version.version}") + + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Retrieved voice agent: {agent.name}") + + print("Voice agents in this project:") + async for item in project_client.agents.list(kind=AgentKind.VOICE): + print(f" - {item.name}") + finally: + await project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py new file mode 100644 index 000000000000..dcb3ec7e2ddb --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py @@ -0,0 +1,66 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates guided authoring: generating and creating a voice + agent through `POST /agents:generate` (`project_client.agents.generate_agent`) + with `kind="voice"`. The service creates a voice agent with a + service-selected starter definition, which is fully editable afterward + through the standard create_version/update flow. + +USAGE: + python sample_voice_agent_generate.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyGeneratedVoiceAgent". +""" + +import os +import sys +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import AgentKind, GenerateVoiceAgentRequest + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The instructions below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyGeneratedVoiceAgent" + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + agent = project_client.agents.generate_agent(GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name)) + print(f"Generated voice agent: {agent.name}") + _safe_print(f"Instructions:\n{agent.versions.latest.definition.instructions}") # type: ignore[attr-defined] + + project_client.agents.delete(agent_name=agent.name) + print(f"Deleted voice agent: {agent.name}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py new file mode 100644 index 000000000000..f103671947ae --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py @@ -0,0 +1,416 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end hands-free, bidirectional voice conversation using the + ``client.realtime`` namespace added on top of the generated + azure-ai-projects client (see ``azure.ai.projects.aio.AsyncRealtime``). + This mirrors the ergonomics of the OpenAI Python realtime client. + + 1. Generate a starter voice agent (see sample_voice_agent_generate.py), + then publish a version with `store=True` so the conversation can be + read back afterward. + 2. Stream live mic audio and let the agent's server-side VAD detect your + turns: your speech is transcribed, the agent replies through the + speakers, and talking over it barges in. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Capture and playback use non-blocking pyaudio callbacks; reply audio is + sequence-numbered so a barge-in can skip whatever is still queued. The + agent owns turn detection and noise suppression server-side. Use a headset + to avoid echo. + + Mic audio is sent as base64 PCM16; the reply arrives as typed + ``response.output_audio.*`` events, decoded to PCM16, mono, 24 kHz. + Requires ``aiohttp`` and ``pyaudio``. + + pip install "azure-ai-projects>=2.0.0" azure-identity aiohttp pyaudio + +USAGE: + python sample_voice_agent_live_audio_conversation_async.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-audio-conversation-agent-async". + + Runs until you press Ctrl-C. Authenticates with DefaultAzureCredential, so + sign in first (e.g. `az login`). +""" + +import asyncio +import concurrent.futures +import os +import queue +import sys +from typing import Any, Final, Optional + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity.aio import DefaultAzureCredential + +# AsyncRealtimeConnection is re-exported dynamically via aio/_patch.py's `__all__`; pylint's +# static import resolution cannot trace that, but the symbol is valid (verified by Pyright/mypy). +from azure.ai.projects.aio import AsyncRealtimeConnection, AIProjectClient # pylint: disable=no-name-in-module +from azure.ai.projects.models import ( + AgentKind, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, +) + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Audio is streamed both ways as PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + +# pyaudio callback buffer size (~50 ms of PCM16 audio per callback). +_CHUNK_SAMPLES: Final = 1200 + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - required audio dependency + pyaudio: Any = None # type: ignore[no-redef] + + +class _AudioProcessor: # pylint: disable=too-many-instance-attributes + """Real-time mic capture and speaker playback via non-blocking pyaudio callbacks. + + * Capture appends each raw PCM16 frame to the input buffer (the realtime + client base64-encodes it). + * Playback pulls sequence-numbered PCM16 from a queue, always returning the + exact sample count pyaudio asked for (a wrong size corrupts audio). + * ``skip_pending_audio`` bumps a base sequence number so audio queued before + a barge-in is dropped, stopping playback the instant the user speaks. + """ + + def __init__(self, connection: "AsyncRealtimeConnection") -> None: + self._conn = connection + self._loop: Optional[asyncio.AbstractEventLoop] = None + self._audio = pyaudio.PyAudio() + + # Playback with sequence numbers for interrupt handling. + self._playback_queue: "queue.Queue[tuple[int, Optional[bytes]]]" = queue.Queue() + self._playback_base = 0 + self._next_seq = 0 + self._bytes = 0 + + # Bounds capture backpressure to a single in-flight send (see start_capture). + self._pending_send: "Optional[concurrent.futures.Future[None]]" = None + self._dropped_frames = 0 + + self._input_stream = None + self._output_stream = None + + # -- capture ----------------------------------------------------------- + + def start_capture(self) -> None: + """Start streaming microphone audio to the service via a callback.""" + if self._input_stream is not None: + return + self._loop = asyncio.get_running_loop() + + def _capture_callback(in_data, _frame_count, _time_info, _status): + # Runs on a pyaudio thread: hand the frame to the event loop to append. Each call + # schedules a coroutine on the loop via a thread-safe handoff; if sending falls + # behind real-time capture (for example, network backpressure on the WebSocket), + # unconditionally scheduling a new one every callback would let pending sends + # accumulate without bound. Instead, only keep at most one in flight and drop + # (skip sending) this frame if the previous send hasn't completed yet. + assert self._loop is not None + if self._pending_send is not None and not self._pending_send.done(): + self._dropped_frames += 1 + return (None, pyaudio.paContinue) + self._pending_send = asyncio.run_coroutine_threadsafe( + self._conn.input_audio_buffer.append(audio=in_data), self._loop + ) + return (None, pyaudio.paContinue) + + self._input_stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + input=True, + frames_per_buffer=_CHUNK_SAMPLES, + stream_callback=_capture_callback, + ) + + # -- playback ------------------------------------------------------------ + + def start_playback(self) -> None: + """Initialize the speaker playback callback.""" + if self._output_stream is not None: + return + remaining = b"" + # The sequence number the currently-buffered `remaining` bytes were dequeued from, so a + # barge-in that lands *between* callback invocations can still discard them below. + remaining_seq = -1 + + def _playback_callback(_in_data, frame_count, _time_info, _status): + nonlocal remaining, remaining_seq + if remaining and remaining_seq < self._playback_base: + remaining = b"" # a barge-in advanced the base since this chunk was dequeued + + wanted = frame_count * pyaudio.get_sample_size(pyaudio.paInt16) + out = remaining[:wanted] + remaining = remaining[wanted:] + + while len(out) < wanted: + try: + seq, data = self._playback_queue.get_nowait() + except queue.Empty: + out = out + bytes(wanted - len(out)) # pad with silence + continue + if not data: + # end-of-stream marker: pad up to the exact frame size pyaudio asked for + # instead of returning a short buffer, which would corrupt playback on close. + out = out + bytes(wanted - len(out)) + break + if seq < self._playback_base: + remaining = b"" # skipped by a barge-in + continue + take = wanted - len(out) + out = out + data[:take] + remaining = data[take:] + remaining_seq = seq + + return (out, pyaudio.paContinue) + + self._output_stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + frames_per_buffer=_CHUNK_SAMPLES, + stream_callback=_playback_callback, + ) + + def _next_seq_num(self) -> int: + seq = self._next_seq + self._next_seq += 1 + return seq + + def queue_audio(self, pcm: bytes) -> None: + """Queue one decoded PCM16 chunk of the agent's reply for playback. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._bytes += len(pcm) + self._playback_queue.put((self._next_seq_num(), pcm)) + + def skip_pending_audio(self) -> None: + """Drop audio still queued for playback (used on barge-in).""" + self._playback_base = self._next_seq_num() + + def shutdown(self) -> None: + """Stop capture and playback and release the audio device.""" + if self._input_stream is not None: + self._input_stream.stop_stream() + self._input_stream.close() + self._input_stream = None + if self._dropped_frames: + print(f"(dropped {self._dropped_frames} mic frame(s) while a send was still in flight)") + if self._output_stream is not None: + self.skip_pending_audio() + self._playback_queue.put((self._next_seq_num(), None)) + self._output_stream.stop_stream() + self._output_stream.close() + self._output_stream = None + self._audio.terminate() + + @property + def seconds(self) -> float: + """Total reply audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._bytes / 2 / _SAMPLE_RATE + + +async def _run_audio_conversation(client: AIProjectClient, agent_name: str) -> Optional[str]: + """Hold a live, hands-free conversation with barge-in. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + if pyaudio is None: + print("This sample needs pyaudio for audio: pip install pyaudio") + return None + + conversation_id: Optional[str] = None + response_active = False + + # Open the realtime session on the voice agent's dedicated route. + async with client.realtime.connect(agent_name=agent_name) as conn: + # A voice agent owns its model, instructions, voice, turn detection, and + # noise suppression server-side, so this client sends no ``session.update``. + ap = _AudioProcessor(conn) + ap.start_playback() + ap.start_capture() + + print("Speak now -- the agent replies after you pause.") + print("(talk over the agent to interrupt it; press Ctrl-C to end the session)") + + try: + async for event in conn: + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + elif isinstance(event, RealtimeServerEventInputAudioBufferSpeechStarted): + # speech_started fires for every user turn, including the very first one, + # when no response is active yet. Only cancel (barge-in) if a response is + # actually in flight; canceling with none active is a service error. + if response_active: + await conn.response.cancel() + ap.skip_pending_audio() + print("(listening...)") + elif isinstance(event, RealtimeServerEventConversationItemInputAudioTranscriptionCompleted): + print(f"You: {event.transcript.strip()}") + elif isinstance(event, RealtimeServerEventError): + # Non-fatal errors are reported; a fatal one closes the socket. + print(f"Session error: {event.error.message}") + elif isinstance(event, RealtimeServerEventResponseCreated): + response_active = True + elif isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; queue it. + ap.queue_audio(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + elif isinstance(event, RealtimeServerEventResponseDone): + response_active = False + except (KeyboardInterrupt, asyncio.CancelledError): + # Ctrl-C ends the session; read back whatever was persisted so far. + print("\n(ending session...)") + finally: + print(f"(received {ap.seconds:.2f}s of reply audio this session)") + ap.shutdown() + + return conversation_id + + +async def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.agent_endpoint_conversations + + conversation = await conversations.get_agent_conversation(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + async for item in conversations.list_agent_conversation_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +async def audio_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-audio-conversation-agent-async" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + try: + # 1) Generate a starter voice agent (see sample_voice_agent_generate.py). + generated = await project_client.agents.generate_agent( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + definition = generated.versions.latest.definition # type: ignore[attr-defined] + + # 2) Publish a new version with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=definition.model_type, # type: ignore[attr-defined] + model=definition.model, # type: ignore[attr-defined] + instructions=definition.instructions, # type: ignore[attr-defined] + store=True, + ), + ) + + # 3) Hold a live microphone conversation with the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = await _run_audio_conversation(project_client, agent_name) + + # 4) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id!r}...") + try: + await _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.agent_endpoint_conversations`: + # - get_agent_conversation_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # get_agent_conversation_audio_content(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_agent_conversation_item_audio(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # get_agent_conversation_item_audio_content(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 5) Clean up the agent created for this sample. + await project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") + + +if __name__ == "__main__": + try: + asyncio.run(audio_conversation()) + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py new file mode 100644 index 000000000000..1386c85401a3 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py @@ -0,0 +1,194 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates handling a client-executed `function` tool during + a live voice-agent session: + + 1) Create a voice agent configured with a `get_weather` function tool. + 2) Open a realtime session and send a text turn that should trigger the tool. + 3) Listen for `response.function_call_arguments.done`, execute the function + locally, and send the result back with `conversation.item.create` + + `response.create` so the agent can finish its reply using the tool output. + +USAGE: + python sample_voice_agent_live_function_tool.py + + Before running the sample: + + pip install "azure-ai-projects[realtime]>=2.0.0" azure-identity python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the sample voice agent + created and deleted by this script. Defaults to + "sample-voice-agent-function-tool". +""" + +import json +import os +import sys +from typing import Any, Final, cast + +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + VoiceModelType, + VoiceOutputModality, +) + +load_dotenv() + +# Seconds to wait for the agent to finish a response. +_RESPONSE_TIMEOUT: Final = 45 + + +def get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's reply below is model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +def _run_turn_with_tool_support(client: AIProjectClient, agent_name: str, prompt: str) -> None: + """Send one turn and resolve any function-call the agent makes before printing its reply. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param prompt: The user's message for this turn. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type prompt: str + """ + with client.realtime.connect(agent_name=agent_name) as conn: + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + conn.response.create() + + while True: + try: + event = conn.recv(timeout=_RESPONSE_TIMEOUT) + except TimeoutError: + print("Timed out waiting for the agent's reply.") + conn.response.cancel() + return + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + # The service forwards the call to us; execute it locally and + # send the result back so the agent can use it in its reply. + args = json.loads(event.arguments) + print(f"Tool call: {event.name}({args})") + if event.name == "get_weather": + result = get_weather(**args) + else: + result = json.dumps({"error": f"Unknown tool: {event.name}"}) + + conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=event.call_id, output=result) + ) + conn.response.create() + elif isinstance(event, RealtimeServerEventResponseTextDone): + # The sample agent uses a text-only output modality, so the + # reply arrives as output text rather than an audio transcript. + _safe_print(f"Agent: {event.text}") + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't a function call is the final answer for this turn. + # Output items are typed models in the tested scenarios here, but the underlying + # union is open (forward-compatible with item kinds this SDK doesn't map yet), so + # an unrecognized kind could still surface as a plain mapping; check both. + if not any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) == "function_call" + for item in (event.response.output or []) + ): + return + elif isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + + +def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-voice-agent-function-tool" + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + try: + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + print(f"Created voice agent: {agent_name}") + + _run_turn_with_tool_support(project_client, agent_name, "What's the weather like in Seattle right now?") + finally: + project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") + + +if __name__ == "__main__": + main() diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py new file mode 100644 index 000000000000..b9c481e01ae6 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py @@ -0,0 +1,311 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end typed conversation using the ``client.realtime`` namespace added + on top of the generated azure-ai-projects client (see + ``azure.ai.projects.Realtime``). + + 1. Generate a starter voice agent (see sample_voice_agent_generate.py), + then publish a version with `store=True` so the conversation can be + read back afterward. + 2. Hold a typed, multi-turn conversation: each prompt is sent as a + ``RealtimeConversationItemMessageUser`` and the reply streams back as + typed audio and transcript events. Blank line (or ``exit`` / ``quit``) + ends it. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Reply audio is PCM16, mono, 24 kHz and plays through the speakers when + ``pyaudio`` is installed; runs headless otherwise. For a hands-free mic + conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py + (that sample needs concurrent send/receive so it stays async-only; see + sample_voice_agent_live_text_conversation_async.py for the async version of + this one). + + pip install "azure-ai-projects[realtime]>=2.0.0" azure-identity pyaudio + +USAGE: + python sample_voice_agent_live_text_conversation.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-text-conversation-agent". + + Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`). +""" + +import os +import sys +from typing import Final, Optional + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + AgentKind, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, +) + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Seconds to wait for the agent to finish its reply. +_RESPONSE_TIMEOUT: Final = 45 + +# Reply audio format: PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - optional playback dependency + pyaudio = None # type: ignore[assignment] + + +class _SpeakerPlayer: + """Play streamed PCM16 audio through the speakers with pyaudio. + + Optional: without pyaudio the player is a no-op and the sample still runs + headless, reporting how much audio it received. + """ + + def __init__(self) -> None: + self._audio = None + self._stream = None + self._bytes = 0 + if pyaudio is not None: + self._audio = pyaudio.PyAudio() + self._stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + ) + + @property + def enabled(self) -> bool: + return self._stream is not None + + def play(self, pcm: bytes) -> None: + """Write one decoded PCM16 chunk to the speaker. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._bytes += len(pcm) + if self._stream is not None: + self._stream.write(pcm) + + def close(self) -> None: + """Drain and release the audio device.""" + if self._stream is not None: + self._stream.stop_stream() + self._stream.close() + self._stream = None + if self._audio is not None: + self._audio.terminate() + self._audio = None + + @property + def seconds(self) -> float: + """Total audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._bytes / 2 / _SAMPLE_RATE + + +def _run_text_conversation(client: AIProjectClient, agent_name: str) -> Optional[str]: + """Hold a typed, multi-turn conversation. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + conversation_id: Optional[str] = None + audio_delta_count = 0 + player = _SpeakerPlayer() + played = False + + try: + # Open the realtime session on the voice agent's dedicated route. + with client.realtime.connect(agent_name=agent_name) as conn: + print("Type a message and press Enter. Blank line (or 'exit') ends the session.") + + def pump() -> None: + nonlocal conversation_id, audio_delta_count + while True: + try: + event = conn.recv(timeout=_RESPONSE_TIMEOUT) + except TimeoutError: + print("Timed out waiting for the agent's reply.") + conn.response.cancel() + return + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + if isinstance(event, RealtimeServerEventResponseDone): + return + if isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + if isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; play it. + audio_delta_count += 1 + player.play(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + + while True: + prompt = input("You: ").strip() + if not prompt or prompt.lower() in ("exit", "quit"): + break + + # Send the turn and ask the agent to respond. + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + conn.response.create() + pump() + except KeyboardInterrupt: + print("\n(ending session...)") + finally: + played = player.enabled + player.close() + + detail = "played" if played else "received" + print(f"(streamed {audio_delta_count} audio chunks, {detail} {player.seconds:.2f}s of audio)") + if not played: + print("(install pyaudio to hear the reply: pip install pyaudio)") + return conversation_id + + +def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.agent_endpoint_conversations + + conversation = conversations.get_agent_conversation(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + for item in conversations.list_agent_conversation_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +def text_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent" + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + try: + # 1) Generate a starter voice agent (see sample_voice_agent_generate.py). + generated = project_client.agents.generate_agent( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + definition = generated.versions.latest.definition # type: ignore[attr-defined] + + # 2) Publish a new version with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=definition.model_type, # type: ignore[attr-defined] + model=definition.model, # type: ignore[attr-defined] + instructions=definition.instructions, # type: ignore[attr-defined] + store=True, + ), + ) + + # 3) Hold the realtime conversation against the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = _run_text_conversation(project_client, agent_name) + + # 4) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id}...") + try: + _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.agent_endpoint_conversations`: + # - get_agent_conversation_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # get_agent_conversation_audio_content(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_agent_conversation_item_audio(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # get_agent_conversation_item_audio_content(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 5) Clean up the agent created for this sample. + project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") + + +if __name__ == "__main__": + try: + text_conversation() + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py new file mode 100644 index 000000000000..6a2244451b55 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py @@ -0,0 +1,310 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end typed conversation using the ``client.realtime`` namespace added + on top of the generated azure-ai-projects client (see + ``azure.ai.projects.aio.AsyncRealtime``). + + 1. Generate a starter voice agent (see sample_voice_agent_generate.py), + then publish a version with `store=True` so the conversation can be + read back afterward. + 2. Hold a typed, multi-turn conversation: each prompt is sent as a + ``RealtimeConversationItemMessageUser`` and the reply streams back as + typed audio and transcript events. Blank line (or ``exit`` / ``quit``) + ends it. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Reply audio is PCM16, mono, 24 kHz and plays through the speakers when + ``pyaudio`` is installed; runs headless otherwise. For a hands-free mic + conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py. + + pip install "azure-ai-projects>=2.0.0" azure-identity aiohttp pyaudio + +USAGE: + python sample_voice_agent_live_text_conversation_async.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-text-conversation-agent-async". + + Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`). +""" + +import asyncio +import os +import sys +from typing import Final, Optional + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity.aio import DefaultAzureCredential +from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import ( + AgentKind, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, +) + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Seconds to wait for the agent to finish its reply. +_RESPONSE_TIMEOUT: Final = 45 + +# Reply audio format: PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - optional playback dependency + pyaudio = None # type: ignore[assignment] + + +class _SpeakerPlayer: + """Play streamed PCM16 audio through the speakers with pyaudio. + + Optional: without pyaudio the player is a no-op and the sample still runs + headless, reporting how much audio it received. + """ + + def __init__(self) -> None: + self._audio = None + self._stream = None + self._bytes = 0 + if pyaudio is not None: + self._audio = pyaudio.PyAudio() + self._stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + ) + + @property + def enabled(self) -> bool: + return self._stream is not None + + def play(self, pcm: bytes) -> None: + """Write one decoded PCM16 chunk to the speaker. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._bytes += len(pcm) + if self._stream is not None: + self._stream.write(pcm) + + def close(self) -> None: + """Drain and release the audio device.""" + if self._stream is not None: + self._stream.stop_stream() + self._stream.close() + self._stream = None + if self._audio is not None: + self._audio.terminate() + self._audio = None + + @property + def seconds(self) -> float: + """Total audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._bytes / 2 / _SAMPLE_RATE + + +async def _run_text_conversation(client: AIProjectClient, agent_name: str) -> Optional[str]: + """Hold a typed, multi-turn conversation. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + conversation_id: Optional[str] = None + audio_delta_count = 0 + player = _SpeakerPlayer() + + try: + # Open the realtime session on the voice agent's dedicated route. + async with client.realtime.connect(agent_name=agent_name) as conn: + print("Type a message and press Enter. Blank line (or 'exit') ends the session.") + + async def pump() -> None: + nonlocal conversation_id, audio_delta_count + async for event in conn: + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + if isinstance(event, RealtimeServerEventResponseDone): + return + if isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + if isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; play it. + audio_delta_count += 1 + player.play(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + + while True: + # input() blocks, so read it off the loop in a worker thread. + prompt = (await asyncio.to_thread(input, "You: ")).strip() + if not prompt or prompt.lower() in ("exit", "quit"): + break + + # Send the turn and ask the agent to respond. + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + await conn.response.create() + + try: + await asyncio.wait_for(pump(), timeout=_RESPONSE_TIMEOUT) + except asyncio.TimeoutError: + print("Timed out waiting for the agent's reply.") + # The server-side response is still active even though we stopped waiting + # locally; cancel it so the next turn's response.create() isn't rejected. + await conn.response.cancel() + except (KeyboardInterrupt, asyncio.CancelledError): + print("\n(ending session...)") + finally: + played = player.enabled + player.close() + + detail = "played" if played else "received" + print(f"(streamed {audio_delta_count} audio chunks, {detail} {player.seconds:.2f}s of audio)") + if not played: + print("(install pyaudio to hear the reply: pip install pyaudio)") + return conversation_id + + +async def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.agent_endpoint_conversations + + conversation = await conversations.get_agent_conversation(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + async for item in conversations.list_agent_conversation_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +async def text_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent-async" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + try: + # 1) Generate a starter voice agent (see sample_voice_agent_generate.py). + generated = await project_client.agents.generate_agent( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + definition = generated.versions.latest.definition # type: ignore[attr-defined] + + # 2) Publish a new version with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=definition.model_type, # type: ignore[attr-defined] + model=definition.model, # type: ignore[attr-defined] + instructions=definition.instructions, # type: ignore[attr-defined] + store=True, + ), + ) + + # 3) Hold the realtime conversation against the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = await _run_text_conversation(project_client, agent_name) + + # 4) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id}...") + try: + await _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.agent_endpoint_conversations`: + # - get_agent_conversation_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # get_agent_conversation_audio_content(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_agent_conversation_item_audio(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # get_agent_conversation_item_audio_content(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 5) Clean up the agent created for this sample. + await project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") + + +if __name__ == "__main__": + try: + asyncio.run(text_conversation()) + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py new file mode 100644 index 000000000000..0e77a4836b42 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py @@ -0,0 +1,88 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates reading a persisted voice conversation back over + the read-only conversation API exposed by `project_client.agent_endpoint_conversations`: + the conversation envelope, its responses (model inference turns), and its + ordered items (the transcript). Conversations are created and written by + the voice orchestrator during a live session; this client can only read + them, and only when the agent was configured with `store=True` (see + sample_voice_agent_basic.py). + +USAGE: + python sample_voice_agent_read_conversation.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - The name of the voice agent. + 3) FOUNDRY_VOICE_CONVERSATION_ID - The id of a persisted conversation + (captured from the `conversation.created` event during a live session, + see sample_voice_agent_live_audio_conversation_async.py). +""" + +import os +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ["FOUNDRY_VOICE_AGENT_NAME"] +conversation_id = os.environ["FOUNDRY_VOICE_CONVERSATION_ID"] + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + conversations = project_client.agent_endpoint_conversations + try: + # The conversation envelope: status, timestamps, aggregate usage. + conversation = conversations.get_agent_conversation(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + # The responses (model inference turns) in the conversation. + print("Responses:") + for response in conversations.list_agent_conversation_responses(agent_name, conversation_id): + print(f" - {response.id}: status={response.status}") + + # Read a single response back, with its output and token usage. + detail = conversations.get_agent_conversation_response(agent_name, conversation_id, response.id) + print(f" usage={detail.usage}") + + # The items produced by this specific response. Conversation items + # belong to an open union, so on read they surface as mappings + # keyed by their wire fields (``type``, ``id``, ...). + for response_item in conversations.list_agent_conversation_response_items( + agent_name, conversation_id, response.id + ): + print(f" item {response_item.get('type')} id={response_item.get('id')}") + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + print("Items (transcript):") + for item in conversations.list_agent_conversation_items(agent_name, conversation_id): + item_id = item.get("id") + print(f" - {item.get('type')} id={item_id}") + + # Read a single item back by id. + if item_id: + single = conversations.get_agent_conversation_item(agent_name, conversation_id, item_id) + print(f" fetched item id={single.get('id')}") + + # Deleting a conversation removes it and all of its responses, items, and audio. + # This is destructive, so it is shown but not run by default. Uncomment to enable. + # deleted = conversations.delete_agent_conversation(agent_name, conversation_id) + # print(f"Deleted conversation {deleted.id}: deleted={deleted.deleted}") + except HttpResponseError as e: + # 404 typically means the conversation was not persisted (agent ran with `store=False`). + print(f"Service responded with an error: {e.status_code} {e.reason}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py new file mode 100644 index 000000000000..c44f00090926 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py @@ -0,0 +1,136 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates reading the persisted audio of a voice + conversation via `project_client.agent_endpoint_conversations`, both the + merged whole-call recording and a single turn's audio segment. For each it + reads the metadata first, then streams the WAV bytes to a local file. The + merged recording is stereo: the caller on the left channel and the agent + on the right. + + Audio is available only after the session has ended and only when the + agent was configured with `store=True`. For bring-your-own-storage (BYOS) + accounts the metadata carries a `blob_uri` instead, and the bytes are read + from your own storage rather than streamed here. + +USAGE: + python sample_voice_agent_read_conversation_audio.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - The name of the voice agent. + 3) FOUNDRY_VOICE_CONVERSATION_ID - The id of a persisted conversation. +""" + +import os +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient + +load_dotenv() + + +def stream_to_wav(stream, output_path) -> None: + """Write a streamed audio-content response to a local WAV file. + + :param stream: An iterable of audio byte chunks. + :param output_path: The local output path. + :type stream: collections.abc.Iterable[bytes] + :type output_path: str + """ + with open(output_path, "wb") as f: + for chunk in stream: + f.write(chunk) + print(f"Wrote {output_path}") + + +def read_merged_recording(conversations, agent_name, conversation_id) -> None: + """Read the merged whole-call stereo recording (left=user, right=agent). + + :param conversations: The conversation operations client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type conversations: azure.ai.projects.operations.AgentEndpointConversationsOperations + :type agent_name: str + :type conversation_id: str + """ + recording = conversations.get_agent_conversation_audio(agent_name, conversation_id) + print( + f"Recording: format={recording.format}, sample_rate={recording.sample_rate}, " + f"channels={recording.channels}, duration_ms={recording.duration_ms}" + ) + + if recording.blob_uri: + # Bring-your-own-storage: download from your own storage using the returned URI. + print(f"Recording is stored in your own storage at: {recording.blob_uri}") + return + + # Foundry-managed storage: stream the bytes and write them to a local WAV file. + stream = conversations.get_agent_conversation_audio_content(agent_name, conversation_id) + stream_to_wav(stream, f"{conversation_id}.wav") + + +def read_first_item_audio(conversations, agent_name, conversation_id) -> None: + """Read the audio segment of the first conversation item that has one. + + :param conversations: The conversation operations client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type conversations: azure.ai.projects.operations.AgentEndpointConversationsOperations + :type agent_name: str + :type conversation_id: str + """ + for item in conversations.list_agent_conversation_items(agent_name, conversation_id): + item_id = item.get("id") + if not item_id: + continue + try: + metadata = conversations.get_agent_conversation_item_audio(agent_name, conversation_id, item_id) + except HttpResponseError as e: + # A 404 means this item has no persisted audio (for example, a text-only turn). + if e.status_code == 404: + continue + raise + + print(f"Item {item_id}: role={metadata.role}, duration_ms={metadata.duration_ms}") + if metadata.blob_uri: + print(f"Item audio is stored in your own storage at: {metadata.blob_uri}") + return + + stream = conversations.get_agent_conversation_item_audio_content(agent_name, conversation_id, item_id) + stream_to_wav(stream, f"{conversation_id}_{item_id}.wav") + return + + print("No conversation item with audio was found.") + + +def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + agent_name = os.environ["FOUNDRY_VOICE_AGENT_NAME"] + conversation_id = os.environ["FOUNDRY_VOICE_CONVERSATION_ID"] + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + conversations = project_client.agent_endpoint_conversations + try: + read_merged_recording(conversations, agent_name, conversation_id) + read_first_item_audio(conversations, agent_name, conversation_id) + except HttpResponseError as e: + # 404: not persisted / not ready. 409: session still in progress. + print(f"Service responded with an error: {e.status_code} {e.reason}") + + +if __name__ == "__main__": + main() diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py new file mode 100644 index 000000000000..d2d6c05ada6b --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py @@ -0,0 +1,92 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates working with voice-agent versions. Agents are + immutable: every `create_version` call produces a new version. This sample + creates an agent, adds a new version to it, adds a draft version, lists the + versions, and reads a single version back. + +USAGE: + python sample_voice_agent_versions.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "sample-versioned-voice-agent". +""" + +import os +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import VoiceAgentDefinition, VoiceModelType + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-versioned-voice-agent" + + +def make_definition(instructions: str) -> VoiceAgentDefinition: + # Each version differs only by its instructions; the rest is identical. + return VoiceAgentDefinition(model_type=VoiceModelType.MANAGED, model=model, instructions=instructions) + + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + try: + # Create the initial agent (this is version 1). + created = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + print(f"Created agent '{agent_name}', version: {created.version}") + + # Create a new version with updated instructions. + new_version = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + description="Added a personalized greeting.", + ) + print(f"Created new version: {new_version.version}") + + # Create a draft version. Drafts are recorded but excluded from the default + # 'latest' resolution and from version listings unless include_drafts=True. + draft_version = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Experimental draft persona."), + description="Candidate persona under review.", + draft=True, + ) + print(f"Created draft version: {draft_version.version}") + + # List released versions (drafts excluded by default). + print(f"Released versions of '{agent_name}':") + for version in project_client.agents.list_versions(agent_name=agent_name): + print(f" - version {version.version} (created_at={version.created_at})") + + # List including drafts. + print(f"All versions of '{agent_name}' (including drafts):") + for version in project_client.agents.list_versions(agent_name=agent_name, include_drafts=True): + print(f" - version {version.version} (draft={version.draft})") + + # Read a single version back. + fetched = project_client.agents.get_version(agent_name=agent_name, agent_version=new_version.version) + print(f"Fetched version {fetched.version}: {fetched.definition.instructions}") # type: ignore[attr-defined] + finally: + project_client.agents.delete(agent_name=agent_name) + print(f"Deleted agent: {agent_name}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py new file mode 100644 index 000000000000..02d923b02810 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py @@ -0,0 +1,147 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the richer parts of a voice agent definition: + + * Input (microphone) audio configuration: audio format, server-side turn + detection (VAD), input-audio transcription. + * Tools the agent may use during a live session: a client-executed + `function` tool and a service-managed `system` control tool (`mcp` and + `toolbox` tools are shown as constructed objects for illustration). + * Bring-your-own-model (BYOM): set `model_type="self_deployed"` to point + the agent at your own Foundry model deployment instead of a + service-managed model. + +USAGE: + python sample_voice_agent_with_tools.py + + Before running the sample: + + pip install "azure-ai-projects>=2.0.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model (managed) or the + Foundry deployment name (BYOM). Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_MODEL_TYPE - Optional. "managed" (default) for a + service-hosted model, or "self_deployed" to bring your own deployment. + 4) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "sample-voice-agent-with-tools". +""" + +import os +from typing import Any, cast + +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeAudioFormatsAudioPcm, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceAgentMcpTool, + VoiceAgentAudioConfig, + VoiceAgentAudioInputConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentInputTranscription, + VoiceAgentInputTranscriptionModel, + VoiceModelType, + VoiceOutputModality, + VoiceAgentServerVadTurnDetection, + VoiceAgentSystemTool, + VoiceAgentSystemToolName, + VoiceAgentToolboxTool, + VoiceType, +) + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +# "managed" runs a service-hosted model; "self_deployed" (BYOM) uses your own +# Foundry deployment named by `model`. The service derives whether the model is +# realtime or cascaded; you don't set that here. +model_type = os.environ.get("FOUNDRY_VOICE_MODEL_TYPE") or VoiceModelType.MANAGED +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-voice-agent-with-tools" + +# A client-executed tool: the service forwards the function call to your app, +# and your app returns the result over the live session. +get_weather = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), +) + +# A service-managed control tool: the platform can end the call on the agent's behalf. +end_call = VoiceAgentSystemTool(name=VoiceAgentSystemToolName.END_CONVERSATION) + +# An MCP tool is executed by the service against a remote MCP server you own. +# It references an external server, so it is constructed here for illustration +# and not attached below. Provide one of server_url, connector_id, or tunnel_id. +_example_mcp_tool = VoiceAgentMcpTool( + server_label="my-mcp-server", + server_url="https://example.com/mcp", + require_approval="never", +) + +# A toolbox tool references a versioned Foundry toolbox you have created. It is +# constructed here for illustration; attach it only if the toolbox exists. +_example_toolbox_tool = VoiceAgentToolboxTool(toolbox_name="my-toolbox", toolbox_version="1") + +definition = VoiceAgentDefinition( + model_type=model_type, + model=model, + instructions="You are a helpful voice assistant. Use tools when they help answer the caller.", + audio=VoiceAgentAudioConfig( + # Input (microphone) side: 24 kHz PCM, server-side VAD so the agent + # auto-responds when the caller stops speaking, plus input-audio + # transcription so user speech is transcribed. + input=VoiceAgentAudioInputConfig( + format=RealtimeAudioFormatsAudioPcm(rate=24000), + turn_detection=VoiceAgentServerVadTurnDetection( + threshold=0.5, + prefix_padding_ms=300, + silence_duration_ms=500, + ), + transcription=VoiceAgentInputTranscription(model=VoiceAgentInputTranscriptionModel.WHISPER1), + ), + # Output (agent speech) side: the voice the agent speaks with. + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + # Attach the self-contained tools. `_example_mcp_tool` and `_example_toolbox_tool` + # reference external resources you must own, so they are left out here. + tools=[get_weather, end_call], + store=True, +) + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + try: + created_version = project_client.agents.create_version(agent_name=agent_name, definition=definition) + print(f"Created voice agent '{agent_name}' (model_type={model_type}, model={model})") + + agent_version = project_client.agents.get_version(agent_name=agent_name, agent_version=created_version.version) + tools = agent_version.definition.tools or [] # type: ignore[attr-defined] + print(f"Configured {len(tools)} tool(s):") + for tool in tools: + # `name` isn't declared on every tool kind (e.g. MCP tools have no `name`), + # so fall back to a placeholder for kinds that don't define it. + print(f" - {tool.type}: {getattr(tool, 'name', '(unnamed)')}") + finally: + project_client.agents.delete(agent_name=agent_name) + print(f"Deleted voice agent: {agent_name}") diff --git a/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream.py index b86587c910b7..f4dfa853d921 100644 --- a/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream.py @@ -130,6 +130,7 @@ def _iter_sse_frames(stream, max_log_events: int): agent_name=agent_name, agent_version=created.version, session_id=session.agent_session_id, + stream=True, ) for frame in _iter_sse_frames(raw_stream, max_log_events=30): print(f"SSE event: {frame.get('event')}") diff --git a/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream_async.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream_async.py index 64475d2b3142..97cba73d55b5 100644 --- a/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream_async.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream_async.py @@ -132,6 +132,7 @@ async def main(): agent_name=agent_name, agent_version=created.version, session_id=session.agent_session_id, + stream=True, ) async for frame in _iter_sse_frames_async(raw_stream, max_log_events=30): print(f"SSE event: {frame.get('event')}") diff --git a/sdk/ai/azure-ai-projects/test-resources-post.ps1 b/sdk/ai/azure-ai-projects/test-resources-post.ps1 new file mode 100644 index 000000000000..0e0c82fab3d3 --- /dev/null +++ b/sdk/ai/azure-ai-projects/test-resources-post.ps1 @@ -0,0 +1,184 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# This script deploys the gpt-realtime model to the Foundry account created by +# test-resources.bicep. It is invoked by the New-TestResources.ps1 script after the Bicep +# template finishes deploying. Model deployments are not expressed directly in the Bicep +# template because they can take several minutes and benefit from retry/wait logic that's +# awkward to express declaratively -- this mirrors the approach used by +# sdk/contentunderstanding/test-resources-post.ps1. +# +# SCOPE NOTE: This only deploys the realtime model needed by the voice-agent live tests +# (tests/agents/test_voice_agent_realtime_live*.py, test_voice_agent_conversations*.py). It does +# not provision anything for this package's broader (already-recorded, cassette-based) test +# suite. + +param ( + [hashtable] $DeploymentOutputs, + [string] $ResourceGroupName +) + +$accountName = $DeploymentOutputs['FOUNDRY_VOICE_TEST_ACCOUNT_NAME'] +$resourceGroup = $DeploymentOutputs['FOUNDRY_VOICE_TEST_RESOURCE_GROUP_NAME'] +$deploymentName = $DeploymentOutputs['FOUNDRY_VOICE_MODEL_NAME'] + +if (-not $accountName) { + Write-Error "FOUNDRY_VOICE_TEST_ACCOUNT_NAME (Foundry account name) not found in deployment outputs" + exit 1 +} + +if (-not $deploymentName) { + Write-Error "FOUNDRY_VOICE_MODEL_NAME (model deployment name) not found in deployment outputs" + exit 1 +} + +if (-not $resourceGroup) { + # Fall back to the resource group New-TestResources.ps1 is already operating in. + $resourceGroup = $ResourceGroupName +} + +Write-Host "Deploying model 'gpt-realtime' as deployment '$deploymentName' to account '$accountName' in resource group '$resourceGroup'..." + +# NOTE: the exact model version below is a best-effort default and may need to be updated -- +# gpt-realtime is a preview model with restricted regional/quota availability, and no other +# package in this repo currently automates its deployment (verified: no existing +# test-resources-post.ps1 anywhere deploys "gpt-realtime"). If this fails with a "model not +# found" or capacity error, check current availability with: +# az cognitiveservices account list-models --resource-group --name --output table +# and adjust -ModelVersion/-SkuCapacity/the Bicep template's location parameter accordingly. +$modelVersion = '2025-08-28' +$skuName = 'GlobalStandard' +$skuCapacity = 1 + +function Deploy-Model { + param ( + [string] $ResourceGroupName, + [string] $AccountName, + [string] $DeploymentName, + [string] $ModelName, + [string] $ModelVersion, + [string] $SkuName, + [int] $SkuCapacity + ) + + Write-Host "Checking for an existing deployment named '$DeploymentName'..." + $null = az cognitiveservices account deployment show ` + --resource-group $ResourceGroupName ` + --name $AccountName ` + --deployment-name $DeploymentName ` + 2>&1 + + if ($LASTEXITCODE -eq 0) { + Write-Host "Deployment '$DeploymentName' already exists, skipping creation." + return $true + } + + $azArgs = @( + 'cognitiveservices', 'account', 'deployment', 'create', + '--resource-group', $ResourceGroupName, + '--name', $AccountName, + '--deployment-name', $DeploymentName, + '--model-format', 'OpenAI', + '--model-name', $ModelName, + '--model-version', $ModelVersion, + '--output', 'json' + ) + if ($SkuName) { + $azArgs += '--sku-name', $SkuName + } + if ($SkuCapacity -gt 0) { + $azArgs += '--sku-capacity', $SkuCapacity.ToString() + } + + try { + $deploymentJson = & az $azArgs 2>&1 + if ($LASTEXITCODE -eq 0) { + $deployment = $deploymentJson | ConvertFrom-Json + Write-Host "Successfully created deployment '$DeploymentName' (status: $($deployment.properties.provisioningState))" -ForegroundColor Green + return $true + } + Write-Error "FAILED to deploy '$DeploymentName': $deploymentJson" -ErrorAction Continue + return $false + } + catch { + Write-Error "FAILED to deploy '$DeploymentName': $_" -ErrorAction Continue + return $false + } +} + +function Wait-ForDeployment { + param ( + [string] $ResourceGroupName, + [string] $AccountName, + [string] $DeploymentName, + [int] $MaxWaitMinutes = 15, + [int] $PollIntervalSeconds = 30 + ) + + Write-Host "Waiting for deployment '$DeploymentName' to be ready..." + $startTime = Get-Date + $maxWaitTime = $startTime.AddMinutes($MaxWaitMinutes) + + while ((Get-Date) -lt $maxWaitTime) { + try { + $deploymentJson = az cognitiveservices account deployment show ` + --resource-group $ResourceGroupName ` + --name $AccountName ` + --deployment-name $DeploymentName ` + --output json 2>&1 + + if ($LASTEXITCODE -eq 0) { + $deployment = $deploymentJson | ConvertFrom-Json + $provisioningState = $deployment.properties.provisioningState + + if ($provisioningState -eq 'Succeeded') { + Write-Host "Deployment '$DeploymentName' is ready (status: $provisioningState)" -ForegroundColor Green + return $true + } + if ($provisioningState -eq 'Failed') { + Write-Error "Deployment '$DeploymentName' failed" -ErrorAction Continue + return $false + } + Write-Host "Deployment '$DeploymentName' status: $provisioningState (waiting...)" + } + else { + Write-Host "Could not check deployment status, will retry..." + } + } + catch { + Write-Host "Error checking deployment status: $_, will retry..." + } + + Start-Sleep -Seconds $PollIntervalSeconds + } + + Write-Warning "Timeout waiting for deployment '$DeploymentName' to be ready after $MaxWaitMinutes minutes" + return $false +} + +$deployed = Deploy-Model ` + -ResourceGroupName $resourceGroup ` + -AccountName $accountName ` + -DeploymentName $deploymentName ` + -ModelName 'gpt-realtime' ` + -ModelVersion $modelVersion ` + -SkuName $skuName ` + -SkuCapacity $skuCapacity + +if ($deployed) { + $ready = Wait-ForDeployment ` + -ResourceGroupName $resourceGroup ` + -AccountName $accountName ` + -DeploymentName $deploymentName ` + -MaxWaitMinutes 15 ` + -PollIntervalSeconds 30 + + if (-not $ready) { + Write-Error "The '$deploymentName' deployment did not finish provisioning in time. Live voice-agent tests would fail against a not-ready model." -ErrorAction Continue + exit 1 + } +} +else { + Write-Error "Could not create the '$deploymentName' model deployment. Live voice-agent tests will fail." -ErrorAction Continue + exit 1 +} diff --git a/sdk/ai/azure-ai-projects/test-resources.bicep b/sdk/ai/azure-ai-projects/test-resources.bicep new file mode 100644 index 000000000000..80d890a85b98 --- /dev/null +++ b/sdk/ai/azure-ai-projects/test-resources.bicep @@ -0,0 +1,114 @@ +// ============================================================================ +// Azure AI Projects SDK Test Resources -- Voice Agent Live-Test Support +// ============================================================================ +// This Bicep template provisions the Azure resources needed to run the +// live-only voice-agent realtime tests (tests/agents/test_voice_agent_realtime_live*.py) +// and to record/re-record the voice-agent conversation-read cassette +// (tests/agents/test_voice_agent_conversations*.py) against a real service. +// +// SCOPE NOTE: This intentionally covers only the voice-agent test surface, not +// the package's full recorded-test suite (datasets, evaluations, fine-tuning, +// memory search, etc.), which already runs entirely from committed cassettes +// and does not need a live resource. Provisioning a resource for that broader +// surface (additional model deployments, storage, connections, ...) is a +// separate, larger effort. +// +// Resources created: +// 1. Microsoft Foundry account (Microsoft.CognitiveServices/accounts, kind +// AIServices, SKU S0) with a nested Foundry project. +// 2. Role assignment granting the test application the "Azure AI User" role +// (matches the role this package's own samples/hosted_agents/rbac_util.py +// uses for agent operations) -- authentication is Entra ID via +// DefaultAzureCredential, no API keys. +// 3. A `gpt-realtime` model deployment, created separately by +// test-resources-post.ps1 (deployments can take several minutes and this +// lets the script retry/wait, which is awkward to express in Bicep). +// +// Outputs (become environment variables read by EnvironmentVariableLoader): +// - FOUNDRY_PROJECT_ENDPOINT: the Foundry project endpoint, in the +// `https://.services.ai.azure.com/api/projects/` form +// these tests expect (see .env.template). +// - FOUNDRY_VOICE_MODEL_NAME: the realtime model deployment name +// (`gpt-realtime`), matching what test-resources-post.ps1 deploys. +// ============================================================================ + +@description('The client OID to grant access to test resources.') +param testApplicationOid string + +@minLength(6) +@maxLength(50) +@description('The base resource name.') +param baseName string = resourceGroup().name + +@description('The location of the resource. By default, this is the same as the resource group. gpt-realtime has restricted regional availability -- override this if the default region does not support it.') +param location string = resourceGroup().location + +// Role definition ID for "Azure AI User" -- matches +// sdk/ai/azure-ai-projects/samples/hosted_agents/rbac_util.py's +// AZURE_AI_USER_ROLE_DEFINITION_GUID, the role this package's own samples use +// to grant an identity access to run agent operations against a Foundry +// project. +var azureAiUserRoleId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '53ca6127-db72-4b80-b1b0-d745d6d5456d') + +// Resource names +var foundryAccountName = '${baseName}-voice-foundry' +var foundryProjectName = toLower(foundryAccountName) + +// The Foundry account. `defaultProjectName`/the nested `projects` sub-resource +// below follow the same shape used by sdk/voicelive's test-resources.json. +resource foundryAccount 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = { + name: foundryAccountName + location: location + kind: 'AIServices' + sku: { + name: 'S0' + } + identity: { + type: 'SystemAssigned' + } + properties: { + customSubDomainName: toLower(foundryAccountName) + publicNetworkAccess: 'Enabled' + allowProjectManagement: true + } +} + +resource foundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = { + parent: foundryAccount + name: foundryProjectName + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + displayName: foundryProjectName + description: 'Voice agent live-test project for azure-ai-projects' + } +} + +// Grants the test application access to run agent/voice-agent operations. +// principalType is omitted so Azure can infer it (works for both a user and a +// service principal), matching the pattern used in +// sdk/contentunderstanding/test-resources.bicep. +resource testAppRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryAccount.id, azureAiUserRoleId) + scope: foundryAccount + properties: { + roleDefinitionId: azureAiUserRoleId + principalId: testApplicationOid + } +} + +// The gpt-realtime model deployment is created by test-resources-post.ps1 +// after this template finishes deploying (see that script for why: model +// deployments can take several minutes and need retry/wait logic that's +// awkward to express here, following the same approach as +// sdk/contentunderstanding/test-resources.bicep). + +output FOUNDRY_PROJECT_ENDPOINT string = 'https://${toLower(foundryAccountName)}.services.ai.azure.com/api/projects/${foundryProjectName}' +output FOUNDRY_VOICE_MODEL_NAME string = 'gpt-realtime' + +// Additional outputs consumed by test-resources-post.ps1 to locate the +// account when deploying the model. +output FOUNDRY_VOICE_TEST_ACCOUNT_NAME string = foundryAccountName +output FOUNDRY_VOICE_TEST_RESOURCE_GROUP_NAME string = resourceGroup().name diff --git a/sdk/ai/azure-ai-projects/tests.yml b/sdk/ai/azure-ai-projects/tests.yml new file mode 100644 index 000000000000..ff842e5c9da1 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests.yml @@ -0,0 +1,17 @@ +trigger: none + +extends: + template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml + parameters: + BuildTargetingString: 'azure-ai-projects' + ServiceDirectory: ai + TestResourceDirectories: + - ai/azure-ai-projects + # gpt-realtime (GlobalStandard) is only deployable in a handful of regions (e.g. eastus2, + # centralus, canadacentral); the shared template's default region for this cloud (westus) + # does not support it, which would fail resource provisioning before any test runs. + Location: 'eastus2' + EnvVars: + AZURE_TEST_RUN_LIVE: 'true' + AZURE_TEST_USE_CLI_AUTH: 'true' + TestMarkArgument: 'live_test_only' diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py new file mode 100644 index 000000000000..9d216a9ceed0 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py @@ -0,0 +1,395 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,protected-access +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable +"""Transport-mocked unit tests for the hand-written sync realtime (WebSocket) client. + +Unlike ``test_voice_agent_crud.py``, these tests never make an HTTP/WS call: the underlying +``websockets.sync.client.connect`` is replaced with a fake so URL construction, header/auth +handling, event serialization/deserialization, connection cleanup, and dependency/error paths +can all be verified without a live service or a recorded transport. +""" + +import json +import inspect +from unittest.mock import MagicMock, patch +from urllib.parse import parse_qs, urlparse + +import pytest +from azure.core.credentials import AccessToken +from websockets.typing import Subprotocol + +from azure.ai.projects._realtime import ( + RealtimeConnectionManager, + _assert_trusted_connection_url, + _to_ws_url, + _USER_AGENT, +) +from azure.ai.projects._version import VERSION +from azure.ai.projects.models import ( + RealtimeClientEventResponseCreate, + RealtimeServerEventSessionCreated, +) + +_ENDPOINT = "https://my-account.services.ai.azure.com/api/projects/my-project" + + +class _FakeCredential: + """Sync stub credential that returns a never-expiring token.""" + + def __init__(self, token: str = "fake-token") -> None: + self._token = token + + def get_token(self, *args, **kwargs) -> AccessToken: # pylint: disable=unused-argument + return AccessToken(self._token, 9_999_999_999) + + +def _make_manager(**overrides) -> RealtimeConnectionManager: + kwargs = { + "endpoint": _ENDPOINT, + "credential": _FakeCredential(), + "credential_scopes": ["https://ai.azure.com/.default"], + "api_version": "v1", + "agent_name": "my-agent", + "foundry_features": "VoiceAgents=V1Preview", + } + kwargs.update(overrides) + return RealtimeConnectionManager(**kwargs) + + +class TestToWsUrl: + """Unit tests for the pure ``_to_ws_url`` URL-construction helper.""" + + def test_https_endpoint_becomes_wss(self): + url = _to_ws_url(_ENDPOINT, "my-agent") + assert ( + url + == "wss://my-account.services.ai.azure.com/api/projects/my-project/agents/my-agent/endpoint/protocols/voice" + ) + + def test_non_https_endpoint_scheme_is_left_unchanged(self): + # Regression test: _to_ws_url used to translate "http://" to "ws://", but + # RealtimeConnectionManager.enter() unconditionally rejects any non-"wss://" URL to + # protect the live Authorization token in transit, so that translated "ws://" URL could + # never actually be used to connect. Leaving the scheme untouched here means the + # downstream "wss://" check surfaces a clear error instead of an unreachable "ws://" path. + url = _to_ws_url("http://localhost:8080", "my-agent") + assert url == "http://localhost:8080/agents/my-agent/endpoint/protocols/voice" + + def test_trailing_slash_is_stripped(self): + url = _to_ws_url(_ENDPOINT + "/", "my-agent") + assert ( + url + == "wss://my-account.services.ai.azure.com/api/projects/my-project/agents/my-agent/endpoint/protocols/voice" + ) + + +class TestAssertTrustedConnectionUrl: + """Unit tests for the connection_url host allow-list guard (security fix).""" + + def test_matching_host_does_not_raise(self): + _assert_trusted_connection_url(f"wss://{'my-account.services.ai.azure.com'}/custom/path", _ENDPOINT) + + def test_mismatched_host_raises_value_error(self): + with pytest.raises(ValueError): + _assert_trusted_connection_url("wss://evil.example.com/steal-token", _ENDPOINT) + + def test_empty_host_raises_value_error(self): + with pytest.raises(ValueError): + _assert_trusted_connection_url("not-a-url", _ENDPOINT) + + def test_matching_host_explicit_default_port_does_not_raise(self): + # An explicit ":443" is the wss/https default, so this is the same origin as _ENDPOINT + # (which omits the port) and must be accepted. + _assert_trusted_connection_url("wss://my-account.services.ai.azure.com:443/custom/path", _ENDPOINT) + + def test_mismatched_port_raises_value_error(self): + # Regression test (security fix): comparing hostname alone let an override targeting the + # same host on a different, non-default port (a different origin) slip through and + # receive the live bearer token. + with pytest.raises(ValueError): + _assert_trusted_connection_url("wss://my-account.services.ai.azure.com:8443/steal-token", _ENDPOINT) + + +class TestRealtimeConnectionManagerEnter: + """Unit tests for ``RealtimeConnectionManager.enter()``: URL/header construction and errors.""" + + def test_enter_builds_bearer_auth_and_query(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + conn = manager.enter() + try: + assert conn is not None + finally: + manager.__exit__() + + assert mock_connect.call_count == 1 + _args, kwargs = mock_connect.call_args + called_url = _args[0] + assert called_url.startswith("wss://my-account.services.ai.azure.com") + assert "api-version=v1" in called_url + assert kwargs["additional_headers"]["Authorization"] == "Bearer fake-token" + assert kwargs["additional_headers"]["Foundry-Features"] == "VoiceAgents=V1Preview" + + def test_enter_identifies_sdk_via_user_agent_and_query(self): + # The generated HTTP surface gets SDK identification for free from the core pipeline's + # UserAgentPolicy; this hand-written client builds its own request and must opt in + # explicitly, both as a User-Agent header and (since some proxies/paths don't forward + # WebSocket upgrade headers) as an x-ms-client-sdk query parameter. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["additional_headers"]["User-Agent"] == _USER_AGENT + assert "azsdk-python-ai-projects" in _USER_AGENT + assert VERSION in _USER_AGENT + + query = parse_qs(urlparse(_args[0]).query) + assert query["x-ms-client-sdk"] == [_USER_AGENT] + + def test_enter_caller_user_agent_overrides_default(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_headers={"User-Agent": "custom-user-agent"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["additional_headers"]["User-Agent"] == "custom-user-agent" + + def test_enter_caller_user_agent_overrides_default_case_insensitive(self): + # Regression test: a plain dict merge of extra_headers would leave a differently-cased + # caller override (e.g. "user-agent") as a *separate* key alongside our own "User-Agent" + # default, since Python dict keys are case-sensitive but HTTP header names are not -- + # sending two User-Agent-like headers instead of cleanly honoring the caller's override. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_headers={"user-agent": "custom-user-agent"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + headers = kwargs["additional_headers"] + assert "User-Agent" not in headers + assert headers["user-agent"] == "custom-user-agent" + + def test_enter_source_retains_client_identification_wiring(self): + # Regression guard for the SDK client-identification fix (ported from azure-ai-voicelive + # PR #48848) surviving a future TypeSpec regeneration. `_realtime.py` is a hand-written + # file that is NOT `_patch.py`-named, so it isn't covered by the code generator's own + # "never touch _patch.py" guarantee -- nothing in the TypeSpec emitter is aware this file + # exists. The tests above already fail on a *behavioral* regression (wrong header/query + # value), but they exercise the code through mocks and could, in principle, still pass + # against a rewritten implementation that happens to produce the same observable values by + # a different (less safe) path. This inspects the actual source of `enter()` so a partial + # revert -- one that drops the case-insensitive guard, say, while keeping the header value + # correct for the common case -- is caught directly, independent of the tests above. + source = inspect.getsource(RealtimeConnectionManager.enter) + assert "_USER_AGENT" in source + assert "_has_header_case_insensitive" in source + assert "x-ms-client-sdk" in source + + def test_enter_disables_library_default_user_agent_header(self): + # Regression test: unlike aiohttp (where an explicit "User-Agent" in `headers` already + # takes precedence over its own default), `websockets.sync.client.connect`'s + # `user_agent_header` is a wholly separate mechanism from `additional_headers` -- passing + # our own "User-Agent" there does not suppress it. Without explicitly disabling it, the + # connection would carry two distinct User-Agent-like values. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["user_agent_header"] is None + + def test_enter_overrides_caller_supplied_subprotocols_kwarg(self): + # Regression test: subprotocols=[Subprotocol("realtime")] is passed explicitly to + # _ws_connect, so a caller-supplied subprotocols override forwarded through **kwargs would + # otherwise collide ("got multiple values for keyword argument 'subprotocols'"). The + # service requires the "realtime" subprotocol, so the override is dropped rather than + # honored -- matching the async implementation's handling of its equivalent `protocols` + # kwarg. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(subprotocols=["other"]) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["subprotocols"] == [Subprotocol("realtime")] + + def test_enter_appends_extra_query_and_headers(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_query={"foo": "bar"}, extra_headers={"X-Custom": "1"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert "foo=bar" in _args[0] + assert kwargs["additional_headers"]["X-Custom"] == "1" + + def test_enter_preserves_existing_query_on_connection_url_override(self): + # Regression test: the URL builder used to unconditionally append "?", corrupting an + # override URL that already has a query string (e.g. a SAS-style "?sig=..."). + fake_connection = MagicMock() + override = f"wss://{'my-account.services.ai.azure.com'}/custom?sig=abc" + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(connection_url=override) + manager.enter() + manager.__exit__() + + called_url = mock_connect.call_args[0][0] + assert called_url.count("?") == 1 + assert "sig=abc&api-version=v1" in called_url + + def test_enter_rejects_untrusted_connection_url_host(self): + manager = _make_manager(connection_url="wss://evil.example.com/steal-token") + with pytest.raises(ValueError): + manager.enter() + + def test_enter_rejects_non_wss_url(self): + # A plain http(s) endpoint that somehow produced a non-ws(s) URL should never proceed. + manager = _make_manager(endpoint="ftp://not-http-or-https") + with pytest.raises(ValueError): + manager.enter() + + def test_enter_raises_runtime_error_when_websockets_missing(self): + manager = _make_manager() + with patch.dict("sys.modules", {"websockets.sync.client": None, "websockets.typing": None}): + with pytest.raises(RuntimeError, match="websockets"): + manager.enter() + + def test_context_manager_closes_connection_on_exit(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + with _make_manager() as conn: + pass + fake_connection.close.assert_called_once() + + +class TestRealtimeConnectionRecv: + """Unit tests for ``RealtimeConnection.recv()``: event dispatch and error/timeout handling.""" + + def test_recv_dispatches_known_event_type(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "session.created", "session": {}}) + event = conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + + def test_recv_unknown_event_type_returns_dict(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "some.new.event", "foo": "bar"}) + event = conn.recv() + assert isinstance(event, dict) + assert event["foo"] == "bar" + + def test_recv_forwards_timeout_to_underlying_connection(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "error", "error": {"message": "boom"}}) + conn.recv(timeout=5.0) + fake_connection.recv.assert_called_once_with(timeout=5.0) + + def test_recv_timeout_error_propagates(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = TimeoutError() + with pytest.raises(TimeoutError): + conn.recv(timeout=0.1) + + def test_recv_connection_closed_raises_connection_reset_error(self, request): + from websockets.exceptions import ConnectionClosedOK + + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionClosedOK(None, None) + with pytest.raises(ConnectionResetError): + conn.recv() + + def test_iteration_stops_cleanly_on_connection_reset(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionResetError() + assert list(conn) == [] + + +class TestRealtimeConnectionSend: + """Unit tests for ``RealtimeConnection.send()``: model/str/mapping serialization.""" + + def test_send_serializes_typed_model(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send(RealtimeClientEventResponseCreate()) + sent_raw = fake_connection.send.call_args[0][0] + payload = json.loads(sent_raw) + assert payload["type"] == "response.create" + + def test_send_passes_through_valid_json_string(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send('{"type": "response.create"}') + fake_connection.send.assert_called_once_with('{"type": "response.create"}') + + def test_send_rejects_invalid_json_string(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + with pytest.raises(ValueError): + conn.send("not valid json") + + def test_send_serializes_mapping(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send({"type": "response.cancel"}) + sent_raw = fake_connection.send.call_args[0][0] + assert json.loads(sent_raw) == {"type": "response.cancel"} diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py new file mode 100644 index 000000000000..aa599ba87de8 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py @@ -0,0 +1,349 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,protected-access +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable +"""Transport-mocked unit tests for the hand-written async realtime (WebSocket) client. + +Async counterpart of ``test_realtime_client.py``. The underlying ``aiohttp.ClientSession`` is +replaced with a fake so URL construction, header/auth handling, event serialization/ +deserialization, connection cleanup, and dependency/error paths can all be verified without a +live service or a recorded transport. +""" + +import json +import inspect +from unittest.mock import AsyncMock, MagicMock, patch +from urllib.parse import parse_qs, urlparse + +import pytest +from azure.core.credentials import AccessToken + +from azure.ai.projects.aio._realtime import AsyncRealtimeConnectionManager, _USER_AGENT +from azure.ai.projects._version import VERSION +from azure.ai.projects.models import ( + RealtimeClientEventResponseCreate, + RealtimeServerEventSessionCreated, +) + +_ENDPOINT = "https://my-account.services.ai.azure.com/api/projects/my-project" + +pytestmark = pytest.mark.asyncio + + +class _AsyncFakeCredential: + """Async stub credential that returns a never-expiring token.""" + + def __init__(self, token: str = "fake-token") -> None: + self._token = token + + async def get_token(self, *args, **kwargs) -> AccessToken: # pylint: disable=unused-argument + return AccessToken(self._token, 9_999_999_999) + + +def _make_manager(**overrides) -> AsyncRealtimeConnectionManager: + kwargs = { + "endpoint": _ENDPOINT, + "credential": _AsyncFakeCredential(), + "credential_scopes": ["https://ai.azure.com/.default"], + "api_version": "v1", + "agent_name": "my-agent", + "foundry_features": "VoiceAgents=V1Preview", + } + kwargs.update(overrides) + return AsyncRealtimeConnectionManager(**kwargs) + + +def _make_fake_msg(msg_type, data=None): + msg = MagicMock() + msg.type = msg_type + msg.data = data + return msg + + +def _make_fake_ws(): + """A fake aiohttp ClientWebSocketResponse with async close() (always awaited by __aexit__).""" + fake_ws = MagicMock() + fake_ws.close = AsyncMock() + return fake_ws + + +def _patch_client_session(fake_ws_connection): + """Patch aiohttp.ClientSession() to return a fake session whose ws_connect/close are async.""" + fake_session = MagicMock() + fake_session.ws_connect = AsyncMock(return_value=fake_ws_connection) + fake_session.close = AsyncMock() + return patch("aiohttp.ClientSession", return_value=fake_session), fake_session + + +class TestAsyncRealtimeConnectionManagerEnter: + """Unit tests for ``AsyncRealtimeConnectionManager.enter()``: URL/header construction and errors.""" + + async def test_enter_builds_bearer_auth_and_query(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + await manager.enter() + await manager.__aexit__() + + assert fake_session.ws_connect.call_count == 1 + _args, kwargs = fake_session.ws_connect.call_args + assert _args[0].startswith("wss://my-account.services.ai.azure.com") + assert kwargs["params"]["api-version"] == "v1" + assert kwargs["headers"]["Authorization"] == "Bearer fake-token" + assert kwargs["headers"]["Foundry-Features"] == "VoiceAgents=V1Preview" + assert "Sec-WebSocket-Protocol" not in kwargs["headers"] + assert kwargs["protocols"] == ("realtime",) + + async def test_enter_identifies_sdk_via_user_agent_and_query(self): + # The generated HTTP surface gets SDK identification for free from the core pipeline's + # UserAgentPolicy; this hand-written client builds its own request and must opt in + # explicitly, both as a User-Agent header and (since some proxies/paths don't forward + # WebSocket upgrade headers) as an x-ms-client-sdk query parameter. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["headers"]["User-Agent"] == _USER_AGENT + assert "azsdk-python-ai-projects" in _USER_AGENT + assert VERSION in _USER_AGENT + assert kwargs["params"]["x-ms-client-sdk"] == _USER_AGENT + + async def test_enter_caller_user_agent_overrides_default(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(extra_headers={"User-Agent": "custom-user-agent"}) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["headers"]["User-Agent"] == "custom-user-agent" + + async def test_enter_caller_user_agent_overrides_default_case_insensitive(self): + # Regression test: a plain dict merge of extra_headers would leave a differently-cased + # caller override (e.g. "user-agent") as a *separate* key alongside our own "User-Agent" + # default, since Python dict keys are case-sensitive but HTTP header names are not -- + # sending two User-Agent-like headers instead of cleanly honoring the caller's override. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(extra_headers={"user-agent": "custom-user-agent"}) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + headers = kwargs["headers"] + assert "User-Agent" not in headers + assert headers["user-agent"] == "custom-user-agent" + + async def test_enter_source_retains_client_identification_wiring(self): + # Regression guard for the SDK client-identification fix (ported from azure-ai-voicelive + # PR #48848) surviving a future TypeSpec regeneration. `aio/_realtime.py` is a hand-written + # file that is NOT `_patch.py`-named, so it isn't covered by the code generator's own + # "never touch _patch.py" guarantee -- nothing in the TypeSpec emitter is aware this file + # exists. The tests above already fail on a *behavioral* regression (wrong header/query + # value), but they exercise the code through mocks and could, in principle, still pass + # against a rewritten implementation that happens to produce the same observable values by + # a different (less safe) path. This inspects the actual source of `enter()` so a partial + # revert -- one that drops the case-insensitive guard, say, while keeping the header value + # correct for the common case -- is caught directly, independent of the tests above. + source = inspect.getsource(AsyncRealtimeConnectionManager.enter) + assert "_USER_AGENT" in source + assert "_has_header_case_insensitive" in source + assert "x-ms-client-sdk" in source + + async def test_enter_rejects_untrusted_connection_url_host(self): + manager = _make_manager(connection_url="wss://evil.example.com/steal-token") + with pytest.raises(ValueError): + await manager.enter() + + async def test_enter_overrides_caller_supplied_protocols_kwarg(self): + # Regression test: protocols=("realtime",) is now passed explicitly to ws_connect, so a + # caller-supplied protocols override forwarded through **kwargs would otherwise collide + # ("got multiple values for keyword argument 'protocols'"). The service requires the + # "realtime" subprotocol, so the override is dropped rather than honored. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(protocols=("other",)) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["protocols"] == ("realtime",) + + async def test_enter_rejects_non_wss_url(self): + manager = _make_manager(endpoint="ftp://not-http-or-https") + with pytest.raises(ValueError): + await manager.enter() + + async def test_enter_raises_runtime_error_when_aiohttp_missing(self): + manager = _make_manager() + with patch.dict("sys.modules", {"aiohttp": None}): + with pytest.raises(RuntimeError, match="aiohttp"): + await manager.enter() + + async def test_enter_closes_session_on_connect_failure(self): + fake_session = MagicMock() + fake_session.ws_connect = AsyncMock(side_effect=OSError("connection refused")) + fake_session.close = AsyncMock() + with patch("aiohttp.ClientSession", return_value=fake_session): + manager = _make_manager() + with pytest.raises(ConnectionError): + await manager.enter() + fake_session.close.assert_awaited_once() + + async def test_context_manager_closes_connection_on_exit(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + async with _make_manager(): + pass + fake_ws.close.assert_awaited_once() + fake_session.close.assert_awaited_once() + + +class TestAsyncRealtimeConnectionRecv: + """Unit tests for ``AsyncRealtimeConnection.recv()``: event dispatch and non-text frames.""" + + async def test_recv_dispatches_known_event_type(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + return_value=_make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "session.created", "session": {}})) + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + finally: + await manager.__aexit__() + + async def test_recv_skips_ping_pong_frames(self): + # Regression test locking in the existing PING/PONG handling. + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + side_effect=[ + _make_fake_msg(aiohttp.WSMsgType.PING, b""), + _make_fake_msg(aiohttp.WSMsgType.PONG, b""), + _make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "session.created", "session": {}})), + ] + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + assert fake_ws.receive.await_count == 3 + finally: + await manager.__aexit__() + + async def test_recv_unknown_event_type_returns_dict(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + return_value=_make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "some.new.event", "foo": "bar"})) + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, dict) + assert event["foo"] == "bar" + finally: + await manager.__aexit__() + + async def test_recv_close_frame_raises_connection_reset_error(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.CLOSE)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + await conn.recv() + finally: + await manager.__aexit__() + + async def test_recv_error_frame_raises_connection_reset_error(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.exception = MagicMock(return_value=RuntimeError("boom")) + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.ERROR)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + await conn.recv() + finally: + await manager.__aexit__() + + +class TestAsyncRealtimeConnectionSend: + """Unit tests for ``AsyncRealtimeConnection.send()``: model/str/mapping serialization.""" + + async def test_send_serializes_typed_model(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + await conn.send(RealtimeClientEventResponseCreate()) + sent_raw = fake_ws.send_str.call_args[0][0] + payload = json.loads(sent_raw) + assert payload["type"] == "response.create" + finally: + await manager.__aexit__() + + async def test_send_rejects_invalid_json_string(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ValueError): + await conn.send("not valid json") + finally: + await manager.__aexit__() + + async def test_send_serializes_mapping(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + await conn.send({"type": "response.cancel"}) + sent_raw = fake_ws.send_str.call_args[0][0] + assert json.loads(sent_raw) == {"type": "response.cancel"} + finally: + await manager.__aexit__() diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py new file mode 100644 index 000000000000..b45243faa549 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py @@ -0,0 +1,241 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,too-many-statements,broad-exception-caught +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Recorded tests covering the read-only voice-agent conversation REST API surface exposed through +``project_client.agent_endpoint_conversations``. + +Conversations, their responses/items, and audio are written by the realtime WebSocket subsystem +during a live session (see ``test_voice_agent_realtime_live.py``) and can only be *read* here -- +there is no REST way to create one. A real ``conversation_id`` can therefore only be obtained by +actually running a live session, which is not itself something the test proxy can capture or +replay (it is a raw WebSocket connection, not an HTTP call through the SDK pipeline). + +To get real recorded/replayable coverage of the REST read-back surface anyway, this test: + * When run live (``AZURE_TEST_RUN_LIVE=true``): creates a `store=True` voice agent, opens a + short-lived realtime session directly (bypassing the recorded pipeline, same as any other + live network call), sends one turn, and waits for the resulting conversation to finalize. + The dynamic conversation id is then sanitized to a fixed placeholder before any of the + REST calls below are made, so what gets written to the recording cassette is stable. + * When replayed from the recording (the normal case in CI): skips the live session entirely + and uses the same fixed placeholder conversation id the cassette already expects. +Either way, the REST calls themselves (list/get conversation, responses, items, audio) go +through ``recorded_by_proxy`` exactly like any other recorded test in this package. +""" + +import re +import time +from typing import Final, Optional + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy, is_live, add_general_regex_sanitizer +from azure.core.exceptions import HttpResponseError +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, +) + +# Fixed test-owned agent name: unlike conversation_id (server-generated, truly dynamic), this is +# our own choice and does not need is_live()/sanitizer handling -- it is identical in both modes. +_AGENT_NAME: Final = "test-conversations-read-agent" + +# Best-effort fixed wait (live only, seconds) after the realtime session ends, before reading the +# conversation back, so persistence finalization (items/audio) is more likely to have completed. +# This must be a single, fixed wait rather than a poll loop through the recorded client: repeated +# polling would record multiple cassette entries for the same "get conversation" request, but +# playback only ever issues that request once (polling itself is live-only), so a replay would +# incorrectly consume the *first* (possibly still "in_progress") recorded entry instead of the +# settled one. A single wait keeps exactly one logical call -- and therefore one cassette entry +# -- for both the live recording and the replay to agree on. +_FINALIZATION_WAIT_SECONDS: Final = 30 + + +def _create_live_conversation(project_client, model: str) -> str: + """Create a `store=True` voice agent, hold one turn over a live realtime session, and + return the resulting conversation id. Only ever called when ``is_live()``. + + :param project_client: The Foundry project client. + :param model: The realtime model deployment name. + :type project_client: ~azure.ai.projects.AIProjectClient + :type model: str + :return: The persisted conversation id. + :rtype: str + """ + try: + project_client.agents.delete(agent_name=_AGENT_NAME) + except Exception: # pylint: disable=broad-except + pass + + project_client.agents.create_version( + agent_name=_AGENT_NAME, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + + conversation_id: Optional[str] = None + with project_client.realtime.connect(agent_name=_AGENT_NAME) as conn: + session_created = conn.recv(timeout=30) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + conversation_id = session_created.conversation_id + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text="Say hello.")], + ) + ) + conn.response.create() + + deadline = time.monotonic() + 45 + while time.monotonic() < deadline: + event = conn.recv(timeout=30) + if isinstance(event, RealtimeServerEventResponseDone): + break + + assert conversation_id is not None, "Expected session.created to carry a conversation_id (store=True)" + time.sleep(_FINALIZATION_WAIT_SECONDS) + return conversation_id + + +class TestVoiceAgentConversations(TestBase): + """ + Recorded tests covering the read-only voice-agent conversation REST API surface exposed + through ``project_client.agent_endpoint_conversations`` (conversation envelope, + responses, items, and audio). + + NOTE: The ``agent_endpoint_conversations.get_agent_conversation_item_generated_audio*`` + methods are intentionally NOT covered here: they return the played-back-interrupted + subordinate "generated" audio, which requires deliberately barging in mid-reply during a + live session to produce -- not exercised by the simple single-turn conversation created + here. See this package's engineering notes. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_conversations.py::TestVoiceAgentConversations::test_read_conversation -s + @servicePreparer() + @recorded_by_proxy() + def test_read_conversation(self, **kwargs): # pylint: disable=too-many-locals + """ + Test reading back a persisted voice-agent conversation: the envelope, its responses + (with per-response output items), its ordered items (the transcript), the merged + whole-call audio recording, a single item's audio, and finally deleting the conversation. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------------------------+----------------------------------------------------------- + GET /agents/{agent_name}/endpoint/protocols/voice/conversations agent_endpoint_conversations.list_agent_conversations() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{id} agent_endpoint_conversations.get_agent_conversation() + GET .../conversations/{id}/responses agent_endpoint_conversations.list_agent_conversation_responses() + GET .../conversations/{id}/responses/{response_id} agent_endpoint_conversations.get_agent_conversation_response() + GET .../conversations/{id}/responses/{response_id}/items agent_endpoint_conversations.list_agent_conversation_response_items() + GET .../conversations/{id}/items agent_endpoint_conversations.list_agent_conversation_items() + GET .../conversations/{id}/items/{item_id} agent_endpoint_conversations.get_agent_conversation_item() + GET .../conversations/{id}/audio agent_endpoint_conversations.get_agent_conversation_audio() + GET .../conversations/{id}/audio/content agent_endpoint_conversations.get_agent_conversation_audio_content() + GET .../conversations/{id}/items/{item_id}/audio agent_endpoint_conversations.get_agent_conversation_item_audio() + GET .../conversations/{id}/items/{item_id}/audio/content agent_endpoint_conversations.get_agent_conversation_item_audio_content() + DELETE .../conversations/{id} agent_endpoint_conversations.delete_agent_conversation() + """ + print("\n") + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + conversations = project_client.agent_endpoint_conversations + + if is_live(): + model = kwargs.get("foundry_voice_model_name") + assert model is not None + conversation_id = _create_live_conversation(project_client, model) + add_general_regex_sanitizer( + regex=re.escape(conversation_id), value="sanitized-conversation-id", function_scoped=True + ) + else: + conversation_id = "sanitized-conversation-id" + + try: + # The conversation should appear in the agent's conversation list. + found = any(c.id == conversation_id for c in conversations.list_agent_conversations(_AGENT_NAME)) + assert found, "Expected the new conversation to appear in list_agent_conversations" + + # The conversation envelope. + conversation = conversations.get_agent_conversation(_AGENT_NAME, conversation_id) + assert conversation.id == conversation_id + assert conversation.status in ("in_progress", "completed", "failed") + assert conversation.created_at is not None + + # The responses (model inference turns) in the conversation. + responses = list(conversations.list_agent_conversation_responses(_AGENT_NAME, conversation_id)) + assert len(responses) >= 1 + first_response = responses[0] + response_detail = conversations.get_agent_conversation_response( + _AGENT_NAME, conversation_id, first_response.id + ) + assert response_detail.id == first_response.id + + # The items produced by that response (does not raise; count may be 0 or more). + list(conversations.list_agent_conversation_response_items(_AGENT_NAME, conversation_id, first_response.id)) + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + items = list(conversations.list_agent_conversation_items(_AGENT_NAME, conversation_id)) + assert len(items) >= 1 + first_item_id = items[0].get("id") + assert first_item_id + fetched_item = conversations.get_agent_conversation_item(_AGENT_NAME, conversation_id, first_item_id) + assert fetched_item.get("id") == first_item_id + + # The merged whole-call recording and per-item audio. Completion is a hard requirement + # here (not a soft skip): a cassette recorded before the conversation finalized would + # otherwise let this test pass while silently never exercising any of the four audio + # methods below, hiding a regression in all of them (including permanently, if such a + # response were ever re-recorded). + assert ( + conversation.status == "completed" + ), f"Expected a completed conversation to exercise audio assertions, got {conversation.status!r}" + recording = conversations.get_agent_conversation_audio(_AGENT_NAME, conversation_id) + assert recording.format is not None + if not recording.blob_uri: + audio_bytes = b"".join(conversations.get_agent_conversation_audio_content(_AGENT_NAME, conversation_id)) + assert len(audio_bytes) > 0 + + # A single item's audio, if any item has one. + for item in items: + item_id = item.get("id") + if not item_id: + continue + try: + item_audio = conversations.get_agent_conversation_item_audio(_AGENT_NAME, conversation_id, item_id) + except HttpResponseError as e: + if e.status_code == 404: + continue + raise + assert item_audio.role is not None + if not item_audio.blob_uri: + item_audio_bytes = b"".join( + conversations.get_agent_conversation_item_audio_content(_AGENT_NAME, conversation_id, item_id) + ) + assert len(item_audio_bytes) > 0 + break + finally: + # Deleting a conversation removes it and all of its responses, items, and audio. + conversations.delete_agent_conversation(_AGENT_NAME, conversation_id) + if is_live(): + project_client.agents.delete(agent_name=_AGENT_NAME) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py new file mode 100644 index 000000000000..d3a59fad6067 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py @@ -0,0 +1,244 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,too-many-statements,broad-exception-caught +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Recorded tests covering the read-only voice-agent conversation REST API surface exposed through +``project_client.agent_endpoint_conversations`` (async client). + +Async counterpart of ``test_voice_agent_conversations.py``. See that module's docstring for the +overall rationale (live-only setup to obtain a real conversation id, sanitized to a fixed +placeholder so the recorded REST calls that follow can be replayed). +""" + +import re +import asyncio +import time +from typing import Final, Optional + +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live, add_general_regex_sanitizer +from devtools_testutils.aio import recorded_by_proxy_async +from azure.core.exceptions import HttpResponseError +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, +) + +# Fixed test-owned agent name: unlike conversation_id (server-generated, truly dynamic), this is +# our own choice and does not need is_live()/sanitizer handling -- it is identical in both modes. +_AGENT_NAME: Final = "test-conversations-read-agent-async" + +# Best-effort fixed wait (live only, seconds) after the realtime session ends, before reading the +# conversation back, so persistence finalization (items/audio) is more likely to have completed. +# This must be a single, fixed wait rather than a poll loop through the recorded client: repeated +# polling would record multiple cassette entries for the same "get conversation" request, but +# playback only ever issues that request once (polling itself is live-only), so a replay would +# incorrectly consume the *first* (possibly still "in_progress") recorded entry instead of the +# settled one. A single wait keeps exactly one logical call -- and therefore one cassette entry +# -- for both the live recording and the replay to agree on. +_FINALIZATION_WAIT_SECONDS: Final = 30 + + +async def _create_live_conversation(project_client, model: str) -> str: + """Create a `store=True` voice agent, hold one turn over a live realtime session, and + return the resulting conversation id. Only ever called when ``is_live()``. + + :param project_client: The Foundry project client. + :param model: The realtime model deployment name. + :type project_client: ~azure.ai.projects.aio.AIProjectClient + :type model: str + :return: The persisted conversation id. + :rtype: str + """ + try: + await project_client.agents.delete(agent_name=_AGENT_NAME) + except Exception: # pylint: disable=broad-except + pass + + await project_client.agents.create_version( + agent_name=_AGENT_NAME, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + + conversation_id: Optional[str] = None + async with project_client.realtime.connect(agent_name=_AGENT_NAME) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=30) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + conversation_id = session_created.conversation_id + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text="Say hello.")], + ) + ) + await conn.response.create() + + got_response_done = False + deadline = time.monotonic() + 45 + while time.monotonic() < deadline and not got_response_done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(30, remaining)) + if isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + + assert conversation_id is not None, "Expected session.created to carry a conversation_id (store=True)" + await asyncio.sleep(_FINALIZATION_WAIT_SECONDS) + return conversation_id + + +class TestVoiceAgentConversationsAsync(TestBase): + """ + Recorded tests covering the read-only voice-agent conversation REST API surface exposed + through ``project_client.agent_endpoint_conversations`` (conversation envelope, + responses, items, and audio), using the async client. + + NOTE: The ``agent_endpoint_conversations.get_agent_conversation_item_generated_audio*`` + methods are intentionally NOT covered here: they return the played-back-interrupted + subordinate "generated" audio, which requires deliberately barging in mid-reply during a + live session to produce -- not exercised by the simple single-turn conversation created + here. See this package's engineering notes. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_conversations_async.py::TestVoiceAgentConversationsAsync::test_read_conversation_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_read_conversation_async(self, **kwargs): # pylint: disable=too-many-locals + """ + Test reading back a persisted voice-agent conversation: the envelope, its responses + (with per-response output items), its ordered items (the transcript), the merged + whole-call audio recording, a single item's audio, and finally deleting the conversation. + + Routes used in this test: see the sync counterpart's docstring in + ``test_voice_agent_conversations.py`` for the full route table (identical here). + """ + print("\n") + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + conversations = project_client.agent_endpoint_conversations + + async with project_client: + if is_live(): + model = kwargs.get("foundry_voice_model_name") + assert model is not None + conversation_id = await _create_live_conversation(project_client, model) + add_general_regex_sanitizer( + regex=re.escape(conversation_id), value="sanitized-conversation-id", function_scoped=True + ) + else: + conversation_id = "sanitized-conversation-id" + + try: + # The conversation should appear in the agent's conversation list. + found = False + async for c in conversations.list_agent_conversations(_AGENT_NAME): + if c.id == conversation_id: + found = True + break + assert found, "Expected the new conversation to appear in list_agent_conversations" + + # The conversation envelope. + conversation = await conversations.get_agent_conversation(_AGENT_NAME, conversation_id) + assert conversation.id == conversation_id + assert conversation.status in ("in_progress", "completed", "failed") + assert conversation.created_at is not None + + # The responses (model inference turns) in the conversation. + responses = [ + r async for r in conversations.list_agent_conversation_responses(_AGENT_NAME, conversation_id) + ] + assert len(responses) >= 1 + first_response = responses[0] + response_detail = await conversations.get_agent_conversation_response( + _AGENT_NAME, conversation_id, first_response.id + ) + assert response_detail.id == first_response.id + + # The items produced by that response (does not raise; count may be 0 or more). + _ = [ + item + async for item in conversations.list_agent_conversation_response_items( + _AGENT_NAME, conversation_id, first_response.id + ) + ] + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + items = [ + item async for item in conversations.list_agent_conversation_items(_AGENT_NAME, conversation_id) + ] + assert len(items) >= 1 + first_item_id = items[0].get("id") + assert first_item_id + fetched_item = await conversations.get_agent_conversation_item( + _AGENT_NAME, conversation_id, first_item_id + ) + assert fetched_item.get("id") == first_item_id + + # The merged whole-call recording and per-item audio. Completion is a hard + # requirement here (not a soft skip): a cassette recorded before the conversation + # finalized would otherwise let this test pass while silently never exercising any + # of the four audio methods below, hiding a regression in all of them (including + # permanently, if such a response were ever re-recorded). + assert ( + conversation.status == "completed" + ), f"Expected a completed conversation to exercise audio assertions, got {conversation.status!r}" + recording = await conversations.get_agent_conversation_audio(_AGENT_NAME, conversation_id) + assert recording.format is not None + if not recording.blob_uri: + audio_chunks = [ + chunk + async for chunk in await conversations.get_agent_conversation_audio_content( + _AGENT_NAME, conversation_id + ) + ] + assert len(b"".join(audio_chunks)) > 0 + + # A single item's audio, if any item has one. + for item in items: + item_id = item.get("id") + if not item_id: + continue + try: + item_audio = await conversations.get_agent_conversation_item_audio( + _AGENT_NAME, conversation_id, item_id + ) + except HttpResponseError as e: + if e.status_code == 404: + continue + raise + assert item_audio.role is not None + if not item_audio.blob_uri: + item_audio_chunks = [ + chunk + async for chunk in await conversations.get_agent_conversation_item_audio_content( + _AGENT_NAME, conversation_id, item_id + ) + ] + assert len(b"".join(item_audio_chunks)) > 0 + break + finally: + # Deleting a conversation removes it and all of its responses, items, and audio. + await conversations.delete_agent_conversation(_AGENT_NAME, conversation_id) + if is_live(): + await project_client.agents.delete(agent_name=_AGENT_NAME) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py new file mode 100644 index 000000000000..d0a96e148356 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py @@ -0,0 +1,199 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy, RecordedTransport +from azure.ai.projects.models import ( + AgentDetails, + AgentKind, + AgentVersionDetails, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceOutputModality, +) + + +class TestVoiceAgentCrud(TestBase): + """ + Recorded tests covering the voice-agent (`kind="voice"`) REST API surface exposed through + `project_client.agents.*`. + + NOTE: Some voice-agent REST APIs are intentionally NOT covered here because they are + currently blocked by known service-side bugs (see this package's engineering notes): + - Reading back a conversation (`project_client.agent_endpoint_conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed service-side, tests can be added for them. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_voice_agent_crud -s + @servicePreparer() + @recorded_by_proxy() + def test_voice_agent_crud(self, **kwargs): + """ + Test CRUD operations for voice Agents (`kind="voice"`). + + This test creates a voice agent, creates a new version of it, gets it, gets a specific + version, lists its versions, and deletes it. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name} project_client.agents.get() + GET /agents/{agent_name}/versions/{agent_version} project_client.agents.get_version() + GET /agents/{agent_name}/versions project_client.agents.list_versions() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "MyVoiceAgentCrudTest" + + def make_definition(instructions: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions=instructions, + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # Create the initial voice agent (version 1). + agent_version1: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + self._validate_agent_version(agent_version1, expected_name=agent_name) + assert agent_version1.definition.kind == "voice" # type: ignore[attr-defined] + + # Create a new version with updated instructions. + agent_version2: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + ) + self._validate_agent_version(agent_version2, expected_name=agent_name) + + # Get the voice agent. + retrieved_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + self._validate_agent(retrieved_agent, expected_name=agent_name, expected_latest_version=agent_version2.version) + + # Retrieve a specific version. + retrieved_agent_version: AgentVersionDetails = project_client.agents.get_version( + agent_name=agent_name, agent_version=agent_version1.version + ) + self._validate_agent_version( + retrieved_agent_version, expected_name=agent_name, expected_version=agent_version1.version + ) + + # List all versions. + item_count = 0 + for listed_agent_version in project_client.agents.list_versions(agent_name=agent_name): + item_count += 1 + self._validate_agent_version(listed_agent_version, expected_name=agent_name) + assert item_count >= 2 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_voice_agent_disable_enable -s + @servicePreparer() + @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + def test_voice_agent_disable_enable(self, **kwargs): + """ + Test disable and enable operations for a voice Agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + POST /agents/{agent_name}:disable project_client.agents.disable() + POST /agents/{agent_name}:enable project_client.agents.enable() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentDisableEnableTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # Disable the agent. + project_client.agents.disable(agent_name=agent_name) + disabled_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + assert str(disabled_agent.state) == "AgentState.DISABLED" or disabled_agent.state == "disabled" + + # Enable the agent. + project_client.agents.enable(agent_name=agent_name) + enabled_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + assert str(enabled_agent.state) == "AgentState.ENABLED" or enabled_agent.state == "enabled" + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_generate_agent -s + @servicePreparer() + @recorded_by_proxy() + def test_generate_agent(self, **kwargs): + """ + Test guided authoring for a voice Agent via `agents.generate_agent()`. + + Routes used in this test: + + Action REST API Route Client Method + ------+----------------------------+----------------------------------- + POST /agents:generate project_client.agents.generate_agent() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentGenerateTest" + + agent: AgentDetails = project_client.agents.generate_agent( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + self._validate_agent(agent, expected_name=agent_name) + assert agent.versions.latest.definition.kind == "voice" # type: ignore[attr-defined] + assert agent.versions.latest.definition.instructions # type: ignore[attr-defined] + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py new file mode 100644 index 000000000000..b5ef9547b3b9 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py @@ -0,0 +1,205 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils.aio import recorded_by_proxy_async +from devtools_testutils import RecordedTransport +from azure.ai.projects.models import ( + AgentDetails, + AgentKind, + AgentVersionDetails, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceOutputModality, +) + + +class TestVoiceAgentCrudAsync(TestBase): + """ + Recorded tests covering the voice-agent (`kind="voice"`) REST API surface exposed through + `project_client.agents.*`. + + NOTE: Some voice-agent REST APIs are intentionally NOT covered here because they are + currently blocked by known service-side bugs (see this package's engineering notes): + - Reading back a conversation (`project_client.agent_endpoint_conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed service-side, tests can be added for them. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_voice_agent_crud_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_voice_agent_crud_async(self, **kwargs): + """ + Test CRUD operations for voice Agents (`kind="voice"`). + + This test creates a voice agent, creates a new version of it, gets it, gets a specific + version, lists its versions, and deletes it. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name} project_client.agents.get() + GET /agents/{agent_name}/versions/{agent_version} project_client.agents.get_version() + GET /agents/{agent_name}/versions project_client.agents.list_versions() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "MyVoiceAgentCrudTestAsync" + + def make_definition(instructions: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions=instructions, + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + async with project_client: + # Create the initial voice agent (version 1). + agent_version1: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + self._validate_agent_version(agent_version1, expected_name=agent_name) + assert agent_version1.definition.kind == "voice" # type: ignore[attr-defined] + + # Create a new version with updated instructions. + agent_version2: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + ) + self._validate_agent_version(agent_version2, expected_name=agent_name) + + # Get the voice agent. + retrieved_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + self._validate_agent( + retrieved_agent, expected_name=agent_name, expected_latest_version=agent_version2.version + ) + + # Retrieve a specific version. + retrieved_agent_version: AgentVersionDetails = await project_client.agents.get_version( + agent_name=agent_name, agent_version=agent_version1.version + ) + self._validate_agent_version( + retrieved_agent_version, expected_name=agent_name, expected_version=agent_version1.version + ) + + # List all versions. + item_count = 0 + async for listed_agent_version in project_client.agents.list_versions(agent_name=agent_name): + item_count += 1 + self._validate_agent_version(listed_agent_version, expected_name=agent_name) + assert item_count >= 2 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_voice_agent_disable_enable_async -s + @servicePreparer() + @recorded_by_proxy_async(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + async def test_voice_agent_disable_enable_async(self, **kwargs): + """ + Test disable and enable operations for a voice Agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + POST /agents/{agent_name}:disable project_client.agents.disable() + POST /agents/{agent_name}:enable project_client.agents.enable() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentDisableEnableTestAsync" + + async with project_client: + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # Disable the agent. + await project_client.agents.disable(agent_name=agent_name) + disabled_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + assert str(disabled_agent.state) == "AgentState.DISABLED" or disabled_agent.state == "disabled" + + # Enable the agent. + await project_client.agents.enable(agent_name=agent_name) + enabled_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + assert str(enabled_agent.state) == "AgentState.ENABLED" or enabled_agent.state == "enabled" + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_generate_agent_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_generate_agent_async(self, **kwargs): + """ + Test guided authoring for a voice Agent via `agents.generate_agent()`. + + Routes used in this test: + + Action REST API Route Client Method + ------+----------------------------+----------------------------------- + POST /agents:generate project_client.agents.generate_agent() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentGenerateTestAsync" + + async with project_client: + agent: AgentDetails = await project_client.agents.generate_agent( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + self._validate_agent(agent, expected_name=agent_name) + assert agent.versions.latest.definition.kind == "voice" # type: ignore[attr-defined] + assert agent.versions.latest.definition.instructions # type: ignore[attr-defined] + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py new file mode 100644 index 000000000000..f5b4d498b1e5 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py @@ -0,0 +1,288 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Live-only tests for the hand-written sync ``client.realtime`` WebSocket streaming client. + +Unlike ``tests/agents/test_realtime_client.py`` (which mocks the transport to unit-test URL +construction, auth, and error paths without a live service), these tests open a REAL WebSocket +connection to a live voice agent and assert on the actual streamed server events. They are +modeled on the live realtime test pattern used by the ``azure-ai-voicelive`` package +(``sdk/voicelive/azure-ai-voicelive/tests/live/``): skip entirely unless running live, use +generous per-event timeouts, and assert on event *types* and content presence/length rather than +exact audio bytes (the model's actual audio/text output is not deterministic). + +These tests do not use ``store=True`` / read back a persisted conversation -- that surface +(``project_client.agent_endpoint_conversations.*``) is covered by the separate recorded +tests in ``test_voice_agent_conversations.py``, which need a real conversation id but replay +against a recorded cassette rather than opening a live WebSocket connection on every run. +""" + +import json +import time +from typing import Any, cast, Final + +import pytest +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceModelType, + VoiceOutputModality, +) + +# Seconds to wait for a single server event (session handshake, an audio delta, ...). +_EVENT_TIMEOUT: Final = 30 +# Seconds to wait for a full response turn to finish (may include a tool round-trip). +_RESPONSE_TIMEOUT: Final = 45 + + +def _get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +@pytest.mark.live_test_only +@pytest.mark.skipif( + not is_live(), + reason="Live-only: opens a real WebSocket connection to the realtime service, which cannot " + "be captured/replayed by the test proxy.", +) +class TestVoiceAgentRealtimeLive(TestBase): + """ + Live tests covering ``client.realtime.connect()`` (the hand-written sync WebSocket streaming + client) against a real voice agent and a real service connection. + """ + + def _make_agent_name(self, suffix: str) -> str: + return f"test-realtime-live-{suffix}" + + def _create_basic_agent(self, project_client, agent_name: str, model: str) -> None: + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_session_lifecycle -s + @servicePreparer() + def test_realtime_session_lifecycle(self, **kwargs): + """ + Test opening and cleanly closing a realtime WebSocket session, and receiving the initial + ``session.created`` handshake event. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("lifecycle") + + try: + self._create_basic_agent(project_client, agent_name, model) + + with project_client.realtime.connect(agent_name=agent_name) as conn: + event = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(event, RealtimeServerEventSessionCreated) + assert event.type == "session.created" + # The `with` block above closes the connection; a second `recv()` after close + # would raise, so we don't attempt one -- clean exit from the block is the assertion. + finally: + project_client.agents.delete(agent_name=agent_name) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_text_turn_produces_audio_and_transcript -s + @servicePreparer() + def test_realtime_text_turn_produces_audio_and_transcript(self, **kwargs): + """ + Test sending one typed user turn and receiving a streamed audio + transcript reply. + + Sends a ``RealtimeConversationItemMessageUser`` text turn and asserts that the service + streams back at least one non-empty audio delta, a transcript-done event with non-empty + text, and a final ``response.done``. Content is not asserted verbatim (the model's actual + wording is not deterministic); only event types, ordering-independent presence, and basic + size/non-emptiness are checked, matching the ``azure-ai-voicelive`` live test convention. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("text-turn") + + try: + self._create_basic_agent(project_client, agent_name, model) + + with project_client.realtime.connect(agent_name=agent_name) as conn: + session_created = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="Say the word 'hello' and nothing else." + ) + ], + ) + ) + conn.response.create() + + audio_delta_count = 0 + audio_bytes = 0 + transcript_done_count = 0 + got_response_done = False + deadline = time.monotonic() + _RESPONSE_TIMEOUT + + while time.monotonic() < deadline and not got_response_done: + event = conn.recv(timeout=_EVENT_TIMEOUT) + if isinstance(event, RealtimeServerEventResponseAudioDelta): + audio_delta_count += 1 + audio_bytes += len(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + transcript_done_count += 1 + assert event.transcript is not None and len(event.transcript.strip()) > 0 + elif isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert got_response_done, "Did not receive response.done within the timeout" + assert audio_delta_count > 0, "Expected at least one response.audio.delta event" + assert audio_bytes > 0, "Expected non-empty streamed audio" + assert transcript_done_count == 1, "Expected exactly one audio-transcript-done event" + finally: + project_client.agents.delete(agent_name=agent_name) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_function_tool_call -s + @servicePreparer() + def test_realtime_function_tool_call(self, **kwargs): + """ + Test a client-executed function-tool round trip during a live realtime session. + + Configures the agent with a ``get_weather`` function tool, sends a prompt that should + trigger it, executes the tool call locally when the service asks for it, and sends the + result back so the agent can finish its reply -- mirroring + ``samples/agents/voice/sample_voice_agent_live_function_tool.py``, which this test + adapts into an automated assertion-based form. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("tool-call") + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + try: + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + + with project_client.realtime.connect(agent_name=agent_name) as conn: + session_created = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="What's the weather like in Seattle right now?" + ) + ], + ) + ) + conn.response.create() + + tool_call_count = 0 + final_text = "" + deadline = time.monotonic() + _RESPONSE_TIMEOUT + done = False + + while time.monotonic() < deadline and not done: + event = conn.recv(timeout=_EVENT_TIMEOUT) + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + tool_call_count += 1 + assert event.name == "get_weather" + args = json.loads(event.arguments) + assert "city" in args + result = _get_weather(**args) + conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=event.call_id, output=result) + ) + conn.response.create() + elif isinstance(event, RealtimeServerEventResponseTextDone): + final_text = event.text + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't itself a function call is the final answer. + # Output items surface as plain mappings (open union) or typed models. + output = event.response.output or [] + is_function_call = any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) + == "function_call" + for item in output + ) + if not is_function_call: + done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert done, "Did not receive a final (non-tool-call) response.done within the timeout" + assert tool_call_count >= 1, "Expected the agent to invoke the get_weather tool at least once" + assert final_text is not None and len(final_text.strip()) > 0 + finally: + project_client.agents.delete(agent_name=agent_name) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py new file mode 100644 index 000000000000..49501b7b772c --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py @@ -0,0 +1,286 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Live-only tests for the hand-written async ``async_client.realtime`` WebSocket streaming client. + +Async counterpart of ``test_voice_agent_realtime_live.py``. See that module's docstring for the +overall rationale (modeled on the ``azure-ai-voicelive`` package's live realtime test pattern: +skip entirely unless running live, generous per-event timeouts, assert on event types and +content presence/length rather than exact audio bytes). +""" + +import asyncio +import json +import time +from typing import Any, cast, Final + +import pytest +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceModelType, + VoiceOutputModality, +) + +# Seconds to wait for a single server event (session handshake, an audio delta, ...). +_EVENT_TIMEOUT: Final = 30 +# Seconds to wait for a full response turn to finish (may include a tool round-trip). +_RESPONSE_TIMEOUT: Final = 45 + + +def _get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +@pytest.mark.live_test_only +@pytest.mark.skipif( + not is_live(), + reason="Live-only: opens a real WebSocket connection to the realtime service, which cannot " + "be captured/replayed by the test proxy.", +) +class TestVoiceAgentRealtimeLiveAsync(TestBase): + """ + Live tests covering ``async_client.realtime.connect()`` (the hand-written async WebSocket + streaming client) against a real voice agent and a real service connection. + """ + + def _make_agent_name(self, suffix: str) -> str: + return f"test-realtime-live-async-{suffix}" + + async def _create_basic_agent(self, project_client, agent_name: str, model: str) -> None: + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_session_lifecycle_async -s + @servicePreparer() + async def test_realtime_session_lifecycle_async(self, **kwargs): + """ + Test opening and cleanly closing a realtime WebSocket session, and receiving the initial + ``session.created`` handshake event. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("lifecycle") + + try: + await self._create_basic_agent(project_client, agent_name, model) + + async with project_client.realtime.connect(agent_name=agent_name) as conn: + event = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(event, RealtimeServerEventSessionCreated) + assert event.type == "session.created" + # The `async with` block above closes the connection; a second `recv()` after close + # would raise, so we don't attempt one -- clean exit from the block is the assertion. + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_text_turn_produces_audio_and_transcript_async -s + @servicePreparer() + async def test_realtime_text_turn_produces_audio_and_transcript_async(self, **kwargs): + """ + Test sending one typed user turn and receiving a streamed audio + transcript reply. + + Sends a ``RealtimeConversationItemMessageUser`` text turn and asserts that the service + streams back at least one non-empty audio delta, a transcript-done event with non-empty + text, and a final ``response.done``. Content is not asserted verbatim (the model's actual + wording is not deterministic); only event types, ordering-independent presence, and basic + size/non-emptiness are checked, matching the ``azure-ai-voicelive`` live test convention. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("text-turn") + + try: + await self._create_basic_agent(project_client, agent_name, model) + + async with project_client.realtime.connect(agent_name=agent_name) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="Say the word 'hello' and nothing else." + ) + ], + ) + ) + await conn.response.create() + + audio_delta_count = 0 + audio_bytes = 0 + transcript_done_count = 0 + got_response_done = False + deadline = time.monotonic() + _RESPONSE_TIMEOUT + + while time.monotonic() < deadline and not got_response_done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(_EVENT_TIMEOUT, remaining)) + if isinstance(event, RealtimeServerEventResponseAudioDelta): + audio_delta_count += 1 + audio_bytes += len(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + transcript_done_count += 1 + assert event.transcript is not None and len(event.transcript.strip()) > 0 + elif isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert got_response_done, "Did not receive response.done within the timeout" + assert audio_delta_count > 0, "Expected at least one response.audio.delta event" + assert audio_bytes > 0, "Expected non-empty streamed audio" + assert transcript_done_count == 1, "Expected exactly one audio-transcript-done event" + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_function_tool_call_async -s + @servicePreparer() + async def test_realtime_function_tool_call_async(self, **kwargs): + """ + Test a client-executed function-tool round trip during a live realtime session. + + Configures the agent with a ``get_weather`` function tool, sends a prompt that should + trigger it, executes the tool call locally when the service asks for it, and sends the + result back so the agent can finish its reply -- the async counterpart of + ``sample_voice_agent_live_function_tool.py``'s pattern, adapted into an automated + assertion-based test. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("tool-call") + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + try: + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + + async with project_client.realtime.connect(agent_name=agent_name) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="What's the weather like in Seattle right now?" + ) + ], + ) + ) + await conn.response.create() + + tool_call_count = 0 + final_text = "" + deadline = time.monotonic() + _RESPONSE_TIMEOUT + done = False + + while time.monotonic() < deadline and not done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(_EVENT_TIMEOUT, remaining)) + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + tool_call_count += 1 + assert event.name == "get_weather" + args = json.loads(event.arguments) + assert "city" in args + result = _get_weather(**args) + await conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=event.call_id, output=result) + ) + await conn.response.create() + elif isinstance(event, RealtimeServerEventResponseTextDone): + final_text = event.text + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't itself a function call is the final answer. + # Output items surface as plain mappings (open union) or typed models. + output = event.response.output or [] + is_function_call = any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) + == "function_call" + for item in output + ) + if not is_function_call: + done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert done, "Did not receive a final (non-tool-call) response.done within the timeout" + assert tool_call_count >= 1, "Expected the agent to invoke the get_weather tool at least once" + assert final_text is not None and len(final_text.strip()) > 0 + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py new file mode 100644 index 000000000000..c9a904afb393 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py @@ -0,0 +1,308 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy +import pytest +from azure.core import MatchConditions +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + PSTNTelephonyTransferDestination, + TelephonyBindingStatus, + TelephonyTransferTarget, + TelephonyTransferTargets, + UpdateTelephonyBindingRequest, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephony(TestBase): + """ + Recorded tests covering the voice-agent telephony REST API surface exposed through + `project_client.agents.*` (telephony bindings, calls, and transfer targets), and the + top-level `project_client.agent_endpoint_conversations.*` generated-audio reads. + + NOTE: All tests in this file are currently marked `skip`: + - The telephony routes (`/agents/{agent_name}/telephony_bindings`, `/telephony_calls`, + `/telephony_transfer_targets`) are defined in the TypeSpec/SDK but not yet deployed to + the live test resource: every call returns an empty-body 404 (a routing-layer "no such + route" response from the service mesh, not an application-level not-found error - + confirmed by comparing against a known-working route's fully-populated JSON error body). + Un-skip `test_telephony_bindings_and_transfer_targets`/`test_telephony_calls_not_found` + once the service deploys these routes. + - `agent_endpoint_conversations.get_agent_conversation_item_generated_audio*` with a + made-up conversation/item ID hits the service's conversation-ID format validator and + returns an unhandled `500 server_error` instead of a clean `404` - the exact same + pre-existing behavior as the already-documented `agent_endpoint_conversations` + limitation below. Testing the success path needs a live realtime session whose playback + was interrupted; testing the not-found path needs a validly-formatted but nonexistent ID + (the format isn't publicly documented). `test_generated_audio_not_found` is left in as a + placeholder and currently skipped. + + Further NOTE: the following are intentionally NOT covered here at all since they require real + infrastructure this test environment does not have: + - `create_telephony_binding` with a real Teams Phone Extension or Twilio provider account + (needs real provider credentials/connections). Its request/response wiring is still + exercised indirectly through the header-injection unit tests in + `tests/foundry_features_header/`. + - `list_telephony_calls`/`get_telephony_call`/`transfer_telephony_call`/`end_telephony_call` + against an actual in-progress or historical call (needs a real inbound telephony call). + - Reading back a conversation (`project_client.agent_endpoint_conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed/deployed service-side, tests can be added/enabled for them. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_telephony_bindings_and_transfer_targets -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy() + def test_telephony_bindings_and_transfer_targets(self, **kwargs): + """ + Test telephony bindings (list/get/update/delete against a nonexistent binding) and a + round-trip of the telephony transfer targets configured for a voice agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_bindings project_client.agents.list_telephony_bindings() + GET /agents/{agent_name}/telephony_transfer_targets project_client.agents.get_telephony_transfer_targets() + PUT /agents/{agent_name}/telephony_transfer_targets project_client.agents.replace_telephony_transfer_targets() + GET /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.get_telephony_binding() + PATCH /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.update_telephony_binding() + DELETE /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.delete_telephony_binding() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyBindingsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony bindings. + bindings = list(project_client.agents.list_telephony_bindings(agent_name=agent_name)) + assert len(bindings) == 0 + + # A freshly created agent has no telephony transfer targets configured. + targets: TelephonyTransferTargets = project_client.agents.get_telephony_transfer_targets(agent_name=agent_name) + assert targets is not None + assert len(targets.transfer_targets) == 0 + + # Configure one PSTN transfer target. + new_target = TelephonyTransferTarget( + name="sales_desk", + description="Transfers to the sales desk for pricing questions.", + destination=PSTNTelephonyTransferDestination(value="+14255550123"), + ) + replaced_targets: TelephonyTransferTargets = project_client.agents.replace_telephony_transfer_targets( + agent_name=agent_name, + transfer_targets=[new_target], + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + assert len(replaced_targets.transfer_targets) == 1 + assert replaced_targets.transfer_targets[0].name == "sales_desk" + assert replaced_targets.transfer_targets[0].destination.kind == "pstn" + + # Confirm the change persisted. + confirmed_targets: TelephonyTransferTargets = project_client.agents.get_telephony_transfer_targets( + agent_name=agent_name + ) + assert len(confirmed_targets.transfer_targets) == 1 + assert confirmed_targets.transfer_targets[0].name == "sales_desk" + + # Clear the transfer targets (empty array clears all targets). + cleared_targets: TelephonyTransferTargets = project_client.agents.replace_telephony_transfer_targets( + agent_name=agent_name, + transfer_targets=[], + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + assert len(cleared_targets.transfer_targets) == 0 + + # A nonexistent telephony binding returns 404 on get/update/delete. + fake_binding_id = "nonexistent-binding-id" + with pytest.raises(ResourceNotFoundError): + project_client.agents.get_telephony_binding(agent_name=agent_name, binding_id=fake_binding_id) + with pytest.raises(ResourceNotFoundError): + project_client.agents.update_telephony_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + body=UpdateTelephonyBindingRequest(status=TelephonyBindingStatus.SUSPENDED), + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + with pytest.raises(ResourceNotFoundError): + project_client.agents.delete_telephony_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_telephony_calls_not_found -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy() + def test_telephony_calls_not_found(self, **kwargs): + """ + Test telephony calls: listing (empty on a fresh agent) and get/transfer/end against a + nonexistent call, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_calls project_client.agents.list_telephony_calls() + GET /agents/{agent_name}/telephony_calls/{call_id} project_client.agents.get_telephony_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:transfer project_client.agents.transfer_telephony_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:end project_client.agents.end_telephony_call() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony call history. + calls = list(project_client.agents.list_telephony_calls(agent_name=agent_name)) + assert len(calls) == 0 + + fake_call_id = "nonexistent-call-id" + with pytest.raises(ResourceNotFoundError): + project_client.agents.get_telephony_call(agent_name=agent_name, call_id=fake_call_id) + with pytest.raises(HttpResponseError) as transfer_exc_info: + project_client.agents.transfer_telephony_call( + agent_name=agent_name, call_id=fake_call_id, target="nonexistent-target" + ) + assert transfer_exc_info.value.status_code == 404 + with pytest.raises(HttpResponseError) as end_exc_info: + project_client.agents.end_telephony_call(agent_name=agent_name, call_id=fake_call_id) + assert end_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_generated_audio_not_found -s + @pytest.mark.skip( + reason="A made-up conversation/item ID hits the service's conversation-ID format validator " + "and returns an unhandled 500 instead of a clean 404 (same pre-existing behavior as " + "agent_endpoint_conversations). Needs a validly-formatted but nonexistent ID, or a real " + "realtime session, to test properly." + ) + @servicePreparer() + @recorded_by_proxy() + def test_generated_audio_not_found(self, **kwargs): + """ + Test the `agent_endpoint_conversations.get_agent_conversation_item_generated_audio`/ + `get_agent_conversation_item_generated_audio_content` methods against a nonexistent + conversation item, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-----------------------------------------------------------------------------------------+----------------------------------------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentGeneratedAudioTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_conversation_id = "nonexistent-conversation-id" + fake_item_id = "nonexistent-item-id" + with pytest.raises(ResourceNotFoundError): + project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + with pytest.raises(HttpResponseError) as content_exc_info: + list( + project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + ) + assert content_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py new file mode 100644 index 000000000000..a815bf7a12ef --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py @@ -0,0 +1,311 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils.aio import recorded_by_proxy_async +import pytest +from azure.core import MatchConditions +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + PSTNTelephonyTransferDestination, + TelephonyBindingStatus, + TelephonyTransferTarget, + TelephonyTransferTargets, + UpdateTelephonyBindingRequest, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephonyAsync(TestBase): + """ + Recorded tests covering the voice-agent telephony REST API surface exposed through + `project_client.agents.*` (telephony bindings, calls, and transfer targets), and the + top-level `project_client.agent_endpoint_conversations.*` generated-audio reads. + + NOTE: All tests in this file are currently marked `skip`: + - The telephony routes (`/agents/{agent_name}/telephony_bindings`, `/telephony_calls`, + `/telephony_transfer_targets`) are defined in the TypeSpec/SDK but not yet deployed to + the live test resource: every call returns an empty-body 404 (a routing-layer "no such + route" response from the service mesh, not an application-level not-found error - + confirmed by comparing against a known-working route's fully-populated JSON error body). + Un-skip `test_telephony_bindings_and_transfer_targets`/`test_telephony_calls_not_found` + once the service deploys these routes. + - `agent_endpoint_conversations.get_agent_conversation_item_generated_audio*` with a + made-up conversation/item ID hits the service's conversation-ID format validator and + returns an unhandled `500 server_error` instead of a clean `404` - the exact same + pre-existing behavior as the already-documented `agent_endpoint_conversations` + limitation below. Testing the success path needs a live realtime session whose playback + was interrupted; testing the not-found path needs a validly-formatted but nonexistent ID + (the format isn't publicly documented). `test_generated_audio_not_found` is left in as a + placeholder and currently skipped. + + Further NOTE: the following are intentionally NOT covered here at all since they require real + infrastructure this test environment does not have: + - `create_telephony_binding` with a real Teams Phone Extension or Twilio provider account + (needs real provider credentials/connections). Its request/response wiring is still + exercised indirectly through the header-injection unit tests in + `tests/foundry_features_header/`. + - `list_telephony_calls`/`get_telephony_call`/`transfer_telephony_call`/`end_telephony_call` + against an actual in-progress or historical call (needs a real inbound telephony call). + - Reading back a conversation (`project_client.agent_endpoint_conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed/deployed service-side, tests can be added/enabled for them. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_telephony_bindings_and_transfer_targets -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_telephony_bindings_and_transfer_targets(self, **kwargs): + """ + Test telephony bindings (list/get/update/delete against a nonexistent binding) and a + round-trip of the telephony transfer targets configured for a voice agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_bindings project_client.agents.list_telephony_bindings() + GET /agents/{agent_name}/telephony_transfer_targets project_client.agents.get_telephony_transfer_targets() + PUT /agents/{agent_name}/telephony_transfer_targets project_client.agents.replace_telephony_transfer_targets() + GET /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.get_telephony_binding() + PATCH /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.update_telephony_binding() + DELETE /agents/{agent_name}/telephony_bindings/{binding_id} project_client.agents.delete_telephony_binding() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyBindingsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony bindings. + bindings = [b async for b in project_client.agents.list_telephony_bindings(agent_name=agent_name)] + assert len(bindings) == 0 + + # A freshly created agent has no telephony transfer targets configured. + targets: TelephonyTransferTargets = await project_client.agents.get_telephony_transfer_targets( + agent_name=agent_name + ) + assert targets is not None + assert len(targets.transfer_targets) == 0 + + # Configure one PSTN transfer target. + new_target = TelephonyTransferTarget( + name="sales_desk", + description="Transfers to the sales desk for pricing questions.", + destination=PSTNTelephonyTransferDestination(value="+14255550123"), + ) + replaced_targets: TelephonyTransferTargets = await project_client.agents.replace_telephony_transfer_targets( + agent_name=agent_name, + transfer_targets=[new_target], + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + assert len(replaced_targets.transfer_targets) == 1 + assert replaced_targets.transfer_targets[0].name == "sales_desk" + assert replaced_targets.transfer_targets[0].destination.kind == "pstn" + + # Confirm the change persisted. + confirmed_targets: TelephonyTransferTargets = await project_client.agents.get_telephony_transfer_targets( + agent_name=agent_name + ) + assert len(confirmed_targets.transfer_targets) == 1 + assert confirmed_targets.transfer_targets[0].name == "sales_desk" + + # Clear the transfer targets (empty array clears all targets). + cleared_targets: TelephonyTransferTargets = await project_client.agents.replace_telephony_transfer_targets( + agent_name=agent_name, + transfer_targets=[], + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + assert len(cleared_targets.transfer_targets) == 0 + + # A nonexistent telephony binding returns 404 on get/update/delete. + fake_binding_id = "nonexistent-binding-id" + with pytest.raises(ResourceNotFoundError): + await project_client.agents.get_telephony_binding(agent_name=agent_name, binding_id=fake_binding_id) + with pytest.raises(ResourceNotFoundError): + await project_client.agents.update_telephony_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + body=UpdateTelephonyBindingRequest(status=TelephonyBindingStatus.SUSPENDED), + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + with pytest.raises(ResourceNotFoundError): + await project_client.agents.delete_telephony_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + etag=None, + match_condition=MatchConditions.Unconditionally, + ) + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_telephony_calls_not_found -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_telephony_calls_not_found(self, **kwargs): + """ + Test telephony calls: listing (empty on a fresh agent) and get/transfer/end against a + nonexistent call, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_calls project_client.agents.list_telephony_calls() + GET /agents/{agent_name}/telephony_calls/{call_id} project_client.agents.get_telephony_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:transfer project_client.agents.transfer_telephony_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:end project_client.agents.end_telephony_call() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony call history. + calls = [c async for c in project_client.agents.list_telephony_calls(agent_name=agent_name)] + assert len(calls) == 0 + + fake_call_id = "nonexistent-call-id" + with pytest.raises(ResourceNotFoundError): + await project_client.agents.get_telephony_call(agent_name=agent_name, call_id=fake_call_id) + with pytest.raises(HttpResponseError) as transfer_exc_info: + await project_client.agents.transfer_telephony_call( + agent_name=agent_name, call_id=fake_call_id, target="nonexistent-target" + ) + assert transfer_exc_info.value.status_code == 404 + with pytest.raises(HttpResponseError) as end_exc_info: + await project_client.agents.end_telephony_call(agent_name=agent_name, call_id=fake_call_id) + assert end_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_generated_audio_not_found -s + @pytest.mark.skip( + reason="A made-up conversation/item ID hits the service's conversation-ID format validator " + "and returns an unhandled 500 instead of a clean 404 (same pre-existing behavior as " + "agent_endpoint_conversations). Needs a validly-formatted but nonexistent ID, or a real " + "realtime session, to test properly." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_generated_audio_not_found(self, **kwargs): + """ + Test the `agent_endpoint_conversations.get_agent_conversation_item_generated_audio`/ + `get_agent_conversation_item_generated_audio_content` methods against a nonexistent + conversation item, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-----------------------------------------------------------------------------------------+----------------------------------------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentGeneratedAudioTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_conversation_id = "nonexistent-conversation-id" + fake_item_id = "nonexistent-item-id" + with pytest.raises(ResourceNotFoundError): + await project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + with pytest.raises(HttpResponseError) as content_exc_info: + [ + chunk + async for chunk in await project_client.agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + ] + assert content_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/conftest.py b/sdk/ai/azure-ai-projects/tests/conftest.py index 5d5722183e64..605d6f1d9fc6 100644 --- a/sdk/ai/azure-ai-projects/tests/conftest.py +++ b/sdk/ai/azure-ai-projects/tests/conftest.py @@ -369,6 +369,20 @@ def sanitize_url_paths(): # would otherwise fail to decode -> UnicodeDecodeError). add_remove_header_sanitizer(headers="Content-Encoding") + # Strip Foundry-Features from record/playback matching. Its value is a comma-joined list of + # preview opt-in flags that legitimately changes over time as new preview features are added + # (e.g. VoiceAgents=V1Preview was added later); exact-matching it against older cassettes + # would otherwise cause spurious playback failures unrelated to what a given test is actually + # validating. Some affected cassettes (test_ai_agents_instrumentor.py/_async.py) have been + # re-recorded and no longer need this, but others still rely on it pending re-recording (see + # test_responses_instrumentor_workflow.py, which currently fails to re-record live due to an + # unrelated pre-existing gap in its expected span-attribute list vs. actual gen_ai.usage.* + # token attributes now returned by the service). Tests that specifically need to assert on + # this header's value use a dedicated unit-test suite (tests/foundry_features_header) with a + # capturing transport instead of the test-proxy, so this does not reduce coverage of the + # header-injection behavior itself. + add_remove_header_sanitizer(headers="Foundry-Features") + # Remove the following sanitizers since certain fields are needed in tests and are non-sensitive: # - AZSDK3493: $..name # - AZSDK3430: $..id diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py index 0cb5faeb0fd4..9b27960efc15 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py @@ -46,7 +46,12 @@ "schedules": "Schedules=V1Preview", "skills": "Skills=V1Preview", "datasets": "DataGenerationJobs=V1Preview", - "agents": "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + "agents": "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + # NOTE: `agent_endpoint_conversations` used to need an entry here (it lived as a nested + # `.beta` sub-client). Upstream has since merged it entirely into the top-level, stable + # `agent_endpoint_conversations` client attribute (see the dedicated + # `_NON_BETA_OPTIONAL_TEST_CASES` entries below), so it must NOT have an entry in this dict -- + # it's no longer part of `.beta` at all. } # Methods on .beta sub-clients that are NOT simple one-HTTP-call wrappers and @@ -84,14 +89,188 @@ # The test id is derived automatically from method_name. pytest.param( "agents.create_version", - "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.generate_agent", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.create_telephony_binding", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.list_telephony_bindings", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.get_telephony_binding", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.update_telephony_binding", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.delete_telephony_binding", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.list_telephony_calls", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.get_telephony_call", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.transfer_telephony_call", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.end_telephony_call", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.get_telephony_transfer_targets", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agents.replace_telephony_transfer_targets", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,VoiceAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + ), + pytest.param( + "agent_telephony.create_telephony_call_job", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.get_telephony_call_job", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.cancel_telephony_call_job", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.create_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.get_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.begin_import_telephony_campaign_recipients", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.get_telephony_campaign_recipient_import", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.begin_validate_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.begin_publish_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.pause_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.resume_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.cancel_telephony_campaign", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_telephony.get_telephony_operation", + "VoiceAgents=V1Preview", ), pytest.param( "evaluation_rules.create_or_update", "Evaluations=V1Preview", ), + # `agent_endpoint_conversations` is a top-level client attribute. Like `agents.generate_agent`, + # every one of its methods optionally sends the Foundry-Features header gated behind + # `allow_preview`, so they belong here rather than in EXPECTED_FOUNDRY_FEATURES above. Upstream + # merged what used to be the separate, always-on `.beta.agent_endpoint_conversations` sub-client + # (12 methods) entirely into this top-level attribute (see the NOTE below), so all 14 methods are + # now covered here uniformly. + pytest.param( + "agent_endpoint_conversations.list_agent_conversations", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.delete_agent_conversation", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.list_agent_conversation_responses", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_response", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.list_agent_conversation_response_items", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.list_agent_conversation_items", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_item", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_item_audio", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_item_audio_content", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_item_generated_audio", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_item_generated_audio_content", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_audio", + "VoiceAgents=V1Preview", + ), + pytest.param( + "agent_endpoint_conversations.get_agent_conversation_audio_content", + "VoiceAgents=V1Preview", + ), ] +# NOTE: `agent_endpoint_conversations` used to need its own dedicated test cases here (it was +# wrapped with `_OperationMethodHeaderProxy` directly in `_patch.py`, unconditionally regardless +# of `allow_preview`, since it lived as a top-level client attribute rather than a `.beta` +# sub-client). It then moved under `.beta` upstream (all methods together) and was covered +# automatically by the dynamic discovery in test_foundry_features_header_on_beta_operations.py. +# Upstream has since merged the entire `.beta.agent_endpoint_conversations` sub-client back into a +# single top-level `agent_endpoint_conversations` attribute (all 14 methods, no `.beta` variant +# left at all) that once again needs dedicated `allow_preview`-gated test cases -- see above. This +# operation group has now round-tripped between "top-level" and "nested under .beta" more than +# once across TypeSpec regenerations; if it moves again, update both this list and +# EXPECTED_FOUNDRY_FEATURES above together. + # Both sentinel values – used by _make_fake_call to detect required parameters # whose defaults are the internal _Unset object (rather than inspect.Parameter.empty). _UNSET_SENTINELS: frozenset = frozenset({_SyncUnset, _AsyncUnset}) diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py index bc11af8db927..fc89b11cd972 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py @@ -213,18 +213,20 @@ def _make_fake_call_with_headers(method: Any, headers: dict) -> Any: return lambda: method(*args, **kwargs) @pytest.mark.parametrize("method_name,_expected_header_value", _NON_BETA_OPTIONAL_TEST_CASES) + @pytest.mark.parametrize("header_name", [FOUNDRY_FEATURES_HEADER, "foundry-features", "FoUnDrY-FeAtUrEs"]) def test_foundry_features_header_override_on_ga_operations( self, client_preview_enabled: AIProjectClient, method_name: str, _expected_header_value: str, + header_name: str, ) -> None: """Caller-supplied headers={"Foundry-Features": "CustomValue"} must reach the transport instead of the internally-set default value (allow_preview=True).""" subclient_name, method_attr = method_name.split(".") sc = getattr(client_preview_enabled, subclient_name) method = getattr(sc, method_attr) - custom_headers = {FOUNDRY_FEATURES_HEADER: "CustomValue"} + custom_headers = {header_name: "CustomValue"} request = self._capture(self._make_fake_call_with_headers(method, custom_headers)) assert ( request.headers.get(FOUNDRY_FEATURES_HEADER) == "CustomValue" diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations_async.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations_async.py index 05fa75a2dca6..2d117f288d74 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations_async.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations_async.py @@ -222,18 +222,20 @@ def _make_fake_call_with_headers(method: Any, headers: dict) -> Any: @pytest.mark.asyncio @pytest.mark.parametrize("method_name,_expected_header_value", _NON_BETA_OPTIONAL_TEST_CASES) + @pytest.mark.parametrize("header_name", [FOUNDRY_FEATURES_HEADER, "foundry-features", "FoUnDrY-FeAtUrEs"]) async def test_foundry_features_header_override_on_ga_operations_async( self, async_client_preview_enabled: AsyncAIProjectClient, method_name: str, _expected_header_value: str, + header_name: str, ) -> None: """Caller-supplied headers={"Foundry-Features": "CustomValue"} must reach the transport instead of the internally-set default value (allow_preview=True).""" subclient_name, method_attr = method_name.split(".") sc = getattr(async_client_preview_enabled, subclient_name) method = getattr(sc, method_attr) - custom_headers = {FOUNDRY_FEATURES_HEADER: "CustomValue"} + custom_headers = {header_name: "CustomValue"} request = await self._capture_async(self._make_fake_call_with_headers(method, custom_headers)) assert ( request.headers.get(FOUNDRY_FEATURES_HEADER) == "CustomValue" diff --git a/sdk/ai/azure-ai-projects/tests/samples/test_samples.py b/sdk/ai/azure-ai-projects/tests/samples/test_samples.py index ee9d60f80fdd..f0721ef8a772 100644 --- a/sdk/ai/azure-ai-projects/tests/samples/test_samples.py +++ b/sdk/ai/azure-ai-projects/tests/samples/test_samples.py @@ -383,3 +383,38 @@ def test_finetuning_samples(self, sample_path: str, **kwargs) -> None: executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs) executor.execute() executor.validate_print_calls_by_llm() + + @pytest.mark.parametrize( + "sample_path", + get_sample_paths( + "agents/voice", + samples_to_skip=[ + # These use client.realtime, a persistent WebSocket connection. recorded_by_proxy + # only supports the AZURE_CORE/HTTPX2 HTTP(S) transports used elsewhere in this + # file, so a WebSocket session can't be captured/replayed through this mechanism. + "sample_voice_agent_live_text_conversation.py", + "sample_voice_agent_live_text_conversation_async.py", + "sample_voice_agent_live_function_tool.py", + "sample_voice_agent_live_audio_conversation_async.py", + # These read back a conversation transcript/audio from a *pre-existing*, + # already-persisted voice session (FOUNDRY_VOICE_CONVERSATION_ID), which none of + # the runnable samples above create (they all use the skipped WebSocket path to + # do so). Needs a recorded conversation fixture before it can run here. + "sample_voice_agent_read_conversation.py", + "sample_voice_agent_read_conversation_audio.py", + # PR #48484: recording not yet available for these REST-only samples. + "sample_voice_agent_basic.py", + "sample_voice_agent_generate.py", + "sample_voice_agent_versions.py", + "sample_voice_agent_with_tools.py", + ], + ), + ) + @servicePreparer() + @SamplePathPasser() + @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + def test_voice_samples(self, sample_path: str, **kwargs) -> None: + env_vars = get_sample_env_vars(kwargs) + executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs) + executor.execute() + executor.validate_print_calls_by_llm() diff --git a/sdk/ai/azure-ai-projects/tests/samples/test_samples_async.py b/sdk/ai/azure-ai-projects/tests/samples/test_samples_async.py index 7fdbe416f0d4..61aea2c6f90e 100644 --- a/sdk/ai/azure-ai-projects/tests/samples/test_samples_async.py +++ b/sdk/ai/azure-ai-projects/tests/samples/test_samples_async.py @@ -312,3 +312,28 @@ async def test_toolboxes_samples(self, sample_path: str, **kwargs) -> None: executor = AsyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs) await executor.execute_async() await executor.validate_print_calls_by_llm_async() + + @pytest.mark.parametrize( + "sample_path", + get_async_sample_paths( + "agents/voice", + samples_to_skip=[ + # These use async_client.realtime, a persistent WebSocket connection. + # recorded_by_proxy_async only supports the AZURE_CORE/HTTPX2 HTTP(S) transports + # used elsewhere in this file, so a WebSocket session can't be captured/replayed + # through this mechanism. + "sample_voice_agent_live_text_conversation_async.py", + "sample_voice_agent_live_audio_conversation_async.py", + # PR #48484: recording not yet available for this REST-only sample. + "sample_voice_agent_basic_async.py", + ], + ), + ) + @servicePreparer() + @SamplePathPasser() + @recorded_by_proxy_async(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + async def test_voice_samples(self, sample_path: str, **kwargs) -> None: + env_vars = get_sample_env_vars(kwargs) + executor = AsyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs) + await executor.execute_async() + await executor.validate_print_calls_by_llm_async() diff --git a/sdk/ai/azure-ai-projects/tests/test_base.py b/sdk/ai/azure-ai-projects/tests/test_base.py index 4069479fdcb3..a4ece82551d2 100644 --- a/sdk/ai/azure-ai-projects/tests/test_base.py +++ b/sdk/ai/azure-ai-projects/tests/test_base.py @@ -43,6 +43,7 @@ foundry_project_api_key="sanitized-api-key", foundry_agent_name="sanitized-agent-name", foundry_model_name="sanitized-model-deployment-name", + foundry_voice_model_name="sanitized-model-deployment-name", llm_validation_project_endpoint="https://sanitized-account-name.services.ai.azure.com/api/projects/sanitized-project-name", image_generation_model_deployment_name="sanitized-gpt-image", bing_project_connection_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sanitized-resource-group/providers/Microsoft.CognitiveServices/accounts/sanitized-account/projects/sanitized-project/connections/sanitized-bing-connection", diff --git a/sdk/ai/azure-ai-projects/tsp-location.yaml b/sdk/ai/azure-ai-projects/tsp-location.yaml new file mode 100644 index 000000000000..1da98888dc38 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tsp-location.yaml @@ -0,0 +1,30 @@ +directory: specification/ai-foundry/data-plane/Foundry/src/sdk-python-js-azure-ai-projects +commit: b538ac90619e094630e3c773d5231070809caf48 +repo: Azure/azure-rest-api-specs +additionalDirectories: +- specification/ai-foundry/data-plane/Foundry/src/agents +- specification/ai-foundry/data-plane/Foundry/src/agent-insights +- specification/ai-foundry/data-plane/Foundry/src/agents-optimization +- specification/ai-foundry/data-plane/Foundry/src/agents-session-files +- specification/ai-foundry/data-plane/Foundry/src/agents-microsoft365 +- specification/ai-foundry/data-plane/Foundry/src/common +- specification/ai-foundry/data-plane/Foundry/src/connections +- specification/ai-foundry/data-plane/Foundry/src/data_generation_jobs +- specification/ai-foundry/data-plane/Foundry/src/datasets +- specification/ai-foundry/data-plane/Foundry/src/deployments +- specification/ai-foundry/data-plane/Foundry/src/evaluation-rules +- specification/ai-foundry/data-plane/Foundry/src/evaluation-taxonomies +- specification/ai-foundry/data-plane/Foundry/src/evaluators +- specification/ai-foundry/data-plane/Foundry/src/indexes +- specification/ai-foundry/data-plane/Foundry/src/insights +- specification/ai-foundry/data-plane/Foundry/src/memory-stores +- specification/ai-foundry/data-plane/Foundry/src/models +- specification/ai-foundry/data-plane/Foundry/src/openai +- specification/ai-foundry/data-plane/Foundry/src/red-teams +- specification/ai-foundry/data-plane/Foundry/src/routines +- specification/ai-foundry/data-plane/Foundry/src/schedules +- specification/ai-foundry/data-plane/Foundry/src/sdk-common +- specification/ai-foundry/data-plane/Foundry/src/skills +- specification/ai-foundry/data-plane/Foundry/src/toolboxes +- specification/ai-foundry/data-plane/Foundry/src/tools +- specification/ai-foundry/data-plane/Foundry/src/voice-agents diff --git a/sdk/ai/azure-ai-projects/tsp-location.yaml.saved b/sdk/ai/azure-ai-projects/tsp-location.yaml.saved index 615a7cd64457..1fd9745871f3 100644 --- a/sdk/ai/azure-ai-projects/tsp-location.yaml.saved +++ b/sdk/ai/azure-ai-projects/tsp-location.yaml.saved @@ -1,5 +1,5 @@ directory: specification/ai-foundry/data-plane/Foundry/src/sdk-python-js-azure-ai-projects -commit: 675e111febec298cdc8e640d9f8653cc287c5dd1 +commit: 16e19af7a5193435c71b3afbd3391bdf5db9010c repo: Azure/azure-rest-api-specs additionalDirectories: - specification/ai-foundry/data-plane/Foundry/src/agents diff --git a/sdk/ai/cspell.yaml b/sdk/ai/cspell.yaml index 18e70907235b..dc9b01add7bb 100644 --- a/sdk/ai/cspell.yaml +++ b/sdk/ai/cspell.yaml @@ -21,6 +21,8 @@ words: - azureopenai - balapvbyostoragecanary - BLPHARMA + - BYOM + - BYOS - cegr - closefd - cogsvc @@ -34,6 +36,8 @@ words: - deser - devtools - dotenv + - dtmf + - DTMF - dtype - estás - evals @@ -64,6 +68,7 @@ words: - LLMRAG - logprobs - LUMIFOOD + - MCPHTTP - miniconda - Ministral - mlflow @@ -80,6 +85,8 @@ words: - openai - openmpi - oupfoo + - pcma + - pcmu - pipelinerunid - PRIFINS - prompty @@ -93,7 +100,9 @@ words: - quantitive - rdel - recsmplmdl + - redef - reraises + - retriable - roups - runid - runsvdir