diff --git a/sdk/ai/azure-ai-agents/CHANGELOG.md b/sdk/ai/azure-ai-agents/CHANGELOG.md index 5dc9cfefc6ffa..768869a84a8bf 100644 --- a/sdk/ai/azure-ai-agents/CHANGELOG.md +++ b/sdk/ai/azure-ai-agents/CHANGELOG.md @@ -4,17 +4,97 @@ ### Features Added +- Added preview voice-agent post-call delivery through `VoiceAgentPostCallConfiguration` for Event Grid and routine + destinations. +- Added preview inline voice subagents and handoff configuration, runtime state, and session handoff events. +- Added preview SIP telephony bindings. +- Added preview Live-agent Responses delegation settings using OpenAI Java's `ResponsesDelegationConfig`. +- Reused OpenAI Java's Live audio settings, voice, and session usage models instead of generating duplicate types. - Added preview typed `of*` factories on `RealtimeResponseInputItem` and `RealtimeResponseInputContent` for heterogeneous voice-agent response input and user-message content, with a shared `RealtimeResponseInputItemStatus` enum. +- Added preview voice-agent system tools, transfer routing, and system-tool intent and input-collection events. +- Added preview voice-agent telephony campaigns with recipient validation and scheduling. +- Added Live voice-agent definitions and preview Live conversation REST clients for persisted conversations, items, + and audio. +- Added preview synchronous and asynchronous GPT Live WebSocket clients through + `AgentsClientBuilder.beta().buildBetaVoiceAgentsLiveWebSocketClient()` and + `buildBetaVoiceAgentsLiveWebSocketAsyncClient()`. Native Live events are sent and received as lossless JSON + using `BinaryData`, separately from the Realtime protocol clients. +- Added typed GPT Live sends through `sendEvent(com.openai.models.live.ClientEvent)` and typed receives through + `receiveEvents()`, retaining the raw JSON APIs. The synchronous client also supports per-event receive timeouts. + Live session clients decode native OpenAI `ServerEvent` models; shared transports buffer only raw messages. + Raw receivers do not depend on JSON parsing or typed decoding succeeding. + Live and Realtime clients select their own routes and headers without a shared protocol-mode flag. +- Added synchronous/asynchronous persisted GPT Live conversation history and audio-download examples with offline tests. +- Added opt-in persistence to the GPT Live text and microphone/speaker samples using `FOUNDRY_GPT_LIVE_STORE` (default `false`), + with explicit startup output when the service does not provide a persisted conversation ID. +- Added runnable native GPT Live samples for synchronous/asynchronous multi-turn text, asynchronous microphone + and speaker audio, and Responses backend function tools, including sample-agent creation and cleanup. + Model deployment names default to `gpt-live-1` and `gpt-5.6-terra` when their environment variables are unset. + The audio sample requests an opening greeting, labels spoken transcripts without duplicating backend text, + reports moderation failures explicitly, and shuts down shared Reactor schedulers when its standalone main exits. + The primary text samples show agent/delegation configuration, typed sends, event handling, and graceful closure + directly, processing command-line prompts or one default question without console input or audio playback. + Separate advanced interactive text samples support terminal input with blank-line, `exit`, and `quit` termination. + The standalone sample mains shut down shared Reactor schedulers on exit. + Both advanced interactive samples request a spoken greeting, play frontend audio and print spoken transcripts + instead of backend working notes. It preserves server closure diagnostics and handles remote hangup normally. + Interactive voice mode streams paced silent PCM input while typing (consuming voice-session usage), uses + blocking console line reads instead of readiness polling, and uses the native console reader when attached. + Assistant transcript fragments are assembled into utterances independently of backend and typed turns. + Completed text is buffered while typing on the `You:` line; audio and input remain available, and incomplete + text is not split or relabeled at Enter. Speech-inactivity boundaries remain heuristic. + The first input prompt waits for greeting audio and text, a one-second quiet period, and queued speaker playback. + Continuous silent output does not extend that quiet period, and paced silent input tolerates send backpressure + without overflowing a periodic timer. + Removed redundant blank lines between console input, assistant transcripts, and session closure. ### Breaking Changes +- Renamed preview `VoiceAgentWebSocketConnectionOptions.getTransport()` and `setTransport(...)` to + `getTransportType()` and `setTransportType(...)`. +- Replaced preview transcription languages with OpenAI Java's `TranscriptionLanguage` and listed MCP tools with + `RealtimeMcpListTools.Tool`. MCP tool input schemas and annotations now retain their JSON contents. +- Replaced preview realtime session configurations, audio formats, turn detection, and MCP errors with the complete + OpenAI Java types. `RealtimeSessionUpdateEvent.getSession()` now returns `SessionUpdateEvent.Session`, audio-format + properties use `RealtimeAudioFormats`, and `RealtimeMcpToolCall.getError()` returns OpenAI's `RealtimeMcpToolCall.Error`. + Foundry-specific session and turn-detection models remain unchanged. +- Updated preview telephony binding, call-job, transfer, and retry model shapes to match the redesigned service contract. +- Standardized preview system-tool names with `VoiceAgent*Event`, `outputReference`, and `objectType`, and exposed + system-tool and transfer-ring timeouts as `Duration` through `timeout` and `ringTimeout`. System-tool items are + service-generated and no longer expose public constructors or setters. +- Moved preview Live-conversation client factories under `AgentsClientBuilder.beta()`. +- Changed preview Live delegation acknowledgement delays to `Duration` with unit-free `acknowledgementDelay` + accessors, and renamed the managed-delegation duration property from `offsetMs` to `offset`. +- Replaced the numeric/string token-limit accessors on preview voice and realtime models with + `getMaxOutputTokens()` and `setMaxOutputTokens(VoiceAgentMaxOutputTokens)`, where writable. `InlineVoiceSubagent` uses + the same type through `getMaxResponseOutputTokens()` and `setMaxResponseOutputTokens(VoiceAgentMaxOutputTokens)`. + Use `VoiceAgentMaxOutputTokens.of(count)` for a numeric limit or `VoiceAgentMaxOutputTokens.MAXIMUM` for `"inf"`, and + inspect the value with `getCount()` or `isMaximum()`. Passing `null` to a setter clears the property. +- Replaced the per-variant tool-choice accessors on preview voice and realtime models with + `getToolChoice()` and `setToolChoice(VoiceAgentToolChoice)`, where writable. Use `VoiceAgentToolChoice.ofMode`, + `ofFunction`, or `ofMcp` to create a choice, and `getMode`, `getFunction`, or `getMcp` to inspect it. Getters for + other variants return `null`. Passing `null` to the setter clears the property; the factories reject null arguments. + `PromptAgentDefinition` is unchanged. +- Added preview typed `of*` factories on `RealtimeResponseInputItem` and `RealtimeResponseInputContent` for heterogeneous + voice-agent response input and user-message content, with a shared `RealtimeResponseInputItemStatus` enum. - Changed the preview `VoiceAgentResponseCreateOptions` input list to `List`. ### Bugs Fixed +- Preserved handoff state when serializing and deserializing voice-agent session response configurations. +- Preserved exact numeric values when round-tripping agent structured input defaults and schemas, telephony + structured inputs, and response structured inputs through `BinaryData`. +- Fixed OpenAI model JSON conversion to use an explicit Jackson serializer, preserving explicit nulls without + depending on the application's Azure JSON serializer provider. +- Removed query values from WebSocket proxy-failure diagnostics to avoid logging structured inputs. +- Updated the synchronous live text sample to replace an existing sample agent on a creation conflict and + delete the replacement on exit, including when the conversation fails. + ### Other Changes +- Extracted shared protocol-neutral WebSocket transports for Live and Realtime, keeping independent blocking + and asynchronous implementations and protocol-specific event decoding in the respective clients. - Regenerated the client with `@azure-tools/openai-typespec` version `1.34.1`. ## 2.9.0 (2026-10-30) @@ -196,8 +276,8 @@ subagents, persistence, avatars, and animation. - Added `createAgentFromPrompt` and `createAgentFromPromptWithResponse` to `BetaAgentsClient` and `BetaAgentsAsyncClient` for generating and creating agents from kind-specific high-level inputs. -- Added preview `BetaVoiceAgentWebSocketClient`, `BetaVoiceAgentWebSocketAsyncClient`, - `BetaVoiceAgentWebSocketSessionClient`, and `BetaVoiceAgentWebSocketSessionAsyncClient` for authenticated realtime +- Added preview `BetaVoiceAgentsWebSocketClient`, `BetaVoiceAgentsWebSocketAsyncClient`, + `BetaVoiceAgentsWebSocketSessionClient`, and `BetaVoiceAgentsWebSocketSessionAsyncClient` for authenticated realtime `wss://` sessions. The clients support typed and raw events, text and audio input, response cancellation, client-executed function results, persisted conversations, agent-version overrides, and the related realtime session, conversation-item, response, transcription, MCP, audio, avatar, and RTC event models. diff --git a/sdk/ai/azure-ai-agents/README.md b/sdk/ai/azure-ai-agents/README.md index 003d4a3770b34..415ab279f71e2 100644 --- a/sdk/ai/azure-ai-agents/README.md +++ b/sdk/ai/azure-ai-agents/README.md @@ -70,7 +70,8 @@ The Agents client library has the following sub-clients which group the differen - `ResponsesClient` / `ResponsesAsyncClient`: Create responses that require Azure-specific request fields, such as an explicit `AgentReference` or structured inputs. For standard OpenAI Responses API calls through an agent endpoint, use an agent-scoped OpenAI client. See the [OpenAI Responses API documentation][openai_responses_api_docs] for more information. - `BetaMemoryStoresClient` / `BetaMemoryStoresAsyncClient` **(preview)**: Manage memory stores and individual memory items for agents. - `ToolboxesClient` / `ToolboxesAsyncClient`: Manage toolboxes and toolbox versions. -- `BetaVoiceAgentWebSocketClient` / `BetaVoiceAgentWebSocketAsyncClient` **(preview)**: Open typed realtime WebSocket sessions with voice agents. +- `BetaVoiceAgentsWebSocketClient` / `BetaVoiceAgentsWebSocketAsyncClient` **(preview)**: Open typed realtime WebSocket sessions with voice agents. +- `BetaVoiceAgentsLiveWebSocketClient` / `BetaVoiceAgentsLiveWebSocketAsyncClient` **(preview)**: Open native GPT Live WebSocket sessions with persisted Live voice agents. - `BetaVoiceAgentsTelephonyClient` / `BetaVoiceAgentsTelephonyAsyncClient` **(preview)**: Manage telephony bindings, calls, transfer targets, and outbound call jobs. - `BetaVoiceAgentsConversationsClient` / `BetaVoiceAgentsConversationsAsyncClient` **(preview)**: Read and delete persisted voice-agent conversations and retrieve their responses, items, and audio. @@ -197,7 +198,8 @@ Build clients whose names start with `Beta` from `AgentsClientBuilder.beta()`. T |---|---| | `BetaAgentsClient` | `WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,VoiceAgents=V1Preview,DigitalWorker=V1Preview,GitHubCopilot=V1Preview,Skills=V1Preview,MicrosoftCopilot=V1Preview` | | `BetaMemoryStoresClient` | `MemoryStores=V1Preview` | -| `BetaVoiceAgentWebSocketClient` | `VoiceAgents=V1Preview` | +| `BetaVoiceAgentsWebSocketClient` | `VoiceAgents=V1Preview` | +| `BetaVoiceAgentsLiveWebSocketClient` / `BetaVoiceAgentsLiveWebSocketAsyncClient` | `VoiceAgents=V1Preview` | | `BetaVoiceAgentsTelephonyClient` | `VoiceAgents=V1Preview` | | `BetaVoiceAgentsConversationsClient` | `VoiceAgents=V1Preview` | @@ -206,7 +208,7 @@ The async `Beta*AsyncClient` counterparts follow the same behavior. ### Realtime voice-agent sessions Create and manage preview voice agents with `VoiceAgentDefinition` and an `AgentsClient` or `AgentsAsyncClient` built -using `allowPreview(true)`. Use `BetaVoiceAgentWebSocketClient` or `BetaVoiceAgentWebSocketAsyncClient` to open a typed, +using `allowPreview(true)`. Use `BetaVoiceAgentsWebSocketClient` or `BetaVoiceAgentsWebSocketAsyncClient` to open a typed, bidirectional session with an existing voice agent. The client acquires a token for `https://ai.azure.com/.default`, negotiates the `realtime` WebSocket subprotocol, and sends the required `VoiceAgents=V1Preview` feature header automatically. @@ -989,10 +991,10 @@ AgentsClientBuilder builder = new AgentsClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .endpoint(endpoint); -BetaVoiceAgentWebSocketClient realtimeClient - = builder.beta().buildBetaVoiceAgentWebSocketClient(); -BetaVoiceAgentWebSocketAsyncClient realtimeAsyncClient - = builder.beta().buildBetaVoiceAgentWebSocketAsyncClient(); +BetaVoiceAgentsWebSocketClient realtimeClient + = builder.beta().buildBetaVoiceAgentsWebSocketClient(); +BetaVoiceAgentsWebSocketAsyncClient realtimeAsyncClient + = builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient(); ``` #### Send a synchronous text turn @@ -1021,7 +1023,7 @@ VoiceAgentWebSocketConnectionOptions options .setReceiveBufferCapacity(512) .setMaxMessageSize(8 * 1024 * 1024) .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR); -try (BetaVoiceAgentWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName, options)) { +try (BetaVoiceAgentsWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName, options)) { session.sendEvent(BinaryData.fromString( "{\"type\":\"response.create\",\"event_id\":\"response-1\"}")); for (RealtimeServerEvent event : session.receiveEvents()) { @@ -1042,7 +1044,7 @@ Use `close(code, reason)` or asynchronous `closeAsync(code, reason)` to send a c fit in 123 UTF-8 bytes and close codes must be valid WebSocket codes. The first asynchronous close request wins. ```java -try (BetaVoiceAgentWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName)) { +try (BetaVoiceAgentsWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName)) { session.sendText("Hello! Tell me about the services you provide."); session.createResponse(); @@ -1078,9 +1080,9 @@ Mono.usingWhen( }) .takeUntil(event -> event instanceof RealtimeResponseDoneEvent) .then(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync, + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync) + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync) .block(); ``` @@ -1101,8 +1103,236 @@ When a `RealtimeResponseFunctionCallArgumentsDoneEvent` requests a client-side t All realtime examples require `FOUNDRY_PROJECT_ENDPOINT` and optionally use `FOUNDRY_VOICE_AGENT_NAME`. The function-tool example also optionally uses `FOUNDRY_VOICE_MODEL` and `FOUNDRY_VOICE_MODEL_TYPE`. The asynchronous text and audio examples delete their generated agents by default; set `FOUNDRY_KEEP_VOICE_AGENT=true` to retain them. +The synchronous live text sample deletes and replaces the selected agent if creation returns a conflict, +then deletes the replacement on exit, including on failure. Use a dedicated sample-agent name: this also +applies when `FOUNDRY_VOICE_AGENT_NAME` is set. This synchronous sample does not support retaining its agent. + The live audio example requires a Java Sound-compatible microphone and speaker. It streams signed, little-endian, mono PCM16 audio at 24 kHz. These examples use WebSocket transport. Although the generated protocol models include WebRTC signaling events, the Java client does not provide a WebRTC peer connection or media implementation. +### GPT Live WebSocket examples (preview) + +GPT Live is a different wire protocol from Realtime. Create a persisted agent with `VoiceAgentLiveDefinition`, +then use `BetaVoiceAgentsLiveWebSocketClient` or `BetaVoiceAgentsLiveWebSocketAsyncClient` to connect. +These clients use +`wss://{project-endpoint}/agents/{agent_name}/endpoint/protocols/voice/live/sessions?api-version=v1`, +send the `Foundry-Features: VoiceAgents=V1Preview` header, and **do not** negotiate the `realtime` WebSocket +subprotocol. `allowPreview(true)` is not required. + +Foundry sends the initial native `session.start`. Wait for `session.started` before sending application events; +do not send `session.start` yourself. Use `sendEvent(ClientEvent)` and `receiveEvents()` with the +`com.openai.models.live` event models from the SDK's existing `openai-java` dependency. These are distinct +from Realtime event models. The synchronous client also offers `receiveEvents(Duration)` for bounded waits. +The `sendEvent(BinaryData)` and `receiveRawEvents()` APIs expose complete JSON objects when the original +wire representation is needed, including unknown properties, nested `response.event` backend events, and the +Foundry `conversation_id` on `session.started`. OpenAI typed models retain extra properties and unknown event +variants, but typed serialization need not preserve the original JSON formatting. +The existing samples named `VoiceAgentLive*ConversationSample` above demonstrate live connections using the +**Realtime** protocol; use the separate GPT Live clients for `VoiceAgentLiveDefinition` agents. + +For example, configure and open a synchronous Live session for an agent using Responses delegation: + +```java readme-sample-com.azure.ai.agents.live_connection_options +BetaVoiceAgentsLiveWebSocketClient liveClient = builder.beta().buildBetaVoiceAgentsLiveWebSocketClient(); +VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions() + .setReceiveBufferCapacity(512) + .setMaxMessageSize(8 * 1024 * 1024) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR) + .setHandshakeTimeout(Duration.ofSeconds(30)) + .setCloseTimeout(Duration.ofSeconds(10)) + .setStoreEnabled(false); + +try (BetaVoiceAgentsLiveWebSocketSessionClient session = liveClient.openWebSocketSession(agentName, options)) { + for (ServerEvent event : session.receiveEvents()) { + if (event.isSessionStarted()) { + session.sendEvent(ClientEvent.ofResponseCreate(ResponseCreateEvent.builder().build())); + } else if (event.isSessionOutputTranscriptDelta()) { + System.out.print(event.asSessionOutputTranscriptDelta().delta()); + } else if (event.isSessionClosed() || event.isErrorEvent()) { + break; + } + } +} +``` + +Send only native Live commands valid for the configured delegation mode, whether typed or raw. +In particular, `response.item.create` and `response.create` are Responses-delegation-only commands. +Service `error` events arrive as events for the application to inspect. Typed receivers decode JSON and +fail on malformed events unless a malformed-event callback was explicitly configured. Raw receivers do not +parse JSON or construct typed models; transport size limits and UTF-8 validation still apply. + +Configure timeouts, bounded receive capacity, overflow handling, message size, persistence, agent version, +and structured inputs with `VoiceAgentLiveWebSocketConnectionOptions`. Structured inputs are passed as +unencoded JSON to `setStructuredInputs` and URL-encoded by the SDK into the `structured_inputs` query parameter. +Do not log endpoint URLs containing sensitive template inputs. Realtime-only transport and agent-session-ID +options are not exposed. Options are copied when opening a session. + +Both transports retain the realtime clients' credential, proxy, custom-header and builder validation behavior. +Custom HTTP clients, pipelines, policies, and retry settings are unsupported and fail at build time rather +than being ignored. Each session permits one receiver, shared by typed and raw receive APIs. +The default receive buffer holds 256 events; overflow +terminates the session unless a drop strategy explicitly permits event loss. + +#### Runnable GPT Live scenarios + +These examples create a uniquely named `VoiceAgentLiveDefinition` agent with **Responses delegation**, connect +using native GPT Live WebSockets, and delete the agent on exit, including on failure. They do not modify or delete +an existing agent. Set these environment variables before running a sample's `main` method: + +| Variable | Value | +|---|---| +| `FOUNDRY_PROJECT_ENDPOINT` | Your Foundry project endpoint. Authentication uses `DefaultAzureCredential`. | +| `FOUNDRY_GPT_LIVE_MODEL` | Optional. Your GPT Live **deployment name**, not a model catalog ID. Defaults to `gpt-live-1` when unset. | +| `FOUNDRY_GPT_LIVE_BACKEND_MODEL` | Optional. Your Responses backend **deployment name in the Live resource**. Defaults to `gpt-5.6-terra` when unset. | +| `FOUNDRY_GPT_LIVE_STORE` | Optional, text and microphone/speaker examples. Set to `true` to persist conversation content and audio. Defaults to `false`. | +| `FOUNDRY_KEEP_GPT_LIVE_AGENT` | Optional. Set to `true` to retain the sample-created agent; defaults to `false`. | + +Each sample reads, defaults, and validates these settings and configures its client builder directly in its own `main` method. +Shared helpers receive explicit values rather than reading environment variables. +Override the model variables if your deployment names differ from these defaults. Explicitly blank values are invalid. +Generated agent names use `gpt-live--` and fit the service's 63-character limit. + +| Scenario | Runnable sample | +|---|---| +| Synchronous multi-turn text | [GptLiveTextConversationSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationSample.java) | +| Asynchronous multi-turn text | [GptLiveTextConversationAsyncSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationAsyncSample.java) | +| Advanced synchronous console input and speaker | [GptLiveInteractiveTextConversationSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationSample.java) | +| Advanced asynchronous console input and speaker | [GptLiveInteractiveTextConversationAsyncSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationAsyncSample.java) | +| Asynchronous microphone and speaker | [GptLiveAudioConversationAsyncSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveAudioConversationAsyncSample.java) | +| Responses backend function tool | [GptLiveFunctionToolSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveFunctionToolSample.java) | + +#### Read persisted GPT Live conversations and audio + +These REST examples read existing persisted data; they do not start a WebSocket session, create an agent, +or delete resources. + +| Scenario | Runnable sample | +|---|---| +| Synchronous history and transcripts | [GptLiveReadConversationSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationSample.java) | +| Asynchronous history and transcripts | [GptLiveReadConversationAsyncSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAsyncSample.java) | +| Synchronous stored audio download | [GptLiveReadConversationAudioSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioSample.java) | +| Asynchronous stored audio download | [GptLiveReadConversationAudioAsyncSample.java](src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioAsyncSample.java) | + +Use an agent/session configured with `store=true` and retain the agent. With either text WebSocket example or the +microphone/speaker example, set +both `FOUNDRY_GPT_LIVE_STORE=true` and `FOUNDRY_KEEP_GPT_LIVE_AGENT=true`. The first sets the session persistence +override; the second prevents sample cleanup from deleting the agent. Keeping the agent alone does **not** enable +persistence. The text, advanced interactive, and microphone examples print the Foundry `conversation_id` from `session.started` +when provided. If absent, startup output explicitly reports that no persisted conversation ID was provided; +it never substitutes the native session ID. +Use `session.started.conversation_id`, not the native session ID. Set: + +| Variable | Value | +|---|---| +| `FOUNDRY_PROJECT_ENDPOINT` | Required. Your Foundry project endpoint; authentication uses `DefaultAzureCredential`. No default. | +| `FOUNDRY_GPT_LIVE_AGENT_NAME` | Required. The existing Live agent's name. No default. | +| `FOUNDRY_GPT_LIVE_CONVERSATION_ID` | Required. The persisted Foundry conversation ID. No default. | +| `FOUNDRY_GPT_LIVE_ITEM_ID` | Optional, audio examples only: a speech item's ID, not a delegation item. Defaults to unset (merged audio only); explicitly blank values are invalid. | + +Model deployment settings such as `FOUNDRY_GPT_LIVE_MODEL` and `FOUNDRY_GPT_LIVE_BACKEND_MODEL` are not needed: +these samples read existing conversations rather than creating agents. +Run a history sample's `main` method with no arguments. For audio, pass one existing local output directory; +there is no default output directory. +Audio examples create uniquely named WAV files without overwriting existing files. History examples explicitly +advance the `after` cursor until an empty page because the generated list clients do not expose automatic +continuation; missing or repeated cursors fail explicitly. They show conversation status and usage seconds, +input/output transcripts, and delegation targets/response IDs. Stored speech segments are not native turns or +proof that audio was played. Treat the printed transcripts and downloaded audio as sensitive data. + +Wait for session completion and recording finalization before downloading. HTTP errors propagate: `404` can mean +missing audio; `409` can mean `recording_not_ready` or `recording_unavailable`. Inspect `Retry-After` before retrying. +BYOS metadata is reported without calling Foundry content endpoints; use the metadata's blob URI and your own +Azure Storage credentials to download BYOS audio. The current generated Live REST builder methods require explicit +preview opt-in, so these samples add `Foundry-Features: VoiceAgents=V1Preview` using an HTTP pipeline header policy. + +#### Using the text WebSocket samples + +The primary synchronous and asynchronous text examples show agent and Responses-delegation configuration, +connection, typed sends, event handling, and graceful closure directly. Each command-line argument is a prompt; +with no arguments, they send `What can you help me with?` and exit after the reply. +They wait for `session.started`, send `response.item.create` followed by `response.create`, and wait for the +nested `response.completed` before advancing to the next turn. They print backend text without console input, +speaker playback, microphone capture, or silent audio uploads. + +#### Using the advanced interactive WebSocket samples + +The separate synchronous and asynchronous interactive examples read terminal input. After each reply, +they prompt for another message; submit a blank line or enter `exit` or `quit` to close the session. +Each example owns its conversation flow; shared helpers provide audio-device plumbing and transcript rendering. +Both request a spoken opening greeting with +`session.commentary.append`, play the voice frontend's 24-kHz PCM16 audio, and print its spoken transcript +rather than backend working notes. The synchronous example uses synchronous session send/receive calls, +with workers for receiving events and reading console input. +Before displaying the first `You:` prompt, each waits for both greeting audio and transcript, one second without +speech activity, and completion of queued speaker playback. Continuous silent audio does not restart the timer. +For this heuristic, PCM16 frames with peak sample magnitude at most 256 (about -42 dBFS) are treated as silence. +The quiet period is a heuristic because native GPT Live +has no speech-completed event: a long pause within a greeting can be mistaken for its end. Missing greeting output +fails with a timeout instead of silently starting input before the introduction. +It sends 20 milliseconds of silent PCM (960 bytes) every 20 milliseconds after startup, providing continuous +audio input without opening a microphone. **This consumes voice-session usage while you type or wait.** +The silent stream is stopped and pending audio sends complete before the sample requests `session.close`. +If sending falls behind, silent-frame production waits for demand instead of accumulating timer ticks or +failing with an interval overflow; it resumes without a burst of stale frames. +Speaker playback runs off the WebSocket receive thread. If a speaker is unavailable, the sample reports that +and still prints transcripts, like the Realtime text example. +Agent creation and deletion occur on the main thread. + +Console input is line-oriented: press Enter to submit a message. The sample flushes the `You:` prompt immediately; +character echo while typing is controlled by Windows CMD/PowerShell and its terminal host, not by the service. +Interactive input uses a normal blocking line read on a worker rather than polling `Reader.ready()`, +matching the Realtime sample's console interaction. The WebSocket receiver continues independently. +When a native Java console is attached, input comes from `System.console().reader()` rather than `System.in`. +Without a console, the sample reads `System.in`, supporting redirected input. End-of-input (EOF), a blank line, +or an explicit exit command closes the session. +The terminal echoes characters on the `You:` line as you type. Assistant transcript fragments are assembled into +utterances independently of typed turns and backend completion. A one-second speech-inactivity period marks an +utterance boundary using the same heuristic as the greeting; a long pause within speech can still divide the text. +Completed utterances are printed with one `Assistant:` label each. While input is active, completed text waits +until Enter so it cannot overwrite typed characters; incomplete text stays buffered across input submissions. +Audio playback and input remain available. This dependency-free approach can delay captions until the next Enter. +Session closure flushes any remaining transcript. Completed and incomplete text share a 65,536-character buffer +limit; exceeding it fails the sample explicitly instead of dropping transcript text or growing memory indefinitely. +The native console's echoed Enter already starts a new line; the sample avoids adding another blank line. +After a remote disconnect, a console read that the operating system cannot interrupt may require Enter to release +the worker. The sample does not close shared standard input to force a pending read to return. +Backend `response.completed` permits the next typed prompt but does not mean that the frontend finished speaking: +native GPT Live has no output-audio-done event. The sample keeps receiving audio and transcripts while you type. +See [GPT-Live audio and transcript events](https://learn.microsoft.com/azure/foundry/openai/gpt-live-reference#sessionoutput_audiodelta). +Server `remote_hangup` closes the conversation normally. Other unexpected closures remain failures and include +the complete `session.closed` event, including its reason, rather than hiding the service diagnostic. + +#### Using the microphone and tool samples + +The audio example requires a Java Sound-compatible microphone and speaker supporting raw, mono PCM16LE at +24 kHz. After `session.started`, it sends a greeting request followed by `response.create` so the agent can +open the conversation. It labels spoken transcript fragments as `You:` or `Assistant:` and omits backend +text deltas, which are not necessarily the words spoken by the voice frontend. +Press Enter to end the call; asking the model to end it does not itself close the session. +Service moderation (`content_filter`) ends the call with an explicit error and the original service event; +it is not treated as a successful completion. Audio devices and the WebSocket are released on failure. +The standalone audio and text samples' `main` methods also shut down shared Reactor schedulers on exit +to avoid lingering timer threads under `exec:java`. Do not invoke those `main` methods inside an application that +shares Reactor schedulers. + +The audio sample sends `session.input_audio.append`, plays base64-decoded `session.output_audio.delta` chunks, and +prints native input/output transcript deltas. It does not send Realtime audio-buffer commit or response-cancel +commands. Capture and playback use dedicated threads; the playback backlog is bounded to 60 seconds. +Device errors and overflow end the call explicitly. Press Enter to stop capture and finalize the session. +This example must be the only reader of standard input. + +The function-tool example configures `get_weather` on the **Responses backend**, consumes completed +`function_call` items from nested `response.output_item.done` events, then sends `function_call_output` items +with the original `call_id` before requesting continuation. Its weather results are **simulated demonstration +data**, not live weather. It does not assume lifecycle snapshots contain output items, and does not add +Foundry-managed-agent tool-result routing. + +All WebSocket scenarios request `session.close` and wait for `session.closed` before normal transport cleanup. +The asynchronous text examples apply a 60-second timeout to startup, each response, and finalization; +the advanced interactive example waits for terminal input without a timeout. +The synchronous text and tool examples use a 60-second event-wait timeout; +the microphone example uses a 60-second startup/finalization timeout. +An unexpected disconnect or native service error fails the sample rather than being reported as success. + ### Service API versions The client library targets the latest service API version by default. diff --git a/sdk/ai/azure-ai-agents/checkstyle-suppressions.xml b/sdk/ai/azure-ai-agents/checkstyle-suppressions.xml index d79b83856edf2..9b0654ce4e80a 100644 --- a/sdk/ai/azure-ai-agents/checkstyle-suppressions.xml +++ b/sdk/ai/azure-ai-agents/checkstyle-suppressions.xml @@ -45,6 +45,17 @@ + + + + + + + + + + + @@ -53,6 +64,8 @@ + + diff --git a/sdk/ai/azure-ai-agents/customizations/beta-annotations.csv b/sdk/ai/azure-ai-agents/customizations/beta-annotations.csv index 079fd27b8ed7f..ea6265562d557 100644 --- a/sdk/ai/azure-ai-agents/customizations/beta-annotations.csv +++ b/sdk/ai/azure-ai-agents/customizations/beta-annotations.csv @@ -10,7 +10,6 @@ class;com.azure.ai.agents.models.AgentHarness;Preview API. GitHubCopilot=V1Previ field;com.azure.ai.agents.models.AgentKind;Preview API.;VOICE field;com.azure.ai.agents.models.AgentVersionDetails;Preview API. DraftAgents=V1Preview;draft class;com.azure.ai.agents.models.AudioTranscription;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.AudioTranscriptionModel;Preview API.; field;com.azure.ai.agents.models.AzureCreateResponseDetails;Preview API. ModelRouterControls=V1Preview;model_selection_details field;com.azure.ai.agents.models.AzureCreateResponseOptions;Preview API. ModelRouterControls=V1Preview;routing_config class;com.azure.ai.agents.models.BingCustomSearchConfiguration;Preview API. preview_tool; @@ -24,10 +23,7 @@ class;com.azure.ai.agents.models.ChatSummaryMemoryItem;Preview API. MemoryStores field;com.azure.ai.agents.models.CreateAgentVersionInput;Preview API. DigitalWorker=V1Preview, DraftAgents=V1Preview, ExternalAgents=V1Preview, GitHubCopilot=V1Preview, MicrosoftCopilot=V1Preview, Skills=V1Preview, VoiceAgents=V1Preview, WorkflowAgents=V1Preview;definition field;com.azure.ai.agents.models.CreateAgentVersionInput;Preview API. DigitalWorker=V1Preview;digital_worker_type field;com.azure.ai.agents.models.CreateAgentVersionInput;Preview API. DraftAgents=V1Preview;draft -class;com.azure.ai.agents.models.CreateTeamsPhoneExtensibilityTelephonyBindingInput;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.CreateTelephonyBindingInput;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.CreateTelephonyCallJobInput;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.CreateTwilioTelephonyBindingInput;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.DatasetReference;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.ExternalAgentDefinition;Preview API. ExternalAgents=V1Preview; class;com.azure.ai.agents.models.FabricDataAgentToolCall;Preview API. preview_tool; class;com.azure.ai.agents.models.FabricDataAgentToolCallOutput;Preview API. preview_tool; @@ -38,9 +34,135 @@ class;com.azure.ai.agents.models.GenerateAgentRequest;Preview API. VoiceAgents=V class;com.azure.ai.agents.models.GenerateVoiceAgentRequest;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.GitHubCopilotHarness;Preview API. GitHubCopilot=V1Preview; class;com.azure.ai.agents.models.GitHubCopilotToolsetPreview;Preview API. GitHubCopilot=V1Preview; -class;com.azure.ai.agents.models.McpListToolsTool;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.McpListToolsToolAnnotations;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.McpListToolsToolInputSchema;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.InlineVoiceSubagent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveAllowedServerEventParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveAllowedToolsChoiceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveApplyPatchToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveAudioFormat;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveAudioFormatType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientConfigParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveCommentaryAppendParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveDecisionCreateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveDecisionItemCreateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveDecisionItemDeleteParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveInputAudioAppendEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveInputAudioMuteParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveInputAudioUnmuteParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveInstructionsAppendParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveOutputAudioFixturePlayParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveResponseCreateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveResponseItemCreateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveSessionCloseParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveSessionUpdateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventLiveThinkingAppendParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveClientEventType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveCodeInterpreterToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveComputerToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveContainerMemoryLimit;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveContainerNetworkPolicyDisabledParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveContainerReferenceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveContextWindowUsage;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveCustomToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveCustomVoiceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDataChannelConfigParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionCompleted;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionInputImageParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionInputItemParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionInputTextParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionQuestionsInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionsDelegationUpdateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionsSettingsInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionsSettingsUpdateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionStoredInputItemParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDecisionTriggerInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDelegationReasoningInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDelegationTextInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveDetailEnum;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveFileSearchToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveFunctionToolChoiceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveFunctionToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveHostedShellContainerAutoParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveHostedShellNetworkPolicyAllowlistParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveHostedShellToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveImageGenerationToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialAssistantMessageItemParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialDeveloperMessageItemParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialInputTextContentPartParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialItemType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialMessageStatus;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialOutputTextContentPartParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialSessionAudioOutputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialSessionAudioParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialTextContentPartParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInitialUserMessageItemParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInlineSkillParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInlineSkillSourceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveInputAudioAppend;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveLiveError;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveLocalEnvironmentParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveLocalSkillParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveMCPToolChoiceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveMCPToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveNamespaceToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveOutputAudioDelta;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveProgrammaticToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveReasoningEffort;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveReasoningSummary;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveResponsesDelegationSettingsInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveResponsesDelegationSettingsUpdateInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveResponsesDelegationUpdateParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveResponsesServiceTier;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveCommentaryAppended;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveDecisionEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveDecisionItemCreated;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveDecisionItemDeleted;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveDelegationCreated;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveErrorEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveInfoEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveInputAudioMuted;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveInputAudioUnmuted;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveInputTranscriptDelta;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveInstructionsAppended;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveOutputAudioFixturePlayed;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveOutputAudioFixturePlaying;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveOutputTranscriptDelta;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveResponseEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveSessionClosed;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveSessionStarted;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveSessionUpdated;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveSessionUsageUpdated;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveThinkingAppended;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveTransportAnswered;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveTransportFailed;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventLiveTransportRinging;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveServerEventType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionAudioFormatPCMAParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionAudioFormatPCMParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionAudioFormatPCMUParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionCreateParams;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionStartEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionUpdateParams;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSessionUsage;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSkillReferenceParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificApplyPatchParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificCodeInterpreterParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificComputerParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificCustomToolParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificFileSearchParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificFunctionShellParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificImageGenParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificProgrammaticToolCallingParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificWebSearchParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveSpecificWebSearchPreviewParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveTextVerbosity;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveToolChoiceEnum;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveToolChoiceValueEnum;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveToolSearchToolInputParam;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveTransportCallError;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.LiveWebSearchToolInputParam;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.MemoryCommandToolCall;Preview API. preview_tool; class;com.azure.ai.agents.models.MemoryCommandToolCallOutput;Preview API. preview_tool; class;com.azure.ai.agents.models.MemoryItem;Preview API. MemoryStores=V1Preview; @@ -68,6 +190,7 @@ class;com.azure.ai.agents.models.MicrosoftCopilotToolsetConfiguration;Preview AP class;com.azure.ai.agents.models.MicrosoftCopilotToolsetDefaultConfiguration;Preview API. MicrosoftCopilot=V1Preview; class;com.azure.ai.agents.models.MicrosoftCopilotToolsetPreview;Preview API. MicrosoftCopilot=V1Preview; class;com.azure.ai.agents.models.MicrosoftFabricPreviewTool;Preview API. preview_tool; +class;com.azure.ai.agents.models.ModelIdsLive;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.ModelRouterAttempt;Preview API. ModelRouterControls=V1Preview; class;com.azure.ai.agents.models.ModelRouterAttemptError;Preview API. ModelRouterControls=V1Preview; class;com.azure.ai.agents.models.ModelRouterAttemptResult;Preview API. ModelRouterControls=V1Preview; @@ -78,7 +201,6 @@ class;com.azure.ai.agents.models.ModelSelectionDetails;Preview API. ModelRouterC class;com.azure.ai.agents.models.ProceduralMemoryItem;Preview API. MemoryStores=V1Preview; field;com.azure.ai.agents.models.PromptAgentDefinition;Preview API. GitHubCopilot=V1Preview, MicrosoftCopilot=V1Preview;harness field;com.azure.ai.agents.models.PromptAgentDefinition;Preview API. Skills=V1Preview;skills -class;com.azure.ai.agents.models.PstnTelephonyTransferDestination;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeAudioFormat;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeAudioFormatType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeClientEvent;Preview API. VoiceAgents=V1Preview; @@ -186,7 +308,6 @@ class;com.azure.ai.agents.models.RealtimeSessionAudioOutput;Preview API. VoiceAg class;com.azure.ai.agents.models.RealtimeSessionConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeSessionConfigurationBase;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeSessionCreatedEvent;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.RealtimeSessionCreateRequestGAAudioOutputVoice;Preview API.; class;com.azure.ai.agents.models.RealtimeSessionTracingConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeSessionType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.RealtimeSessionUpdatedEvent;Preview API. VoiceAgents=V1Preview; @@ -210,18 +331,20 @@ class;com.azure.ai.agents.models.SharepointGroundingToolCall;Preview API. previe class;com.azure.ai.agents.models.SharepointGroundingToolCallOutput;Preview API. preview_tool; class;com.azure.ai.agents.models.SharepointGroundingToolParameters;Preview API. preview_tool; class;com.azure.ai.agents.models.SharepointPreviewTool;Preview API. preview_tool; -class;com.azure.ai.agents.models.SipTelephonyTransferDestination;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.SipTelephonyBinding;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.SipTelephonyBindingListItem;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.SkillReference;Preview API. Skills=V1Preview; class;com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBinding;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBindingListItem;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TeamsTelephonyTransferDestination;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyAddress;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyAddressType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyBinding;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyBindingListItem;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyBindingStatus;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallDurationBasis;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallEndReason;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallJob;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallJobCancellation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCallJobCreate;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallJobSchedule;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallJobStatus;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallJobTerminalReason;Preview API. VoiceAgents=V1Preview; @@ -239,14 +362,27 @@ class;com.azure.ai.agents.models.TelephonyCallTiming;Preview API. VoiceAgents=V1 class;com.azure.ai.agents.models.TelephonyCallTrace;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallTraceMode;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyCallTraceStatus;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyOutboundDestination;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyOutboundDestinationType;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyOutboundFixedIntervalRetryPolicy;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaign;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignAtTimeSchedule;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignImmediateSchedule;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignOperation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignOperationKind;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignPageTelephonyCampaign;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignPerRecipientSchedule;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignProgress;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignSchedule;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignScheduleType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignStatus;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignValidationError;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyCampaignValidationErrorPage;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyFixedIntervalRetryPolicy;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyOutboundRetryPolicy;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyOutboundRetryPolicyType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyPhoneNumber;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyProvider;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyTransferDestination;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.TelephonyTransferDestinationKind;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyRecipient;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonySipAddress;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.TelephonyTeamsAddress;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyTransferTarget;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.TelephonyTransferTargets;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.ToolboxSearchPreviewToolboxTool;Preview API. preview_tool; @@ -278,27 +414,86 @@ class;com.azure.ai.agents.models.VoiceAgentAvatarVideoResolution;Preview API. Vo class;com.azure.ai.agents.models.VoiceAgentAzureSemanticVadEnglishTurnDetection;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentAzureSemanticVadTurnDetection;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentBaseDefinition;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentClientEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentClientEventSessionUpdate;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentClientEventTypeExtension;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentCollectDtmfStartArguments;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentCollectDtmfSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentCollectionStartArguments;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentCollectSmsStartArguments;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentCollectSmsSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentConversationItemTypeExtension;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentDefinition;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDelegateSubagentConfiguration;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDigitRecognitionSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDtmfCompletionMode;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDtmfFixedLengthCompletionMode;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDtmfInterDigitSilenceCompletionMode;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDtmfTerminator;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentDtmfTerminatorCompletionMode;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEchoCancellation;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEchoCancellationReferenceSource;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEndConversationSystemTool;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetection;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetectionModel;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentEndOfUtteranceThresholdLevel;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentEventGridPostCallDestination;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentFunctionTool;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentGreetingConfiguration;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentGreetingMode;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffAbortReason;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffCondition;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffEdgeState;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffMaxOutputTokens;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffNodeState;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffPipelineFamily;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffPolicy;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffReasoningEffort;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffState;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffTargetResponse;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentHandoffVoiceAdaptation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentInlineSubagentConfiguration;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentInputCollectionChannel;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentInputCollectionStatus;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentInputCollectionStatusEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentInputTranscription;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentInputTranscriptionModel;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentInterimResponseConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentInterimResponseTrigger;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentInterimResponseType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLanguageDetectionArguments;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLanguageDetectionSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveClientDelegation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveClientDelegationConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveConversation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveConversationItemType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDefinition;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationResultItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationStatus;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationTarget;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveDelegationType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveFoundryManagedAgentDelegationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveInputConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveManagedAgentDelegation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveOutputConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegation;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegationConversationItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentLiveSessionResource;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentLlmGeneratedGreetingConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentLlmInterimResponseConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentMaxOutputTokens;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentMcpTool;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentNoiseReduction;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentNoiseReductionType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentPostCallConfiguration;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentPostCallDestination;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentPostCallDestinationType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentPostCallIncludeOption;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentProfanityFilterMode;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentRealtimeResponse;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentResponseAnimationBlendshapeDeltaEvent;Preview API. VoiceAgents=V1Preview; @@ -310,20 +505,27 @@ class;com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDeltaEvent;Prev class;com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDoneEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentResponseCreateOptions;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentResponseVideoDeltaEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentRoutinePostCallDestination;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentRtcCallErrorDetails;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentRtcCallErrorEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentRtcCallErrorType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreatedEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreateEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSemanticVadTurnDetection;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSendDtmfSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSendSmsSystemTool;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentServerEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentServerEventTypeExtension;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentServerVadTurnDetection;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionAvatarConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectingEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToIdleEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToSpeakingEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSessionHandoffAbortedEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSessionHandoffCompletedEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSessionHandoffStartedEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionIncludeOption;Preview API. VoiceAgents=V1Preview; -class;com.azure.ai.agents.models.VoiceAgentSessionResponse;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionResponseConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionSubagentAbortedEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSessionSubagentCompletedEvent;Preview API. VoiceAgents=V1Preview; @@ -340,17 +542,33 @@ class;com.azure.ai.agents.models.VoiceAgentSubagent;Preview API. VoiceAgents=V1P class;com.azure.ai.agents.models.VoiceAgentSubagentAbortReason;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSubagentConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSubagentResponsePolicy;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSubagentType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSubProtocol;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSystemToolArgumentsDeltaEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSystemToolArgumentsDoneEvent;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSystemToolItem;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentSystemToolItemObjectType;Preview API.; +class;com.azure.ai.agents.models.VoiceAgentSystemToolItemStatus;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentSystemToolName;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTemplateGreetingConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTool;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentToolboxTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentToolChoice;Preview API.; class;com.azure.ai.agents.models.VoiceAgentToolResponseScheduling;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentToolType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTranscriptionPhrase;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTranscriptionWord;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferDestination;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferDestinationType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferRouting;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferStrategy;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferSystemTool;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentTransferTarget;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTransport;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTurnDetectionConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentTurnDetectionType;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceAgentVoiceConfiguration;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentWarningDetails;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentWarningEvent;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceAgentWebSocketMessage;Preview API. VoiceAgents=V1Preview; @@ -360,6 +578,7 @@ class;com.azure.ai.agents.models.VoiceAudioItem;Preview API. VoiceAgents=V1Previ class;com.azure.ai.agents.models.VoiceAudioRole;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceConversation;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceConversationEngine;Preview API. VoiceAgents=V1Preview; +class;com.azure.ai.agents.models.VoiceConversationEngineType;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceConversationStatus;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceGeneratedAudioItem;Preview API. VoiceAgents=V1Preview; class;com.azure.ai.agents.models.VoiceHostedAgentConversationEngine;Preview API. VoiceAgents=V1Preview; diff --git a/sdk/ai/azure-ai-agents/customizations/src/main/java/AgentsCustomizations.java b/sdk/ai/azure-ai-agents/customizations/src/main/java/AgentsCustomizations.java index 0fcd1251ad217..50e69de2bae42 100644 --- a/sdk/ai/azure-ai-agents/customizations/src/main/java/AgentsCustomizations.java +++ b/sdk/ai/azure-ai-agents/customizations/src/main/java/AgentsCustomizations.java @@ -39,6 +39,7 @@ public void customize(LibraryCustomization libraryCustomization, Logger logger) renameImageGenToolSize(libraryCustomization, logger); modifyPollingStrategies(libraryCustomization, logger); customizeOptimizationPollingStrategies(libraryCustomization, logger); + customizeCampaignPollingStrategies(libraryCustomization, logger); stopPagingWhenHasMoreIsFalse(libraryCustomization, logger); internalizeUnusedFunctionToolType(libraryCustomization, logger); deprecateLegacyBrowserAutomationTools(libraryCustomization); @@ -171,15 +172,15 @@ private & NodeWithJavadoc> void depr private void internalizeUnusedFunctionToolType(LibraryCustomization customization, Logger logger) { ClassCustomization enumCustomization = customization.getPackage(MODELS_PACKAGE).listClasses().stream() - .filter(clazz -> "ToolFunctionToolType1".equals(clazz.getClassName())) + .filter(clazz -> "ToolFunctionToolType3".equals(clazz.getClassName())) .findFirst() .orElse(null); if (enumCustomization == null) { - logger.info("ToolFunctionToolType1 is not generated; no enum visibility change is needed."); + logger.info("ToolFunctionToolType3 is not generated; no enum visibility change is needed."); return; } - enumCustomization.customizeAst(ast -> ast.getEnumByName("ToolFunctionToolType1") - .orElseThrow(() -> new IllegalStateException("ToolFunctionToolType1 was not generated")) + enumCustomization.customizeAst(ast -> ast.getEnumByName("ToolFunctionToolType3") + .orElseThrow(() -> new IllegalStateException("ToolFunctionToolType3 was not generated")) .removeModifier(Modifier.Keyword.PUBLIC)); } @@ -194,23 +195,26 @@ private void protectPolymorphicBaseConstructors(LibraryCustomization customizati List classNames = Arrays.asList("AgentHarness", "AgentOptimizationConfigurationBase", "AgentOptimizationEvaluationSet", "AgentOptimizationTargetCompletionDataSource", "AgentOptimizationTargetConfiguration", "AgentOptimizationUserConversationSimulationDataSource", - "CreateTelephonyBindingInput", "EvaluationVoiceModelConfiguration", "OptimizationContext", + "EvaluationVoiceModelConfiguration", "OptimizationContext", "MemoryItem", "MemoryStoreDefinition", - "RealtimeAudioFormat", "RealtimeClientEvent", "RealtimeConversationItem", - "RealtimeConversationItemMessage", "RealtimeResponseInputMessage", "RealtimeMcpError", - "RealtimeSessionConfigurationBase", - "RealtimeTurnDetection", "TelephonyOutboundRetryPolicy", "TelephonyTransferDestination", - "UserConversationSimulationInterruptionConfiguration", "VoiceAgentGreetingConfiguration", - "VoiceAgentInterimResponseConfiguration", "VoiceAgentSystemTool", "VoiceAgentTool", - "VoiceAgentTurnDetectionConfiguration", "VoiceConversationEngine"); + "RealtimeClientEvent", "RealtimeConversationItem", + "RealtimeConversationItemMessage", "RealtimeResponseInputMessage", + "TelephonyAddress", "TelephonyBinding", "TelephonyCampaignSchedule", + "TelephonyOutboundRetryPolicy", + "UserConversationSimulationInterruptionConfiguration", "VoiceAgentBaseDefinition", + "VoiceAgentGreetingConfiguration", + "VoiceAgentPostCallDestination", + "VoiceAgentInterimResponseConfiguration", "VoiceAgentLiveDelegation", "VoiceAgentSystemTool", "VoiceAgentTool", + "VoiceAgentSubagentConfiguration", "VoiceAgentTurnDetectionConfiguration", "VoiceConversationEngine"); for (String className : classNames) { ClassCustomization classCustomization = customization.getClass(MODELS_PACKAGE, className); - classCustomization.customizeAst(ast -> ast.getClassByName(className).ifPresent(clazz -> clazz + classCustomization.customizeAst(ast -> ast.getClassByName(className) + .orElseThrow(() -> new IllegalStateException(className + " was not generated")) .getConstructors() .stream() .filter(constructor -> constructor.isPublic()) - .forEach(constructor -> constructor.setModifiers(Modifier.Keyword.PROTECTED)))); + .forEach(constructor -> constructor.setModifiers(Modifier.Keyword.PROTECTED))); } } @@ -224,111 +228,13 @@ private void applyUnionTypeWrappers(LibraryCustomization customization, Logger l List requireApproval = Arrays.asList( stringUnionVariant("the approval setting string to set (e.g., \"always\" or \"never\")"), modelUnionVariant("McpToolRequireApproval", "the {@link McpToolRequireApproval} filter to set")); - List toolChoice = Arrays.asList( - openAiDirectUnionVariant("com.openai.models.responses.ToolChoiceOptions", "ToolChoiceOptions", - "the openai-java {@link ToolChoiceOptions} mode to set ({@code NONE}, {@code AUTO} or" - + " {@code REQUIRED})", - "an openai-java {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another" - + " variant", - "json.startsWith(\"\\\"\")"), - openAiUnionVariant("com.openai.models.responses.ToolChoiceFunction", - "com.openai.models.responses.ResponseCreateParams", "ResponseCreateParams.ToolChoice", "isFunction", - "asFunction", "a specific function tool"), - openAiUnionVariant("com.openai.models.responses.ToolChoiceMcp", - "com.openai.models.responses.ResponseCreateParams", "ResponseCreateParams.ToolChoice", "isMcp", - "asMcp", "a specific MCP tool")); - List longMaxOutputTokens = Arrays.asList( - longUnionVariant("the maximum number of output tokens to set"), - stringUnionVariant( - "the token-limit string to set, for example {@code \"inf\"} for an unlimited count")); List allowedTools = Arrays.asList(stringListUnionVariant("the list of tool name strings to set"), modelUnionVariant("McpToolFilter", "the {@link McpToolFilter} to set")); - List tracing = Arrays.asList(stringUnionVariant("the tracing mode string to set"), - modelUnionVariant("RealtimeSessionTracingConfiguration", - "the {@link RealtimeSessionTracingConfiguration} configuration to set")); - List truncation = Arrays.asList(stringUnionVariant("the truncation mode string to set"), - openAiDirectUnionVariant("com.openai.models.realtime.RealtimeTruncationRetentionRatio", - "RealtimeTruncationRetentionRatio", - "the openai-java {@link RealtimeTruncationRetentionRatio} configuration to set", - "an openai-java {@link RealtimeTruncationRetentionRatio}, or {@code null} when it is not set or" - + " holds another variant", - "json.startsWith(\"{\")")); - List voice = Arrays.asList( - stringEnumUnionVariant("VoiceIds", "the {@link VoiceIds} built-in voice to set"), - modelUnionVariant("RealtimeSessionCreateRequestGAAudioOutputVoice", - "the {@link RealtimeSessionCreateRequestGAAudioOutputVoice} custom voice to set")); - List transcriptionUsage = Arrays.asList( - discriminatedModelUnionVariant("TranscriptTextUsageTokens", "TranscriptTextUsage", - "the {@link TranscriptTextUsageTokens} usage to set"), - discriminatedModelUnionVariant("TranscriptTextUsageDuration", "TranscriptTextUsage", - "the {@link TranscriptTextUsageDuration} usage to set")); - List voiceAgentSessionResponse = Arrays.asList( - modelUnionVariant("VoiceAgentSessionResponseConfiguration", - "the {@link VoiceAgentSessionResponseConfiguration} session to set")); - - customizeImmutableUnionProperty(customization, - "RealtimeConversationItemInputAudioTranscriptionCompletedEvent", "usage", - "Usage statistics for the transcription.", transcriptionUsage, logger); - customizeImmutableUnionProperty(customization, "RealtimeSessionCreatedEvent", "session", - "The session configuration.", voiceAgentSessionResponse, logger); - customizeImmutableUnionProperty(customization, "RealtimeSessionUpdatedEvent", "session", - "The session configuration.", voiceAgentSessionResponse, logger); - - customizeUnionProperty(customization, "RealtimeSessionConfiguration", "tracing", "Tracing configuration.", - tracing, true, false, logger); - customizeUnionProperty(customization, "RealtimeSessionConfiguration", "toolChoice", - "How the model chooses tools.", toolChoice, true, false, logger); - customizeUnionProperty(customization, "RealtimeSessionConfiguration", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response.", longMaxOutputTokens, true, false, - logger); - customizeUnionProperty(customization, "RealtimeSessionConfiguration", "truncation", - "The truncation policy for the session.", truncation, true, false, logger); - customizeUnionProperty(customization, "RealtimeSessionAudioOutput", "voice", - "The built-in or custom voice used for audio output.", voice, true, false, logger); - - customizeUnionProperty(customization, "VoiceAgentDefinition", "maxOutputTokens", - "The maximum output-token count for one response.", longMaxOutputTokens, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentDefinition", "toolChoice", - "How the model chooses tools for generated responses.", toolChoice, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentLlmGeneratedGreetingConfiguration", "toolChoice", - "The tool-selection policy for the opening response. Defaults to `none`.", toolChoice, true, false, - logger); customizeUnionProperty(customization, "VoiceAgentMcpTool", "allowedTools", "The allowed_tools property.", allowedTools, true, false, logger); customizeUnionProperty(customization, "VoiceAgentMcpTool", "requireApproval", "The require_approval property.", requireApproval, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentResponseCreateOptions", "toolChoice", - "How the model chooses tools.", toolChoice, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentResponseCreateOptions", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response.", longMaxOutputTokens, true, false, - logger); - customizeUnionProperty(customization, "VoiceAgentSessionUpdateConfiguration", "maxOutputTokens", - "The maximum output-token count for one response.", longMaxOutputTokens, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentSessionUpdateConfiguration", "toolChoice", - "Tool-selection behavior for the session.", toolChoice, true, false, logger); - customizeUnionProperty(customization, "VoiceAgentSessionResponseConfiguration", "maxOutputTokens", - "The maximum output-token count for one response.", longMaxOutputTokens, false, false, logger); - customizeUnionProperty(customization, "VoiceAgentSessionResponseConfiguration", "toolChoice", - "Tool-selection behavior for the session.", toolChoice, false, false, logger); - - // Retain base-model wrappers for older snapshots and expose them directly on the flattened response models. - customizeUnionProperty(customization, "VoiceAgentRealtimeResponseBase", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response, inclusive of tool calls, that was used" - + " in this response.", - longMaxOutputTokens, false, true, logger); - customizeUnionProperty(customization, "VoiceAgentRealtimeResponse", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response, inclusive of tool calls, that was used" - + " in this response.", - longMaxOutputTokens, false, false, logger); - customizeUnionProperty(customization, "VoiceResponseBase", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response, inclusive of tool calls, that was used" - + " in this response.", - longMaxOutputTokens, false, true, logger); - customizeUnionProperty(customization, "VoiceResponse", "maxOutputTokens", - "Maximum number of output tokens for a single assistant response, inclusive of tool calls, that was used" - + " in this response.", - longMaxOutputTokens, false, false, logger); customizeUnionProperty(customization, "WebIqPreviewTool", "requireApproval", "Whether the agent requires approval before executing actions. When omitted, the service defaults to" + " \"always\".", @@ -643,12 +549,6 @@ private static String[] stringEnumUnionVariant(String type, String paramDoc) { return variant; } - private static String[] longUnionVariant(String paramDoc) { - return unionVariant("long", "Long", "Long.class", "Long", "fromObject", paramDoc, - "a Long, or {@code null} when it is not set or holds another variant", - "!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-')", null, false); - } - private static String[] stringListUnionVariant(String paramDoc) { return unionVariant("List", "List", "new TypeReference>() { }", "StringList", "fromObject", paramDoc, "a list of Strings, or {@code null} when it is not set or holds another variant", @@ -817,6 +717,56 @@ private void customizeOptimizationPollingStrategies(LibraryCustomization customi }); } + private void customizeCampaignPollingStrategies(LibraryCustomization customization, Logger logger) { + customization.getClass("com.azure.ai.agents.implementation", "BetaVoiceAgentsTelephoniesImpl").customizeAst(ast -> { + ClassOrInterfaceDeclaration clazz = ast.getClassByName("BetaVoiceAgentsTelephoniesImpl") + .orElseThrow(() -> new IllegalStateException("BetaVoiceAgentsTelephoniesImpl was not generated.")); + customizeCampaignPollingStrategies(clazz); + logger.info("Customized twelve campaign polling strategies."); + }); + } + + private static void customizeCampaignPollingStrategies(ClassOrInterfaceDeclaration clazz) { + String[] prefixes = { "beginCreateCampaign", "beginCancelCampaign", "beginDeleteCampaign" }; + int[] counts = new int[prefixes.length]; + for (MethodDeclaration method : clazz.getMethods()) { + for (int i = 0; i < prefixes.length; i++) { + if (!method.getNameAsString().startsWith(prefixes[i])) { + continue; + } + boolean async = method.getNameAsString().endsWith("Async"); + String originalType = async ? "DefaultPollingStrategy" : "SyncDefaultPollingStrategy"; + String replacementType + = async ? "CampaignOperationLocationPollingStrategy" : "SyncCampaignOperationLocationPollingStrategy"; + List strategies = method.findAll(ObjectCreationExpr.class); + strategies.removeIf(creation -> !originalType.equals(creation.getType().getNameAsString()) + && !replacementType.equals(creation.getType().getNameAsString())); + if (strategies.size() != 1) { + throw new IllegalStateException("Expected one campaign polling strategy in " + + method.getNameAsString() + " but found " + strategies.size() + "."); + } + ObjectCreationExpr creation = strategies.get(0); + int expectedArguments = originalType.equals(creation.getType().getNameAsString()) ? 1 : 2; + if (creation.getArguments().size() != expectedArguments) { + throw new IllegalStateException("Unexpected campaign polling strategy arguments in " + + method.getNameAsString() + "."); + } + creation.setType(StaticJavaParser.parseClassOrInterfaceType( + "com.azure.ai.agents.implementation." + replacementType + "<>")); + creation.setArguments(NodeList.nodeList(creation.getArgument(0).clone(), + StaticJavaParser.parseExpression("finalRequestOptions -> this.getCampaignWithResponse" + + (async ? "Async" : "") + "(agentName, campaignName, finalRequestOptions)"))); + counts[i]++; + } + } + for (int i = 0; i < prefixes.length; i++) { + if (counts[i] != 4) { + throw new IllegalStateException("Expected four campaign polling strategies for " + prefixes[i] + + " but customized " + counts[i] + "."); + } + } + } + private void annotateBetaClients(LibraryCustomization customization, Logger logger) { customization.getPackage("com.azure.ai.agents") .listClasses() diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/AgentsClientBuilder.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/AgentsClientBuilder.java index c31bb48920f9a..233267f8c9c0a 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/AgentsClientBuilder.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/AgentsClientBuilder.java @@ -67,12 +67,14 @@ @ServiceClientBuilder( serviceClients = { BetaVoiceAgentsConversationsClient.class, + BetaVoiceAgentsLiveConversationsClient.class, BetaVoiceAgentsTelephonyClient.class, BetaMemoryStoresClient.class, BetaAgentsClient.class, AgentsClient.class, ToolboxesClient.class, BetaVoiceAgentsConversationsAsyncClient.class, + BetaVoiceAgentsLiveConversationsAsyncClient.class, BetaVoiceAgentsTelephonyAsyncClient.class, BetaMemoryStoresAsyncClient.class, BetaAgentsAsyncClient.class, @@ -601,7 +603,8 @@ private GenAiInstrumentation createInstrumentation(com.azure.core.util.tracing.T * when you want to build a client whose type is prefixed with {@code Beta}, such as {@link BetaAgentsClient}, * {@link BetaAgentsAsyncClient}, {@link BetaMemoryStoresClient}, {@link BetaMemoryStoresAsyncClient}, * {@link BetaVoiceAgentsTelephonyClient}, {@link BetaVoiceAgentsTelephonyAsyncClient}, - * {@link BetaVoiceAgentsConversationsClient}, or {@link BetaVoiceAgentsConversationsAsyncClient}. + * {@link BetaVoiceAgentsConversationsClient}, {@link BetaVoiceAgentsConversationsAsyncClient}, + * {@link BetaVoiceAgentsLiveConversationsClient}, or {@link BetaVoiceAgentsLiveConversationsAsyncClient}. *

* Clients created by this sub-builder automatically opt in to the preview service area they target by adding the * required {@code Foundry-Features} header. Calling {@link #allowPreview(boolean)} is not required for these @@ -626,14 +629,18 @@ public BetaAgentsClientBuilder beta() { serviceClients = { BetaAgentsClient.class, BetaMemoryStoresClient.class, - BetaVoiceAgentWebSocketClient.class, + BetaVoiceAgentsWebSocketClient.class, + BetaVoiceAgentsLiveWebSocketClient.class, BetaVoiceAgentsTelephonyClient.class, BetaVoiceAgentsConversationsClient.class, + BetaVoiceAgentsLiveConversationsClient.class, BetaAgentsAsyncClient.class, BetaMemoryStoresAsyncClient.class, - BetaVoiceAgentWebSocketAsyncClient.class, + BetaVoiceAgentsWebSocketAsyncClient.class, + BetaVoiceAgentsLiveWebSocketAsyncClient.class, BetaVoiceAgentsTelephonyAsyncClient.class, - BetaVoiceAgentsConversationsAsyncClient.class }) + BetaVoiceAgentsConversationsAsyncClient.class, + BetaVoiceAgentsLiveConversationsAsyncClient.class }) public final class BetaAgentsClientBuilder { /** @@ -705,6 +712,20 @@ public BetaVoiceAgentsConversationsAsyncClient buildBetaVoiceAgentsConversations buildInnerClient(VOICE_AGENTS_PREVIEW_FEATURES).getBetaVoiceAgentsConversations()); } + /** + * Builds an asynchronous beta client for persisted Live voice-agent conversations. + *

+ * Uses the enclosing builder's configuration and automatically adds the voice-agent + * {@code Foundry-Features} header. {@link AgentsClientBuilder#allowPreview(boolean)} is not required. + * + * @return an instance of BetaVoiceAgentsLiveConversationsAsyncClient. + */ + @Beta + public BetaVoiceAgentsLiveConversationsAsyncClient buildBetaVoiceAgentsLiveConversationsAsyncClient() { + return new BetaVoiceAgentsLiveConversationsAsyncClient( + buildInnerClient(VOICE_AGENTS_PREVIEW_FEATURES).getBetaVoiceAgentsLiveConversations()); + } + /** * Builds a synchronous beta Agents client for preview agent generation operations. *

@@ -747,8 +768,8 @@ public BetaMemoryStoresClient buildBetaMemoryStoresClient() { * @throws IllegalStateException if unsupported HTTP pipeline configuration is present. */ @Beta - public BetaVoiceAgentWebSocketAsyncClient buildBetaVoiceAgentWebSocketAsyncClient() { - return new BetaVoiceAgentWebSocketAsyncClient(createVoiceAgentWebSocketConfiguration()); + public BetaVoiceAgentsWebSocketAsyncClient buildBetaVoiceAgentsWebSocketAsyncClient() { + return new BetaVoiceAgentsWebSocketAsyncClient(createVoiceAgentWebSocketConfiguration()); } /** @@ -763,8 +784,36 @@ public BetaVoiceAgentWebSocketAsyncClient buildBetaVoiceAgentWebSocketAsyncClien * @throws IllegalStateException if unsupported HTTP pipeline configuration is present. */ @Beta - public BetaVoiceAgentWebSocketClient buildBetaVoiceAgentWebSocketClient() { - return new BetaVoiceAgentWebSocketClient(createVoiceAgentWebSocketConfiguration()); + public BetaVoiceAgentsWebSocketClient buildBetaVoiceAgentsWebSocketClient() { + return new BetaVoiceAgentsWebSocketClient(createVoiceAgentWebSocketConfiguration()); + } + + /** + * Builds an asynchronous WebSocket client for persisted GPT Live voice agents. + *

+ * Applies the same endpoint, credential, proxy and client options as the realtime WebSocket client. + * Custom HTTP clients, pipelines, policies and retry settings are not supported. + * + * @return an asynchronous Live WebSocket client. + * @throws IllegalStateException if unsupported HTTP pipeline configuration is present. + */ + @Beta + public BetaVoiceAgentsLiveWebSocketAsyncClient buildBetaVoiceAgentsLiveWebSocketAsyncClient() { + return new BetaVoiceAgentsLiveWebSocketAsyncClient(createVoiceAgentWebSocketConfiguration()); + } + + /** + * Builds a synchronous WebSocket client for persisted GPT Live voice agents. + *

+ * Applies the same endpoint, credential, proxy and client options as the realtime WebSocket client. + * Custom HTTP clients, pipelines, policies and retry settings are not supported. + * + * @return a synchronous Live WebSocket client. + * @throws IllegalStateException if unsupported HTTP pipeline configuration is present. + */ + @Beta + public BetaVoiceAgentsLiveWebSocketClient buildBetaVoiceAgentsLiveWebSocketClient() { + return new BetaVoiceAgentsLiveWebSocketClient(createVoiceAgentWebSocketConfiguration()); } /** @@ -798,6 +847,20 @@ public BetaVoiceAgentsConversationsClient buildBetaVoiceAgentsConversationsClien return new BetaVoiceAgentsConversationsClient( buildInnerClient(VOICE_AGENTS_PREVIEW_FEATURES).getBetaVoiceAgentsConversations()); } + + /** + * Builds a synchronous beta client for persisted Live voice-agent conversations. + *

+ * Uses the enclosing builder's configuration and automatically adds the voice-agent + * {@code Foundry-Features} header. {@link AgentsClientBuilder#allowPreview(boolean)} is not required. + * + * @return an instance of BetaVoiceAgentsLiveConversationsClient. + */ + @Beta + public BetaVoiceAgentsLiveConversationsClient buildBetaVoiceAgentsLiveConversationsClient() { + return new BetaVoiceAgentsLiveConversationsClient( + buildInnerClient(VOICE_AGENTS_PREVIEW_FEATURES).getBetaVoiceAgentsLiveConversations()); + } } /** @@ -949,8 +1012,8 @@ private VoiceAgentWebSocketClientConfiguration createVoiceAgentWebSocketConfigur * * @return an asynchronous voice-agent WebSocket client. */ - private BetaVoiceAgentWebSocketAsyncClient buildBetaVoiceAgentWebSocketAsyncClient() { - return new BetaVoiceAgentWebSocketAsyncClient(createVoiceAgentWebSocketConfiguration()); + private BetaVoiceAgentsWebSocketAsyncClient buildBetaVoiceAgentsWebSocketAsyncClient() { + return new BetaVoiceAgentsWebSocketAsyncClient(createVoiceAgentWebSocketConfiguration()); } /** @@ -958,7 +1021,26 @@ private BetaVoiceAgentWebSocketAsyncClient buildBetaVoiceAgentWebSocketAsyncClie * * @return a synchronous voice-agent WebSocket client. */ - private BetaVoiceAgentWebSocketClient buildBetaVoiceAgentWebSocketClient() { - return new BetaVoiceAgentWebSocketClient(createVoiceAgentWebSocketConfiguration()); + private BetaVoiceAgentsWebSocketClient buildBetaVoiceAgentsWebSocketClient() { + return new BetaVoiceAgentsWebSocketClient(createVoiceAgentWebSocketConfiguration()); + } + + /** + * Builds an instance of BetaVoiceAgentsLiveConversationsAsyncClient class. + * + * @return an instance of BetaVoiceAgentsLiveConversationsAsyncClient. + */ + private BetaVoiceAgentsLiveConversationsAsyncClient buildBetaVoiceAgentsLiveConversationsAsyncClient() { + return new BetaVoiceAgentsLiveConversationsAsyncClient( + buildInnerClient().getBetaVoiceAgentsLiveConversations()); + } + + /** + * Builds an instance of BetaVoiceAgentsLiveConversationsClient class. + * + * @return an instance of BetaVoiceAgentsLiveConversationsClient. + */ + private BetaVoiceAgentsLiveConversationsClient buildBetaVoiceAgentsLiveConversationsClient() { + return new BetaVoiceAgentsLiveConversationsClient(buildInnerClient().getBetaVoiceAgentsLiveConversations()); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java index bc75a56e04d7e..8db5fa3154fef 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java @@ -304,7 +304,7 @@ public Mono> deleteAgentConversationWithResponse(String agentName * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -342,7 +342,6 @@ public Mono> deleteAgentConversationWithResponse(String agentName * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -394,7 +393,7 @@ public PagedFlux listAgentConversationResponses(String agentName, St * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -432,7 +431,6 @@ public PagedFlux listAgentConversationResponses(String agentName, St * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -496,7 +494,7 @@ public Mono> getAgentConversationResponseWithResponse(Strin *

      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -550,7 +548,7 @@ public PagedFlux listAgentConversationResponseItems(String agentName *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -584,7 +582,7 @@ public PagedFlux listAgentConversationItems(String agentName, String *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -802,8 +800,8 @@ public Mono> downloadAgentConversationGeneratedAudioItemWit * sample_rate: int (Required) * channels: int (Required) * channel_layout (Required): { - * left: String (Required) - * right: String (Required) + * left: String(user/agent) (Required) + * right: String(user/agent) (Required) * } * duration_ms: long (Required) * blob_uri: String (Optional) diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java index 7de634da1209e..37d5fbc78521a 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java @@ -298,7 +298,7 @@ public Response deleteAgentConversationWithResponse(String agentName, Stri * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -336,7 +336,6 @@ public Response deleteAgentConversationWithResponse(String agentName, Stri * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -388,7 +387,7 @@ public PagedIterable listAgentConversationResponses(String agentName * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -426,7 +425,6 @@ public PagedIterable listAgentConversationResponses(String agentName * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -490,7 +488,7 @@ public Response getAgentConversationResponseWithResponse(String agen *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -544,7 +542,7 @@ public PagedIterable listAgentConversationResponseItems(String agent *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -578,7 +576,7 @@ public PagedIterable listAgentConversationItems(String agentName, St *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -795,8 +793,8 @@ public Response downloadAgentConversationGeneratedAudioItemWithRespo * sample_rate: int (Required) * channels: int (Required) * channel_layout (Required): { - * left: String (Required) - * right: String (Required) + * left: String(user/agent) (Required) + * right: String(user/agent) (Required) * } * duration_ms: long (Required) * blob_uri: String (Optional) diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsAsyncClient.java new file mode 100644 index 0000000000000..282dfbfa1aaa1 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsAsyncClient.java @@ -0,0 +1,855 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.BetaVoiceAgentsLiveConversationsImpl; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.PageOrder; +import com.azure.ai.agents.models.VoiceAgentLiveConversation; +import com.azure.ai.agents.models.VoiceAgentLiveConversationItem; +import com.azure.ai.agents.models.VoiceAudioItem; +import com.azure.ai.agents.models.VoiceRecording; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.ReturnType; +import com.azure.core.annotation.ServiceClient; +import com.azure.core.annotation.ServiceMethod; +import com.azure.core.exception.ClientAuthenticationException; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.exception.ResourceModifiedException; +import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.rest.PagedFlux; +import com.azure.core.http.rest.PagedResponse; +import com.azure.core.http.rest.PagedResponseBase; +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.util.BinaryData; +import com.azure.core.util.FluxUtil; +import java.util.stream.Collectors; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Initializes a new instance of the asynchronous AgentsClient type. + */ +@ServiceClient(builder = AgentsClientBuilder.class, isAsync = true) +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveConversationsAsyncClient { + + @Generated + private final BetaVoiceAgentsLiveConversationsImpl serviceClient; + + /** + * Initializes an instance of BetaVoiceAgentsLiveConversationsAsyncClient class. + * + * @param serviceClient the service client implementation. + */ + @Generated + BetaVoiceAgentsLiveConversationsAsyncClient(BetaVoiceAgentsLiveConversationsImpl serviceClient) { + this.serviceClient = serviceClient; + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversations(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listAgentConversationsAsync(agentName, requestOptions); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately along with {@link Response} on successful completion of + * {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationWithResponseAsync(agentName, conversationId, requestOptions); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.deleteAgentConversationWithResponseAsync(agentName, conversationId, requestOptions); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationItems(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.listAgentConversationItemsAsync(agentName, conversationId, requestOptions); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID along with {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationItemWithResponseAsync(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     item_id: String (Required)
+     *     role: String(user/agent) (Optional)
+     *     format: String(wav) (Optional)
+     *     codec: String(pcm16/pcmu/pcma) (Optional)
+     *     sample_rate: Integer (Optional)
+     *     channels: Integer (Optional)
+     *     start_offset_ms: Long (Optional)
+     *     duration_ms: Long (Optional)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata along with {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationAudioItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationAudioItemWithResponseAsync(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> downloadAgentConversationAudioItemWithResponse(String agentName, + String conversationId, String itemId, RequestOptions requestOptions) { + return this.serviceClient.downloadAgentConversationAudioItemWithResponseAsync(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     format: String(wav) (Required)
+     *     sample_rate: int (Required)
+     *     channels: int (Required)
+     *     channel_layout (Required): {
+     *         left: String(user/agent) (Required)
+     *         right: String(user/agent) (Required)
+     *     }
+     *     duration_ms: long (Required)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right) along with {@link Response} on successful + * completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationAudioWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationAudioWithResponseAsync(agentName, conversationId, requestOptions); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> downloadAgentConversationAudioWithResponse(String agentName, + String conversationId, RequestOptions requestOptions) { + return this.serviceClient.downloadAgentConversationAudioWithResponseAsync(agentName, conversationId, + requestOptions); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + * + * @param agentName The name of the Live voice agent. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversations(String agentName, Integer limit, + PageOrder order, String after, String before) { + // Generated convenience method for listAgentConversations + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + PagedFlux pagedFluxResponse + = serviceClient.listAgentConversationsAsync(after, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversation.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + * + * @param agentName The name of the Live voice agent. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversations(String agentName) { + // Generated convenience method for listAgentConversations + RequestOptions requestOptions = new RequestOptions(); + PagedFlux pagedFluxResponse + = serviceClient.listAgentConversationsAsync(null, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversation.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAgentConversation(String agentName, String conversationId) { + // Generated convenience method for getAgentConversationWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationWithResponse(agentName, conversationId, requestOptions).flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversation.class)); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that completes when a successful response is received. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteAgentConversation(String agentName, String conversationId) { + // Generated convenience method for deleteAgentConversationWithResponse + RequestOptions requestOptions = new RequestOptions(); + return deleteAgentConversationWithResponse(agentName, conversationId, requestOptions).flatMap(FluxUtil::toMono); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationItems(String agentName, String conversationId, + Integer limit, PageOrder order, String after, String before) { + // Generated convenience method for listAgentConversationItems + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + PagedFlux pagedFluxResponse + = serviceClient.listAgentConversationItemsAsync(after, agentName, conversationId, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversationItem.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationItems(String agentName, + String conversationId) { + // Generated convenience method for listAgentConversationItems + RequestOptions requestOptions = new RequestOptions(); + PagedFlux pagedFluxResponse + = serviceClient.listAgentConversationItemsAsync(null, agentName, conversationId, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversationItem.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAgentConversationItem(String agentName, String conversationId, + String itemId) { + // Generated convenience method for getAgentConversationItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationItemWithResponse(agentName, conversationId, itemId, requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAgentLiveConversationItem.class)); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAgentConversationAudioItem(String agentName, String conversationId, String itemId) { + // Generated convenience method for getAgentConversationAudioItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(VoiceAudioItem.class)); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono downloadAgentConversationAudioItem(String agentName, String conversationId, String itemId) { + // Generated convenience method for downloadAgentConversationAudioItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return downloadAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, requestOptions) + .flatMap(FluxUtil::toMono); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right) on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAgentConversationAudio(String agentName, String conversationId) { + // Generated convenience method for getAgentConversationAudioWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationAudioWithResponse(agentName, conversationId, requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(VoiceRecording.class)); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono downloadAgentConversationAudio(String agentName, String conversationId) { + // Generated convenience method for downloadAgentConversationAudioWithResponse + RequestOptions requestOptions = new RequestOptions(); + return downloadAgentConversationAudioWithResponse(agentName, conversationId, requestOptions) + .flatMap(FluxUtil::toMono); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsClient.java new file mode 100644 index 0000000000000..3b0265f24eb64 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsClient.java @@ -0,0 +1,765 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.BetaVoiceAgentsLiveConversationsImpl; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.PageOrder; +import com.azure.ai.agents.models.VoiceAgentLiveConversation; +import com.azure.ai.agents.models.VoiceAgentLiveConversationItem; +import com.azure.ai.agents.models.VoiceAudioItem; +import com.azure.ai.agents.models.VoiceRecording; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.ReturnType; +import com.azure.core.annotation.ServiceClient; +import com.azure.core.annotation.ServiceMethod; +import com.azure.core.exception.ClientAuthenticationException; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.exception.ResourceModifiedException; +import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.rest.PagedIterable; +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.util.BinaryData; + +/** + * Initializes a new instance of the synchronous AgentsClient type. + */ +@ServiceClient(builder = AgentsClientBuilder.class) +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveConversationsClient { + + @Generated + private final BetaVoiceAgentsLiveConversationsImpl serviceClient; + + /** + * Initializes an instance of BetaVoiceAgentsLiveConversationsClient class. + * + * @param serviceClient the service client implementation. + */ + @Generated + BetaVoiceAgentsLiveConversationsClient(BetaVoiceAgentsLiveConversationsImpl serviceClient) { + this.serviceClient = serviceClient; + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversations(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listAgentConversations(agentName, requestOptions); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationWithResponse(agentName, conversationId, requestOptions); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.deleteAgentConversationWithResponse(agentName, conversationId, requestOptions); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversationItems(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.listAgentConversationItems(agentName, conversationId, requestOptions); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationItemWithResponse(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     item_id: String (Required)
+     *     role: String(user/agent) (Optional)
+     *     format: String(wav) (Optional)
+     *     codec: String(pcm16/pcmu/pcma) (Optional)
+     *     sample_rate: Integer (Optional)
+     *     channels: Integer (Optional)
+     *     start_offset_ms: Long (Optional)
+     *     duration_ms: Long (Optional)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationAudioItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response downloadAgentConversationAudioItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + return this.serviceClient.downloadAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, + requestOptions); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     format: String(wav) (Required)
+     *     sample_rate: int (Required)
+     *     channels: int (Required)
+     *     channel_layout (Required): {
+     *         left: String(user/agent) (Required)
+     *         right: String(user/agent) (Required)
+     *     }
+     *     duration_ms: long (Required)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right) along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationAudioWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.getAgentConversationAudioWithResponse(agentName, conversationId, requestOptions); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response downloadAgentConversationAudioWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return this.serviceClient.downloadAgentConversationAudioWithResponse(agentName, conversationId, requestOptions); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + * + * @param agentName The name of the Live voice agent. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversations(String agentName, Integer limit, + PageOrder order, String after, String before) { + // Generated convenience method for listAgentConversations + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + return serviceClient.listAgentConversations(after, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(VoiceAgentLiveConversation.class)); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + * + * @param agentName The name of the Live voice agent. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversations(String agentName) { + // Generated convenience method for listAgentConversations + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.listAgentConversations(null, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(VoiceAgentLiveConversation.class)); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public VoiceAgentLiveConversation getAgentConversation(String agentName, String conversationId) { + // Generated convenience method for getAgentConversationWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationWithResponse(agentName, conversationId, requestOptions).getValue() + .toObject(VoiceAgentLiveConversation.class); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public void deleteAgentConversation(String agentName, String conversationId) { + // Generated convenience method for deleteAgentConversationWithResponse + RequestOptions requestOptions = new RequestOptions(); + deleteAgentConversationWithResponse(agentName, conversationId, requestOptions).getValue(); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversationItems(String agentName, + String conversationId, Integer limit, PageOrder order, String after, String before) { + // Generated convenience method for listAgentConversationItems + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + return serviceClient.listAgentConversationItems(after, agentName, conversationId, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(VoiceAgentLiveConversationItem.class)); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversationItems(String agentName, + String conversationId) { + // Generated convenience method for listAgentConversationItems + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.listAgentConversationItems(null, agentName, conversationId, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(VoiceAgentLiveConversationItem.class)); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public VoiceAgentLiveConversationItem getAgentConversationItem(String agentName, String conversationId, + String itemId) { + // Generated convenience method for getAgentConversationItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationItemWithResponse(agentName, conversationId, itemId, requestOptions).getValue() + .toObject(VoiceAgentLiveConversationItem.class); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public VoiceAudioItem getAgentConversationAudioItem(String agentName, String conversationId, String itemId) { + // Generated convenience method for getAgentConversationAudioItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, requestOptions).getValue() + .toObject(VoiceAudioItem.class); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public BinaryData downloadAgentConversationAudioItem(String agentName, String conversationId, String itemId) { + // Generated convenience method for downloadAgentConversationAudioItemWithResponse + RequestOptions requestOptions = new RequestOptions(); + return downloadAgentConversationAudioItemWithResponse(agentName, conversationId, itemId, requestOptions) + .getValue(); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public VoiceRecording getAgentConversationAudio(String agentName, String conversationId) { + // Generated convenience method for getAgentConversationAudioWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getAgentConversationAudioWithResponse(agentName, conversationId, requestOptions).getValue() + .toObject(VoiceRecording.class); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public BinaryData downloadAgentConversationAudio(String agentName, String conversationId) { + // Generated convenience method for downloadAgentConversationAudioWithResponse + RequestOptions requestOptions = new RequestOptions(); + return downloadAgentConversationAudioWithResponse(agentName, conversationId, requestOptions).getValue(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketAsyncClient.java new file mode 100644 index 0000000000000..90fca1b92c29e --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketAsyncClient.java @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionAsyncTransport; +import com.azure.ai.agents.implementation.realtime.WebSocketTransportOptions; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.annotation.ServiceClient; +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; + +import java.util.Objects; + +/** + * An asynchronous client for opening native GPT Live sessions with persisted Foundry Live voice agents. + * Create instances with {@link AgentsClientBuilder#beta()}. + */ +@ServiceClient(builder = AgentsClientBuilder.class, isAsync = true) +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveWebSocketAsyncClient { + private final VoiceAgentWebSocketClientConfiguration configuration; + + BetaVoiceAgentsLiveWebSocketAsyncClient(VoiceAgentWebSocketClientConfiguration configuration) { + this.configuration = Objects.requireNonNull(configuration, "'configuration' cannot be null."); + } + + /** + * Opens a WebSocket session using the persisted Live agent configuration. + * + * @param agentName the Live voice agent name. + * @return the connected session. Each subscription opens a new connection. + */ + public Mono openWebSocketSession(String agentName) { + return openWebSocketSession(agentName, new VoiceAgentLiveWebSocketConnectionOptions()); + } + + /** + * Opens a WebSocket session. Foundry sends the initial {@code session.start}; consume {@code session.started} + * from the event stream before sending application events. No Realtime subprotocol is negotiated. + * + * @param agentName the Live voice agent name. + * @param options the connection options, copied when this method is called. + * @return the connected session. Each subscription opens a new connection. + */ + public Mono openWebSocketSession(String agentName, + VoiceAgentLiveWebSocketConnectionOptions options) { + Objects.requireNonNull(agentName, "'agentName' cannot be null."); + VoiceAgentLiveWebSocketConnectionOptions snapshot = new VoiceAgentLiveWebSocketConnectionOptions(options); + return Mono.defer(() -> { + WebSocketSessionAsyncTransport transport = new WebSocketSessionAsyncTransport(configuration, + VoiceAgentWebSocketUtils.buildLiveWebSocketUri(configuration, agentName, snapshot), + new WebSocketTransportOptions(snapshot), HttpClient.create(), null, + token -> VoiceAgentWebSocketUtils.buildHeaders(configuration, token)); + return transport.connect() + .thenReturn( + new BetaVoiceAgentsLiveWebSocketSessionAsyncClient(transport, snapshot.getMalformedEventHandler())); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketClient.java new file mode 100644 index 0000000000000..9044c117f70a1 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketClient.java @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionTransport; +import com.azure.ai.agents.implementation.realtime.WebSocketTransportOptions; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.annotation.ServiceClient; +import com.azure.core.util.logging.ClientLogger; + +import java.util.Objects; + +/** + * A synchronous client for opening native GPT Live sessions with persisted Foundry Live voice agents. + * Create instances with {@link AgentsClientBuilder#beta()}. + */ +@ServiceClient(builder = AgentsClientBuilder.class) +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveWebSocketClient { + private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentsLiveWebSocketClient.class); + private final VoiceAgentWebSocketClientConfiguration configuration; + + BetaVoiceAgentsLiveWebSocketClient(VoiceAgentWebSocketClientConfiguration configuration) { + this.configuration = Objects.requireNonNull(configuration, "'configuration' cannot be null."); + } + + /** + * Opens a WebSocket session using the persisted Live agent configuration. + * + * @param agentName the Live voice agent name. + * @return the connected session. + */ + public BetaVoiceAgentsLiveWebSocketSessionClient openWebSocketSession(String agentName) { + return openWebSocketSession(agentName, new VoiceAgentLiveWebSocketConnectionOptions()); + } + + /** + * Opens a WebSocket session. Foundry sends the initial {@code session.start}; consume {@code session.started} + * from the event stream before sending application events. No Realtime subprotocol is negotiated. + * + * @param agentName the Live voice agent name. + * @param options the connection options, copied before connecting. + * @return the connected session. + * @throws IllegalArgumentException if the agent name is empty. + */ + public BetaVoiceAgentsLiveWebSocketSessionClient openWebSocketSession(String agentName, + VoiceAgentLiveWebSocketConnectionOptions options) { + Objects.requireNonNull(agentName, "'agentName' cannot be null."); + if (agentName.isEmpty()) { + throw LOGGER.logExceptionAsError(new IllegalArgumentException("'agentName' cannot be empty.")); + } + VoiceAgentLiveWebSocketConnectionOptions snapshot = new VoiceAgentLiveWebSocketConnectionOptions(options); + return new BetaVoiceAgentsLiveWebSocketSessionClient( + WebSocketSessionTransport.connect(configuration, + VoiceAgentWebSocketUtils.buildLiveWebSocketUri(configuration, agentName, snapshot), + new WebSocketTransportOptions(snapshot), null, + token -> VoiceAgentWebSocketUtils.buildHeaders(configuration, token)), + snapshot.getMalformedEventHandler()); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionAsyncClient.java new file mode 100644 index 0000000000000..352e9034d3723 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionAsyncClient.java @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionAsyncTransport; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.util.AsyncCloseable; +import com.azure.core.util.BinaryData; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ServerEvent; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.Objects; +import java.util.function.Consumer; + +/** + * An asynchronous bidirectional native GPT Live session. + *

+ * Live events can be sent and received using {@link ClientEvent} and {@link ServerEvent}, or as complete JSON objects. + * Raw JSON preserves unknown fields, nested {@code response.event} payloads and Foundry {@code conversation_id} values. + * Typed and raw receivers share one event subscriber. Close sessions when they are no longer needed. + */ +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveWebSocketSessionAsyncClient implements AsyncCloseable, AutoCloseable { + private final WebSocketSessionAsyncTransport transport; + private final Consumer malformedEventHandler; + + BetaVoiceAgentsLiveWebSocketSessionAsyncClient(WebSocketSessionAsyncTransport transport, + Consumer malformedEventHandler) { + this.transport = transport; + this.malformedEventHandler = malformedEventHandler; + } + + /** + * Gets the WebSocket endpoint. It may contain structured inputs; do not log sensitive query values. + * + * @return the endpoint. + */ + public String getEndpoint() { + return transport.getEndpoint(); + } + + /** + * Determines whether the transport is open, not whether {@code session.started} has been received. + * + * @return whether the WebSocket is open. + */ + public boolean isOpen() { + return transport.isOpen(); + } + + /** + * Gets the peer close code. + * + * @return the code, or null if no close frame has been received. + */ + public Integer getCloseCode() { + return transport.getCloseCode(); + } + + /** + * Gets the peer close reason. + * + * @return the reason, or null if no close frame has been received. + */ + public String getCloseReason() { + return transport.getCloseReason(); + } + + /** + * Receives native Live server events in wire order, including unknown events. + * Messages are not parsed or validated as JSON. Transport errors terminate the stream. + * + * @return the single-subscriber stream of raw messages. + */ + public Flux receiveRawEvents() { + return transport.receiveEvents(); + } + + /** + * Receives typed native Live server events. Typed and raw receivers share the single-subscriber limit. + * Use {@link #receiveRawEvents()} when the original JSON representation is needed. + * + * @return the typed server event stream. + */ + public Flux receiveEvents() { + return VoiceAgentWebSocketUtils.decodeEvents(transport.receiveEvents(), + json -> OpenAIJsonHelper.fromBinaryData(VoiceAgentWebSocketUtils.deserializeRawEvent(json), + ServerEvent.class), + malformedEventHandler, () -> transport.closeAsync(1007, "Invalid JSON event").subscribe()); + } + + /** + * Sends a typed native Live command. Foundry supplies {@code session.start}; clients must not send it. + * + * @param event the command to send. + * @return completion after the frame is written. + */ + public Mono sendEvent(ClientEvent event) { + Objects.requireNonNull(event, "'event' cannot be null."); + return Mono.defer(() -> sendEvent(OpenAIJsonHelper.toBinaryData(event))); + } + + /** + * Sends a native Live JSON event. Foundry supplies {@code session.start}; clients must not send it. + * The service validates native command semantics, including delegation restrictions. + * + * @param event the complete JSON object. + * @return completion after the frame is written, or an error for invalid JSON or a closed session. + */ + public Mono sendEvent(BinaryData event) { + return transport.sendEvent(event); + } + + /** + * Closes the WebSocket normally. + * + * @return completion when the session is closed. + */ + @Override + public Mono closeAsync() { + return transport.closeAsync(); + } + + /** + * Closes the WebSocket with the specified close frame. The first asynchronous close request wins. + * + * @param code a valid WebSocket close code. + * @param reason a non-null reason of at most 123 UTF-8 bytes. + * @return completion when the session is closed. + * @throws IllegalArgumentException if the code or reason is invalid. + */ + public Mono closeAsync(int code, String reason) { + return transport.closeAsync(code, reason); + } + + /** + * Closes the session, blocking until closure or the configured close timeout. + */ + @Override + public void close() { + transport.close(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionClient.java new file mode 100644 index 0000000000000..0607e5e888035 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveWebSocketSessionClient.java @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionTransport; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.util.BinaryData; +import com.azure.core.util.IterableStream; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ServerEvent; + +import java.time.Duration; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A synchronous bidirectional native GPT Live session. + *

+ * Events can be sent and received using {@link ClientEvent} and {@link ServerEvent}, or as complete JSON objects. + * Raw JSON preserves unknown fields, nested {@code response.event} payloads and Foundry {@code conversation_id} values. + * Typed and raw receivers share one event iterator. Close sessions when they are no longer needed. + */ +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsLiveWebSocketSessionClient implements AutoCloseable { + private final WebSocketSessionTransport transport; + private final Consumer malformedEventHandler; + + BetaVoiceAgentsLiveWebSocketSessionClient(WebSocketSessionTransport transport, + Consumer malformedEventHandler) { + this.transport = transport; + this.malformedEventHandler = malformedEventHandler; + } + + /** + * Gets the WebSocket endpoint. It may contain structured inputs; do not log sensitive query values. + * + * @return the endpoint. + */ + public String getEndpoint() { + return transport.getEndpoint(); + } + + /** + * Determines whether the transport is open, not whether {@code session.started} has been received. + * + * @return whether the WebSocket is open. + */ + public boolean isOpen() { + return transport.isOpen(); + } + + /** + * Gets the peer close code. + * + * @return the code, or null if no close frame has been received. + */ + public Integer getCloseCode() { + return transport.getCloseCode(); + } + + /** + * Gets the peer close reason. + * + * @return the reason, or null if no close frame has been received. + */ + public String getCloseReason() { + return transport.getCloseReason(); + } + + /** + * Receives native Live server events in wire order, including unknown events. + * Messages are not parsed or validated as JSON. Transport errors terminate iteration. + * + * @return the single-consumer stream of raw messages. + * @throws IllegalStateException if the receive stream was already claimed. + */ + public IterableStream receiveRawEvents() { + return receiveRawEvents(null); + } + + /** + * Receives typed native Live server events. Typed and raw receivers share the single-consumer limit. + * + * @return the typed server event stream. + */ + public IterableStream receiveEvents() { + return receiveEvents(null); + } + + /** + * Receives typed native Live events with a timeout per wait. Timeouts leave the session open. + * Use {@link #receiveRawEvents(Duration)} when the original JSON representation is needed. + * + * @param timeout a positive timeout, or null to wait indefinitely. + * @return the single-consumer typed event stream. + * @throws IllegalArgumentException if the timeout is zero or negative. + * @throws IllegalStateException if the receive stream was already claimed, or a wait times out. + */ + public IterableStream receiveEvents(Duration timeout) { + return VoiceAgentWebSocketUtils.decodeEvents( + transport.receiveEvents(timeout), json -> OpenAIJsonHelper + .fromBinaryData(VoiceAgentWebSocketUtils.deserializeRawEvent(json), ServerEvent.class), + malformedEventHandler, () -> transport.close(1007, "Invalid JSON event")); + } + + /** + * Sends a typed native Live command. Foundry supplies {@code session.start}; clients must not send it. + * This method enqueues the event; returning does not mean the frame has been written to the network. + * Later network failures surface through the receive stream and session lifecycle. + * + * @param event the command to send. + * @throws IllegalStateException if the session cannot accept the event. + */ + public void sendEvent(ClientEvent event) { + Objects.requireNonNull(event, "'event' cannot be null."); + sendEvent(OpenAIJsonHelper.toBinaryData(event)); + } + + /** + * Receives raw Live messages without JSON decoding, with a timeout per wait. + * Timeouts leave the session open so iteration can resume. + * + * @param timeout a positive timeout, or null to wait indefinitely. + * @return the single-consumer event stream. + * @throws IllegalArgumentException if the timeout is zero or negative. + * @throws IllegalStateException if the receive stream was already claimed, or a wait times out. + */ + public IterableStream receiveRawEvents(Duration timeout) { + return transport.receiveEvents(timeout); + } + + /** + * Sends a native Live JSON event. Foundry supplies {@code session.start}; clients must not send it. + * The service validates native command semantics, including delegation restrictions. + * This method enqueues the event; returning does not mean the frame has been written to the network. + * Later network failures surface through the receive stream and session lifecycle. + * + * @param event the complete JSON object. + * @throws IllegalArgumentException if the event is not a JSON object. + * @throws IllegalStateException if the session cannot accept the event. + */ + public void sendEvent(BinaryData event) { + transport.sendEvent(event); + } + + /** + * Closes the WebSocket normally. + */ + @Override + public void close() { + transport.close(); + } + + /** + * Closes the WebSocket with the specified close frame. + * + * @param code a valid WebSocket close code. + * @param reason a non-null reason of at most 123 UTF-8 bytes. + * @throws IllegalArgumentException if the code or reason is invalid. + */ + public void close(int code, String reason) { + transport.close(code, reason); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java index d37a1bd7de6aa..12ab77c6df613 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java @@ -8,16 +8,19 @@ import com.azure.ai.agents.implementation.models.ReplaceTelephonyTransferTargetsRequest; import com.azure.ai.agents.implementation.models.TransferTelephonyCallRequest; import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.ai.agents.models.CreateTelephonyBindingInput; -import com.azure.ai.agents.models.CreateTelephonyCallJobInput; import com.azure.ai.agents.models.PageOrder; import com.azure.ai.agents.models.TelephonyBinding; import com.azure.ai.agents.models.TelephonyBindingListItem; -import com.azure.ai.agents.models.TelephonyBindingStatus; import com.azure.ai.agents.models.TelephonyCallJob; +import com.azure.ai.agents.models.TelephonyCallJobCreate; +import com.azure.ai.agents.models.TelephonyCallJobStatus; import com.azure.ai.agents.models.TelephonyCallRecord; import com.azure.ai.agents.models.TelephonyCallStatus; import com.azure.ai.agents.models.TelephonyCallSummary; +import com.azure.ai.agents.models.TelephonyCampaign; +import com.azure.ai.agents.models.TelephonyCampaignOperation; +import com.azure.ai.agents.models.TelephonyCampaignStatus; +import com.azure.ai.agents.models.TelephonyCampaignValidationError; import com.azure.ai.agents.models.TelephonyProvider; import com.azure.ai.agents.models.TelephonyTransferTarget; import com.azure.ai.agents.models.TelephonyTransferTargets; @@ -30,6 +33,7 @@ import com.azure.core.exception.HttpResponseException; import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.HttpHeaderName; import com.azure.core.http.rest.PagedFlux; import com.azure.core.http.rest.PagedResponse; import com.azure.core.http.rest.PagedResponseBase; @@ -37,6 +41,7 @@ import com.azure.core.http.rest.Response; import com.azure.core.util.BinaryData; import com.azure.core.util.FluxUtil; +import com.azure.core.util.polling.PollerFlux; import java.time.OffsetDateTime; import java.util.List; import java.util.stream.Collectors; @@ -81,9 +86,11 @@ public final class BetaVoiceAgentsTelephonyAsyncClient { *

      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
+     *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
+     *     incoming_call_url: String (Required)
      * }
      * }
      * 
@@ -93,11 +100,10 @@ public final class BetaVoiceAgentsTelephonyAsyncClient { *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -112,7 +118,7 @@ public final class BetaVoiceAgentsTelephonyAsyncClient {
      * 
      *
      * @param agentName The name of the voice agent that owns the binding.
-     * @param telephonyBinding The provider-specific binding to create.
+     * @param binding The provider-specific binding to create.
      * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
      * @throws HttpResponseException thrown if the request is rejected by server.
      * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
@@ -123,9 +129,9 @@ public final class BetaVoiceAgentsTelephonyAsyncClient {
      */
     @Generated
     @ServiceMethod(returns = ReturnType.SINGLE)
-    public Mono> createTelephonyBindingWithResponse(String agentName, BinaryData telephonyBinding,
+    public Mono> createTelephonyBindingWithResponse(String agentName, BinaryData binding,
         RequestOptions requestOptions) {
-        return this.serviceClient.createTelephonyBindingWithResponseAsync(agentName, telephonyBinding, requestOptions);
+        return this.serviceClient.createTelephonyBindingWithResponseAsync(agentName, binding, requestOptions);
     }
 
     /**
@@ -137,9 +143,7 @@ public Mono> createTelephonyBindingWithResponse(String agen
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -161,11 +165,10 @@ public Mono> createTelephonyBindingWithResponse(String agen
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -195,11 +198,10 @@ public PagedFlux listTelephonyBindings(String agentName, RequestOpti
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -241,10 +243,12 @@ public Mono> getTelephonyBindingWithResponse(String agentNa
      * 
      * {@code
      * {
-     *     status: String(active/suspended) (Optional)
      *     label: String (Optional)
      *     connection_name: String (Optional)
      *     phone_number: String (Optional)
+     *     allowed_calling_numbers (Optional): [
+     *         String (Optional)
+     *     ]
      * }
      * }
      * 
@@ -254,11 +258,10 @@ public Mono> getTelephonyBindingWithResponse(String agentNa *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -326,7 +329,7 @@ public Mono> deleteTelephonyBindingWithResponse(String agentName,
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -355,7 +358,7 @@ public Mono> deleteTelephonyBindingWithResponse(String agentName,
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -399,7 +402,7 @@ public PagedFlux listTelephonyCalls(String agentName, RequestOptions
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -496,7 +499,7 @@ public Mono> getTelephonyCallWithResponse(String agentName,
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -583,7 +586,7 @@ public Mono> transferTelephonyCallWithResponse(String agent
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -672,7 +675,8 @@ public Mono> endTelephonyCallWithResponse(String agentName,
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -720,7 +724,8 @@ public Mono> getTelephonyTransferTargetsWithResponse(String
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -738,7 +743,8 @@ public Mono> getTelephonyTransferTargetsWithResponse(String
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -777,18 +783,18 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St
     /**
      * Create an outbound telephony call job
      *
-     * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes.
+     * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and
+     * its voice session.
      * 

Request Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -801,6 +807,7 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St
      *         type: String(fixed_interval) (Required)
      *         max_attempts: Integer (Optional)
      *     }
+     *     source (Required): (recursive schema, see source above)
      * }
      * }
      * 
@@ -811,11 +818,10 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -825,7 +831,6 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -844,6 +849,8 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -852,15 +859,18 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -872,8 +882,8 @@ public Mono> replaceTelephonyTransferTargetsWithResponse(St @Generated @ServiceMethod(returns = ReturnType.SINGLE) public Mono> createTelephonyCallJobWithResponse(String agentName, String idempotencyKey, - BinaryData body, RequestOptions requestOptions) { - return this.serviceClient.createTelephonyCallJobWithResponseAsync(agentName, idempotencyKey, body, + BinaryData job, RequestOptions requestOptions) { + return this.serviceClient.createTelephonyCallJobWithResponseAsync(agentName, idempotencyKey, job, requestOptions); } @@ -887,11 +897,10 @@ public Mono> createTelephonyCallJobWithResponse(String agen * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -901,7 +910,6 @@ public Mono> createTelephonyCallJobWithResponse(String agen * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -920,6 +928,8 @@ public Mono> createTelephonyCallJobWithResponse(String agen * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -928,11 +938,12 @@ public Mono> createTelephonyCallJobWithResponse(String agen * * * - * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -953,18 +964,18 @@ public Mono> getTelephonyCallJobWithResponse(String agentNa /** * Cancel an outbound telephony call job * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. *

Response Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -974,7 +985,6 @@ public Mono> getTelephonyCallJobWithResponse(String agentNa
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -993,6 +1003,8 @@ public Mono> getTelephonyCallJobWithResponse(String agentNa
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
@@ -1001,13 +1013,16 @@ public Mono> getTelephonyCallJobWithResponse(String agentNa * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that * read. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. @@ -1310,8 +1325,8 @@ public Mono replaceTelephonyTransferTargets(String age * * Retrieves a durable direct or campaign-created outbound call job. * - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1334,10 +1349,11 @@ public Mono getTelephonyCallJob(String agentName, String callJ /** * Cancel an outbound telephony call job * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. * - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that * read. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -1358,32 +1374,6 @@ public Mono cancelTelephonyCallJob(String agentName, String ca .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallJob.class)); } - /** - * Create an agent telephony binding - * - * Creates a telephony binding for the voice agent named in the path. - * - * @param agentName The name of the voice agent that owns the binding. - * @param telephonyBinding The provider-specific binding to create. - * @throws IllegalArgumentException thrown if parameters fail the validation. - * @throws HttpResponseException thrown if the request is rejected by server. - * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. - * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. - * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. - * @return a telephony binding owned by a voice agent on successful completion of {@link Mono}. - */ - @Generated - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createTelephonyBinding(String agentName, - CreateTelephonyBindingInput telephonyBinding) { - // Generated convenience method for createTelephonyBindingWithResponse - RequestOptions requestOptions = new RequestOptions(); - return createTelephonyBindingWithResponse(agentName, BinaryData.fromObject(telephonyBinding), requestOptions) - .flatMap(FluxUtil::toMono) - .map(protocolMethodData -> protocolMethodData.toObject(TelephonyBinding.class)); - } - /** * Update an agent telephony binding * @@ -1419,41 +1409,15 @@ public Mono updateTelephonyBinding(String agentName, String bi } /** - * Create an outbound telephony call job - * - * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes. - * - * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. - * @throws IllegalArgumentException thrown if parameters fail the validation. - * @throws HttpResponseException thrown if the request is rejected by server. - * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. - * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. - * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. - * @return a durable direct or campaign-created outbound call intent on successful completion of {@link Mono}. - */ - @Generated - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createTelephonyCallJob(String agentName, String idempotencyKey, - CreateTelephonyCallJobInput body) { - // Generated convenience method for createTelephonyCallJobWithResponse - RequestOptions requestOptions = new RequestOptions(); - return createTelephonyCallJobWithResponse(agentName, idempotencyKey, BinaryData.fromObject(body), - requestOptions).flatMap(FluxUtil::toMono) - .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallJob.class)); - } - - /** - * List agent telephony bindings + * List agent telephony calls * - * Returns the telephony bindings owned by the voice agent named in the path. + * Returns the durable inbound call history for the voice agent named in the path. * - * @param agentName The name of the voice agent whose bindings are listed. - * @param provider Filters bindings by provider. - * @param status Filters bindings by lifecycle status. + * @param agentName The name of the voice agent whose calls are listed. + * @param provider Filters calls by provider. + * @param status Filters calls by lifecycle status. + * @param startedAfter Includes calls that started at or after this Unix timestamp in seconds. + * @param startedBefore Includes calls that started at or before this Unix timestamp in seconds. * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the * default is 20. * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` @@ -1474,9 +1438,10 @@ public Mono createTelephonyCallJob(String agentName, String id */ @Generated @ServiceMethod(returns = ReturnType.COLLECTION) - public PagedFlux listTelephonyBindings(String agentName, TelephonyProvider provider, - TelephonyBindingStatus status, Integer limit, PageOrder order, String after, String before) { - // Generated convenience method for listTelephonyBindings + public PagedFlux listTelephonyCalls(String agentName, TelephonyProvider provider, + TelephonyCallStatus status, OffsetDateTime startedAfter, OffsetDateTime startedBefore, Integer limit, + PageOrder order, String after, String before) { + // Generated convenience method for listTelephonyCalls RequestOptions requestOptions = new RequestOptions(); if (provider != null) { requestOptions.addQueryParam("provider", provider.toString(), false); @@ -1484,6 +1449,12 @@ public PagedFlux listTelephonyBindings(String agentNam if (status != null) { requestOptions.addQueryParam("status", status.toString(), false); } + if (startedAfter != null) { + requestOptions.addQueryParam("started_after", String.valueOf(startedAfter.toEpochSecond()), false); + } + if (startedBefore != null) { + requestOptions.addQueryParam("started_before", String.valueOf(startedBefore.toEpochSecond()), false); + } if (limit != null) { requestOptions.addQueryParam("limit", String.valueOf(limit), false); } @@ -1494,7 +1465,7 @@ public PagedFlux listTelephonyBindings(String agentNam requestOptions.addQueryParam("before", before, false); } PagedFlux pagedFluxResponse - = serviceClient.listTelephonyBindingsAsync(after, agentName, requestOptions); + = serviceClient.listTelephonyCallsAsync(after, agentName, requestOptions); return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { Flux> flux; if (pageSizeParam == null) { @@ -1507,26 +1478,157 @@ public PagedFlux listTelephonyBindings(String agentNam : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); } return flux - .map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + .map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), pagedResponse.getValue() .stream() - .map(protocolMethodData -> protocolMethodData.toObject(TelephonyBindingListItem.class)) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallSummary.class)) .collect(Collectors.toList()), pagedResponse.getContinuationToken(), null)); }); } /** - * List agent telephony calls + * List outbound telephony call jobs * - * Returns the durable inbound call history for the voice agent named in the path. + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + *

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
* - * @param agentName The name of the voice agent whose calls are listed. - * @param provider Filters calls by provider. - * @param status Filters calls by lifecycle status. - * @param startedAfter Includes calls that started at or after this Unix timestamp in seconds. - * @param startedBefore Includes calls that started at or before this Unix timestamp in seconds. + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listTelephonyCallJobs(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listTelephonyCallJobsAsync(agentName, requestOptions); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteTelephonyCallJobWithResponse(String agentName, String callJobId, + RequestOptions requestOptions) { + return this.serviceClient.deleteTelephonyCallJobWithResponseAsync(agentName, callJobId, requestOptions); + } + + /** + * Create an agent telephony binding + * + * Creates a telephony binding for the voice agent named in the path. + * + * @param agentName The name of the voice agent that owns the binding. + * @param binding The provider-specific binding to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony binding owned by a voice agent on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createTelephonyBinding(String agentName, TelephonyBinding binding) { + // Generated convenience method for createTelephonyBindingWithResponse + RequestOptions requestOptions = new RequestOptions(); + return createTelephonyBindingWithResponse(agentName, BinaryData.fromObject(binding), requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyBinding.class)); + } + + /** + * List agent telephony bindings + * + * Returns the telephony bindings owned by the voice agent named in the path. + * + * @param agentName The name of the voice agent whose bindings are listed. + * @param provider Filters bindings by provider. * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the * default is 20. * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` @@ -1547,23 +1649,13 @@ public PagedFlux listTelephonyBindings(String agentNam */ @Generated @ServiceMethod(returns = ReturnType.COLLECTION) - public PagedFlux listTelephonyCalls(String agentName, TelephonyProvider provider, - TelephonyCallStatus status, OffsetDateTime startedAfter, OffsetDateTime startedBefore, Integer limit, - PageOrder order, String after, String before) { - // Generated convenience method for listTelephonyCalls + public PagedFlux listTelephonyBindings(String agentName, TelephonyProvider provider, + Integer limit, PageOrder order, String after, String before) { + // Generated convenience method for listTelephonyBindings RequestOptions requestOptions = new RequestOptions(); if (provider != null) { requestOptions.addQueryParam("provider", provider.toString(), false); } - if (status != null) { - requestOptions.addQueryParam("status", status.toString(), false); - } - if (startedAfter != null) { - requestOptions.addQueryParam("started_after", String.valueOf(startedAfter.toEpochSecond()), false); - } - if (startedBefore != null) { - requestOptions.addQueryParam("started_before", String.valueOf(startedBefore.toEpochSecond()), false); - } if (limit != null) { requestOptions.addQueryParam("limit", String.valueOf(limit), false); } @@ -1574,7 +1666,7 @@ public PagedFlux listTelephonyCalls(String agentName, Tele requestOptions.addQueryParam("before", before, false); } PagedFlux pagedFluxResponse - = serviceClient.listTelephonyCallsAsync(after, agentName, requestOptions); + = serviceClient.listTelephonyBindingsAsync(after, agentName, requestOptions); return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { Flux> flux; if (pageSizeParam == null) { @@ -1587,13 +1679,1319 @@ public PagedFlux listTelephonyCalls(String agentName, Tele : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); } return flux - .map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + .map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), pagedResponse.getValue() .stream() - .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallSummary.class)) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyBindingListItem.class)) .collect(Collectors.toList()), pagedResponse.getContinuationToken(), null)); }); } + + /** + * Create an outbound telephony call job + * + * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and + * its voice session. + * + * @param agentName The name of the voice agent that executes the call. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a durable direct or campaign-created outbound call intent on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createTelephonyCallJob(String agentName, String idempotencyKey, + TelephonyCallJobCreate job) { + // Generated convenience method for createTelephonyCallJobWithResponse + RequestOptions requestOptions = new RequestOptions(); + return createTelephonyCallJobWithResponse(agentName, idempotencyKey, BinaryData.fromObject(job), requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallJob.class)); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. + * @param status Optional lifecycle filter. + * @param campaignName Current Campaign round: 404 if absent, empty while deleting. Omit for direct and Campaign + * jobs. Replacement/name reuse invalidates cursors. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listTelephonyCallJobs(String agentName, Integer limit, PageOrder order, + String after, String before, TelephonyCallJobStatus status, String campaignName) { + // Generated convenience method for listTelephonyCallJobs + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + if (status != null) { + requestOptions.addQueryParam("status", status.toString(), false); + } + if (campaignName != null) { + requestOptions.addQueryParam("campaign_name", campaignName, false); + } + PagedFlux pagedFluxResponse + = serviceClient.listTelephonyCallJobsAsync(after, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallJob.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listTelephonyCallJobs(String agentName) { + // Generated convenience method for listTelephonyCallJobs + RequestOptions requestOptions = new RequestOptions(); + PagedFlux pagedFluxResponse + = serviceClient.listTelephonyCallJobsAsync(null, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCallJob.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that completes when a successful response is received. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteTelephonyCallJob(String agentName, String callJobId) { + // Generated convenience method for deleteTelephonyCallJobWithResponse + RequestOptions requestOptions = new RequestOptions(); + return deleteTelephonyCallJobWithResponse(agentName, callJobId, requestOptions).flatMap(FluxUtil::toMono); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCreateCampaign(String agentName, String campaignName, + BinaryData campaign, RequestOptions requestOptions) { + return this.serviceClient.beginCreateCampaignAsync(agentName, campaignName, campaign, requestOptions); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
operation_idStringNoOriginal response's Operation-Id guards its instance/round + * and survives same-round actions. Replacement/name reuse: 409 campaign_operation_mismatch; + * missing/expired/wrong-scope operation: 404.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients along with {@link Response} on + * successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getCampaignWithResponse(String agentName, String campaignName, + RequestOptions requestOptions) { + return this.serviceClient.getCampaignWithResponseAsync(agentName, campaignName, requestOptions); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaigns(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listCampaignsAsync(agentName, requestOptions); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCancelCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return this.serviceClient.beginCancelCampaignAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginDeleteCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return this.serviceClient.beginDeleteCampaignAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignValidationErrors(String agentName, String campaignName, + RequestOptions requestOptions) { + return this.serviceClient.listCampaignValidationErrorsAsync(agentName, campaignName, requestOptions); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + *
Response Headers
NameTypeDescription
Retry-AfterintRecommended number of seconds to wait before polling again.
+ * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a campaign operation + * + * Gets the initiating operation's status along with {@link Response} on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getCampaignOperationWithResponse(String agentName, String campaignName, + String operationId, RequestOptions requestOptions) { + return this.serviceClient.getCampaignOperationWithResponseAsync(agentName, campaignName, operationId, + requestOptions); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param operationId Retry key: matching submitted inputs and original If-Match replay the saved monitor before + * current-state checks. Conflicting reuse returns 409 operation_id_conflict; retained creation keys after deletion + * return 409 campaign_deleted. + * @param ifMatch Required with a fresh Operation-Id for failed-state replacement; no wildcards. Changed input + * without it returns 409. Missing replacement ID: 400; stale token/absent resource: 412; other states: 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCreateCampaign(String agentName, + String campaignName, TelephonyCampaign campaign, String operationId, String ifMatch) { + // Generated convenience method for beginCreateCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + if (ifMatch != null) { + requestOptions.setHeader(HttpHeaderName.IF_MATCH, ifMatch); + } + return serviceClient.beginCreateCampaignWithModelAsync(agentName, campaignName, BinaryData.fromObject(campaign), + requestOptions); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCreateCampaign(String agentName, + String campaignName, TelephonyCampaign campaign) { + // Generated convenience method for beginCreateCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginCreateCampaignWithModelAsync(agentName, campaignName, BinaryData.fromObject(campaign), + requestOptions); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param operationId Original response's Operation-Id guards its instance/round and survives same-round actions. + * Replacement/name reuse: 409 campaign_operation_mismatch; missing/expired/wrong-scope operation: 404. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients on successful completion of + * {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getCampaign(String agentName, String campaignName, String operationId) { + // Generated convenience method for getCampaignWithResponse + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.addQueryParam("operation_id", operationId, false); + } + return getCampaignWithResponse(agentName, campaignName, requestOptions).flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaign.class)); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients on successful completion of + * {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getCampaign(String agentName, String campaignName) { + // Generated convenience method for getCampaignWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getCampaignWithResponse(agentName, campaignName, requestOptions).flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaign.class)); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param before Opaque first_id for backward paging with unchanged scope/filters/order; exclusive with after. + * @param status Filter by Campaign business state. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaigns(String agentName, Integer limit, PageOrder order, String before, + TelephonyCampaignStatus status) { + // Generated convenience method for listCampaigns + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + if (status != null) { + requestOptions.addQueryParam("status", status.toString(), false); + } + PagedFlux pagedFluxResponse = serviceClient.listCampaignsAsync(null, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaign.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaigns(String agentName) { + // Generated convenience method for listCampaigns + RequestOptions requestOptions = new RequestOptions(); + PagedFlux pagedFluxResponse = serviceClient.listCampaignsAsync(null, agentName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase(pagedResponse.getRequest(), + pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaign.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param operationId Optional retry key, generated if omitted. Original If-Match/key replays 202 even after + * deletion/name reuse, never touching a replacement; conflicts return 409. Failed cancellation needs a fresh + * key/current token. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCancelCampaign(String agentName, + String campaignName, String ifMatch, String operationId) { + // Generated convenience method for beginCancelCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + return serviceClient.beginCancelCampaignWithModelAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCancelCampaign(String agentName, + String campaignName, String ifMatch) { + // Generated convenience method for beginCancelCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginCancelCampaignWithModelAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param operationId Optional retry key. Original If-Match/key replays 202 even after deletion/name reuse, never + * touching a new instance; conflicts return 409. Failed cleanup needs a fresh key/current token. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginDeleteCampaign(String agentName, String campaignName, + String ifMatch, String operationId) { + // Generated convenience method for beginDeleteCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + return serviceClient.beginDeleteCampaignWithModelAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link PollerFlux} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginDeleteCampaign(String agentName, String campaignName, + String ifMatch) { + // Generated convenience method for beginDeleteCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginDeleteCampaignWithModelAsync(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param before Opaque first_id for backward paging with unchanged scope/filters/order; exclusive with after. + * @param order Sort invalid rows by their original row_number. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return error-only page as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignValidationErrors(String agentName, + String campaignName, Integer limit, String before, PageOrder order) { + // Generated convenience method for listCampaignValidationErrors + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + PagedFlux pagedFluxResponse + = serviceClient.listCampaignValidationErrorsAsync(null, agentName, campaignName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaignValidationError.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return error-only page as paginated response with {@link PagedFlux}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignValidationErrors(String agentName, + String campaignName) { + // Generated convenience method for listCampaignValidationErrors + RequestOptions requestOptions = new RequestOptions(); + PagedFlux pagedFluxResponse + = serviceClient.listCampaignValidationErrorsAsync(null, agentName, campaignName, requestOptions); + return PagedFlux.create(() -> (continuationTokenParam, pageSizeParam) -> { + Flux> flux; + if (pageSizeParam == null) { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage().take(1) + : pagedFluxResponse.byPage(continuationTokenParam).take(1); + } else { + flux = (continuationTokenParam == null) + ? pagedFluxResponse.byPage(pageSizeParam).take(1) + : pagedFluxResponse.byPage(continuationTokenParam, pageSizeParam).take(1); + } + return flux.map(pagedResponse -> new PagedResponseBase( + pagedResponse.getRequest(), pagedResponse.getStatusCode(), pagedResponse.getHeaders(), + pagedResponse.getValue() + .stream() + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaignValidationError.class)) + .collect(Collectors.toList()), + pagedResponse.getContinuationToken(), null)); + }); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a campaign operation + * + * Gets the initiating operation's status on successful completion of {@link Mono}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getCampaignOperation(String agentName, String campaignName, + String operationId) { + // Generated convenience method for getCampaignOperationWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getCampaignOperationWithResponse(agentName, campaignName, operationId, requestOptions) + .flatMap(FluxUtil::toMono) + .map(protocolMethodData -> protocolMethodData.toObject(TelephonyCampaignOperation.class)); + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java index c12e4b4345dd9..d54c7fe40e8c2 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java @@ -8,16 +8,19 @@ import com.azure.ai.agents.implementation.models.ReplaceTelephonyTransferTargetsRequest; import com.azure.ai.agents.implementation.models.TransferTelephonyCallRequest; import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.ai.agents.models.CreateTelephonyBindingInput; -import com.azure.ai.agents.models.CreateTelephonyCallJobInput; import com.azure.ai.agents.models.PageOrder; import com.azure.ai.agents.models.TelephonyBinding; import com.azure.ai.agents.models.TelephonyBindingListItem; -import com.azure.ai.agents.models.TelephonyBindingStatus; import com.azure.ai.agents.models.TelephonyCallJob; +import com.azure.ai.agents.models.TelephonyCallJobCreate; +import com.azure.ai.agents.models.TelephonyCallJobStatus; import com.azure.ai.agents.models.TelephonyCallRecord; import com.azure.ai.agents.models.TelephonyCallStatus; import com.azure.ai.agents.models.TelephonyCallSummary; +import com.azure.ai.agents.models.TelephonyCampaign; +import com.azure.ai.agents.models.TelephonyCampaignOperation; +import com.azure.ai.agents.models.TelephonyCampaignStatus; +import com.azure.ai.agents.models.TelephonyCampaignValidationError; import com.azure.ai.agents.models.TelephonyProvider; import com.azure.ai.agents.models.TelephonyTransferTarget; import com.azure.ai.agents.models.TelephonyTransferTargets; @@ -30,10 +33,12 @@ import com.azure.core.exception.HttpResponseException; import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.HttpHeaderName; import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.RequestOptions; import com.azure.core.http.rest.Response; import com.azure.core.util.BinaryData; +import com.azure.core.util.polling.SyncPoller; import java.time.OffsetDateTime; import java.util.List; @@ -75,9 +80,11 @@ public final class BetaVoiceAgentsTelephonyClient { *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
+     *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
+     *     incoming_call_url: String (Required)
      * }
      * }
      * 
@@ -87,11 +94,10 @@ public final class BetaVoiceAgentsTelephonyClient { *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -106,7 +112,7 @@ public final class BetaVoiceAgentsTelephonyClient {
      * 
      *
      * @param agentName The name of the voice agent that owns the binding.
-     * @param telephonyBinding The provider-specific binding to create.
+     * @param binding The provider-specific binding to create.
      * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
      * @throws HttpResponseException thrown if the request is rejected by server.
      * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
@@ -116,9 +122,9 @@ public final class BetaVoiceAgentsTelephonyClient {
      */
     @Generated
     @ServiceMethod(returns = ReturnType.SINGLE)
-    public Response createTelephonyBindingWithResponse(String agentName, BinaryData telephonyBinding,
+    public Response createTelephonyBindingWithResponse(String agentName, BinaryData binding,
         RequestOptions requestOptions) {
-        return this.serviceClient.createTelephonyBindingWithResponse(agentName, telephonyBinding, requestOptions);
+        return this.serviceClient.createTelephonyBindingWithResponse(agentName, binding, requestOptions);
     }
 
     /**
@@ -130,9 +136,7 @@ public Response createTelephonyBindingWithResponse(String agentName,
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -154,11 +158,10 @@ public Response createTelephonyBindingWithResponse(String agentName,
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -188,11 +191,10 @@ public PagedIterable listTelephonyBindings(String agentName, Request
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -233,10 +235,12 @@ public Response getTelephonyBindingWithResponse(String agentName, St
      * 
      * {@code
      * {
-     *     status: String(active/suspended) (Optional)
      *     label: String (Optional)
      *     connection_name: String (Optional)
      *     phone_number: String (Optional)
+     *     allowed_calling_numbers (Optional): [
+     *         String (Optional)
+     *     ]
      * }
      * }
      * 
@@ -246,11 +250,10 @@ public Response getTelephonyBindingWithResponse(String agentName, St *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -316,7 +319,7 @@ public Response deleteTelephonyBindingWithResponse(String agentName, Strin
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -345,7 +348,7 @@ public Response deleteTelephonyBindingWithResponse(String agentName, Strin
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -389,7 +392,7 @@ public PagedIterable listTelephonyCalls(String agentName, RequestOpt
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -485,7 +488,7 @@ public Response getTelephonyCallWithResponse(String agentName, Strin
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -571,7 +574,7 @@ public Response transferTelephonyCallWithResponse(String agentName,
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -659,7 +662,8 @@ public Response endTelephonyCallWithResponse(String agentName, Strin
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -706,7 +710,8 @@ public Response getTelephonyTransferTargetsWithResponse(String agent
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -724,7 +729,8 @@ public Response getTelephonyTransferTargetsWithResponse(String agent
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -762,18 +768,18 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a
     /**
      * Create an outbound telephony call job
      *
-     * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes.
+     * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and
+     * its voice session.
      * 

Request Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -786,6 +792,7 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a
      *         type: String(fixed_interval) (Required)
      *         max_attempts: Integer (Optional)
      *     }
+     *     source (Required): (recursive schema, see source above)
      * }
      * }
      * 
@@ -796,11 +803,10 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -810,7 +816,6 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -829,6 +834,8 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -837,15 +844,18 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -856,8 +866,8 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a @Generated @ServiceMethod(returns = ReturnType.SINGLE) public Response createTelephonyCallJobWithResponse(String agentName, String idempotencyKey, - BinaryData body, RequestOptions requestOptions) { - return this.serviceClient.createTelephonyCallJobWithResponse(agentName, idempotencyKey, body, requestOptions); + BinaryData job, RequestOptions requestOptions) { + return this.serviceClient.createTelephonyCallJobWithResponse(agentName, idempotencyKey, job, requestOptions); } /** @@ -870,11 +880,10 @@ public Response createTelephonyCallJobWithResponse(String agentName, * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -884,7 +893,6 @@ public Response createTelephonyCallJobWithResponse(String agentName, * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -903,6 +911,8 @@ public Response createTelephonyCallJobWithResponse(String agentName, * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -911,11 +921,12 @@ public Response createTelephonyCallJobWithResponse(String agentName, * * * - * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -935,18 +946,18 @@ public Response getTelephonyCallJobWithResponse(String agentName, St /** * Cancel an outbound telephony call job * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. *

Response Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -956,7 +967,6 @@ public Response getTelephonyCallJobWithResponse(String agentName, St
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -975,6 +985,8 @@ public Response getTelephonyCallJobWithResponse(String agentName, St
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
@@ -983,13 +995,16 @@ public Response getTelephonyCallJobWithResponse(String agentName, St * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that * read. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. @@ -1242,8 +1257,8 @@ public TelephonyTransferTargets replaceTelephonyTransferTargets(String agentName * * Retrieves a durable direct or campaign-created outbound call job. * - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1266,10 +1281,11 @@ public TelephonyCallJob getTelephonyCallJob(String agentName, String callJobId) /** * Cancel an outbound telephony call job * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. * - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that * read. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -1289,31 +1305,6 @@ public TelephonyCallJob cancelTelephonyCallJob(String agentName, String callJobI .toObject(TelephonyCallJob.class); } - /** - * Create an agent telephony binding - * - * Creates a telephony binding for the voice agent named in the path. - * - * @param agentName The name of the voice agent that owns the binding. - * @param telephonyBinding The provider-specific binding to create. - * @throws IllegalArgumentException thrown if parameters fail the validation. - * @throws HttpResponseException thrown if the request is rejected by server. - * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. - * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. - * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. - * @return a telephony binding owned by a voice agent. - */ - @Generated - @ServiceMethod(returns = ReturnType.SINGLE) - public TelephonyBinding createTelephonyBinding(String agentName, CreateTelephonyBindingInput telephonyBinding) { - // Generated convenience method for createTelephonyBindingWithResponse - RequestOptions requestOptions = new RequestOptions(); - return createTelephonyBindingWithResponse(agentName, BinaryData.fromObject(telephonyBinding), requestOptions) - .getValue() - .toObject(TelephonyBinding.class); - } - /** * Update an agent telephony binding * @@ -1349,30 +1340,196 @@ public TelephonyBinding updateTelephonyBinding(String agentName, String bindingI } /** - * Create an outbound telephony call job + * List agent telephony calls * - * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes. + * Returns the durable inbound call history for the voice agent named in the path. * - * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. + * @param agentName The name of the voice agent whose calls are listed. + * @param provider Filters calls by provider. + * @param status Filters calls by lifecycle status. + * @param startedAfter Includes calls that started at or after this Unix timestamp in seconds. + * @param startedBefore Includes calls that started at or before this Unix timestamp in seconds. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param after A cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list. + * @param 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. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. - * @return a durable direct or campaign-created outbound call intent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listTelephonyCalls(String agentName, TelephonyProvider provider, + TelephonyCallStatus status, OffsetDateTime startedAfter, OffsetDateTime startedBefore, Integer limit, + PageOrder order, String after, String before) { + // Generated convenience method for listTelephonyCalls + RequestOptions requestOptions = new RequestOptions(); + if (provider != null) { + requestOptions.addQueryParam("provider", provider.toString(), false); + } + if (status != null) { + requestOptions.addQueryParam("status", status.toString(), false); + } + if (startedAfter != null) { + requestOptions.addQueryParam("started_after", String.valueOf(startedAfter.toEpochSecond()), false); + } + if (startedBefore != null) { + requestOptions.addQueryParam("started_before", String.valueOf(startedBefore.toEpochSecond()), false); + } + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + return serviceClient.listTelephonyCalls(after, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCallSummary.class)); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + *

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listTelephonyCallJobs(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listTelephonyCallJobs(agentName, requestOptions); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response}. */ @Generated @ServiceMethod(returns = ReturnType.SINGLE) - public TelephonyCallJob createTelephonyCallJob(String agentName, String idempotencyKey, - CreateTelephonyCallJobInput body) { - // Generated convenience method for createTelephonyCallJobWithResponse + public Response deleteTelephonyCallJobWithResponse(String agentName, String callJobId, + RequestOptions requestOptions) { + return this.serviceClient.deleteTelephonyCallJobWithResponse(agentName, callJobId, requestOptions); + } + + /** + * Create an agent telephony binding + * + * Creates a telephony binding for the voice agent named in the path. + * + * @param agentName The name of the voice agent that owns the binding. + * @param binding The provider-specific binding to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony binding owned by a voice agent. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public TelephonyBinding createTelephonyBinding(String agentName, TelephonyBinding binding) { + // Generated convenience method for createTelephonyBindingWithResponse RequestOptions requestOptions = new RequestOptions(); - return createTelephonyCallJobWithResponse(agentName, idempotencyKey, BinaryData.fromObject(body), - requestOptions).getValue().toObject(TelephonyCallJob.class); + return createTelephonyBindingWithResponse(agentName, BinaryData.fromObject(binding), requestOptions).getValue() + .toObject(TelephonyBinding.class); } /** @@ -1382,7 +1539,6 @@ public TelephonyCallJob createTelephonyCallJob(String agentName, String idempote * * @param agentName The name of the voice agent whose bindings are listed. * @param provider Filters bindings by provider. - * @param status Filters bindings by lifecycle status. * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the * default is 20. * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` @@ -1404,15 +1560,12 @@ public TelephonyCallJob createTelephonyCallJob(String agentName, String idempote @Generated @ServiceMethod(returns = ReturnType.COLLECTION) public PagedIterable listTelephonyBindings(String agentName, TelephonyProvider provider, - TelephonyBindingStatus status, Integer limit, PageOrder order, String after, String before) { + Integer limit, PageOrder order, String after, String before) { // Generated convenience method for listTelephonyBindings RequestOptions requestOptions = new RequestOptions(); if (provider != null) { requestOptions.addQueryParam("provider", provider.toString(), false); } - if (status != null) { - requestOptions.addQueryParam("status", status.toString(), false); - } if (limit != null) { requestOptions.addQueryParam("limit", String.valueOf(limit), false); } @@ -1427,15 +1580,41 @@ public PagedIterable listTelephonyBindings(String agen } /** - * List agent telephony calls + * Create an outbound telephony call job * - * Returns the durable inbound call history for the voice agent named in the path. + * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and + * its voice session. * - * @param agentName The name of the voice agent whose calls are listed. - * @param provider Filters calls by provider. - * @param status Filters calls by lifecycle status. - * @param startedAfter Includes calls that started at or after this Unix timestamp in seconds. - * @param startedBefore Includes calls that started at or before this Unix timestamp in seconds. + * @param agentName The name of the voice agent that executes the call. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a durable direct or campaign-created outbound call intent. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public TelephonyCallJob createTelephonyCallJob(String agentName, String idempotencyKey, + TelephonyCallJobCreate job) { + // Generated convenience method for createTelephonyCallJobWithResponse + RequestOptions requestOptions = new RequestOptions(); + return createTelephonyCallJobWithResponse(agentName, idempotencyKey, BinaryData.fromObject(job), requestOptions) + .getValue() + .toObject(TelephonyCallJob.class); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + * + * @param agentName The owning voice agent. Authorization is applied before pagination. * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the * default is 20. * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` @@ -1446,6 +1625,9 @@ public PagedIterable listTelephonyBindings(String agen * @param 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. + * @param status Optional lifecycle filter. + * @param campaignName Current Campaign round: 404 if absent, empty while deleting. Omit for direct and Campaign + * jobs. Replacement/name reuse invalidates cursors. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1456,23 +1638,10 @@ public PagedIterable listTelephonyBindings(String agen */ @Generated @ServiceMethod(returns = ReturnType.COLLECTION) - public PagedIterable listTelephonyCalls(String agentName, TelephonyProvider provider, - TelephonyCallStatus status, OffsetDateTime startedAfter, OffsetDateTime startedBefore, Integer limit, - PageOrder order, String after, String before) { - // Generated convenience method for listTelephonyCalls + public PagedIterable listTelephonyCallJobs(String agentName, Integer limit, PageOrder order, + String after, String before, TelephonyCallJobStatus status, String campaignName) { + // Generated convenience method for listTelephonyCallJobs RequestOptions requestOptions = new RequestOptions(); - if (provider != null) { - requestOptions.addQueryParam("provider", provider.toString(), false); - } - if (status != null) { - requestOptions.addQueryParam("status", status.toString(), false); - } - if (startedAfter != null) { - requestOptions.addQueryParam("started_after", String.valueOf(startedAfter.toEpochSecond()), false); - } - if (startedBefore != null) { - requestOptions.addQueryParam("started_before", String.valueOf(startedBefore.toEpochSecond()), false); - } if (limit != null) { requestOptions.addQueryParam("limit", String.valueOf(limit), false); } @@ -1482,7 +1651,1119 @@ public PagedIterable listTelephonyCalls(String agentName, if (before != null) { requestOptions.addQueryParam("before", before, false); } - return serviceClient.listTelephonyCalls(after, agentName, requestOptions) - .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCallSummary.class)); + if (status != null) { + requestOptions.addQueryParam("status", status.toString(), false); + } + if (campaignName != null) { + requestOptions.addQueryParam("campaign_name", campaignName, false); + } + return serviceClient.listTelephonyCallJobs(after, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCallJob.class)); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listTelephonyCallJobs(String agentName) { + // Generated convenience method for listTelephonyCallJobs + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.listTelephonyCallJobs(null, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCallJob.class)); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public void deleteTelephonyCallJob(String agentName, String callJobId) { + // Generated convenience method for deleteTelephonyCallJobWithResponse + RequestOptions requestOptions = new RequestOptions(); + deleteTelephonyCallJobWithResponse(agentName, callJobId, requestOptions).getValue(); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCreateCampaign(String agentName, String campaignName, + BinaryData campaign, RequestOptions requestOptions) { + return this.serviceClient.beginCreateCampaign(agentName, campaignName, campaign, requestOptions); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
operation_idStringNoOriginal response's Operation-Id guards its instance/round + * and survives same-round actions. Replacement/name reuse: 409 campaign_operation_mismatch; + * missing/expired/wrong-scope operation: 404.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getCampaignWithResponse(String agentName, String campaignName, + RequestOptions requestOptions) { + return this.serviceClient.getCampaignWithResponse(agentName, campaignName, requestOptions); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaigns(String agentName, RequestOptions requestOptions) { + return this.serviceClient.listCampaigns(agentName, requestOptions); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCancelCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return this.serviceClient.beginCancelCampaign(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginDeleteCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return this.serviceClient.beginDeleteCampaign(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaignValidationErrors(String agentName, String campaignName, + RequestOptions requestOptions) { + return this.serviceClient.listCampaignValidationErrors(agentName, campaignName, requestOptions); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + *
Response Headers
NameTypeDescription
Retry-AfterintRecommended number of seconds to wait before polling again.
+ * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a campaign operation + * + * Gets the initiating operation's status along with {@link Response}. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getCampaignOperationWithResponse(String agentName, String campaignName, + String operationId, RequestOptions requestOptions) { + return this.serviceClient.getCampaignOperationWithResponse(agentName, campaignName, operationId, + requestOptions); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param operationId Retry key: matching submitted inputs and original If-Match replay the saved monitor before + * current-state checks. Conflicting reuse returns 409 operation_id_conflict; retained creation keys after deletion + * return 409 campaign_deleted. + * @param ifMatch Required with a fresh Operation-Id for failed-state replacement; no wildcards. Changed input + * without it returns 409. Missing replacement ID: 400; stale token/absent resource: 412; other states: 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCreateCampaign(String agentName, + String campaignName, TelephonyCampaign campaign, String operationId, String ifMatch) { + // Generated convenience method for beginCreateCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + if (ifMatch != null) { + requestOptions.setHeader(HttpHeaderName.IF_MATCH, ifMatch); + } + return serviceClient.beginCreateCampaignWithModel(agentName, campaignName, BinaryData.fromObject(campaign), + requestOptions); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of agent-owned outbound call Campaign. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCreateCampaign(String agentName, + String campaignName, TelephonyCampaign campaign) { + // Generated convenience method for beginCreateCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginCreateCampaignWithModel(agentName, campaignName, BinaryData.fromObject(campaign), + requestOptions); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param operationId Original response's Operation-Id guards its instance/round and survives same-round actions. + * Replacement/name reuse: 409 campaign_operation_mismatch; missing/expired/wrong-scope operation: 404. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public TelephonyCampaign getCampaign(String agentName, String campaignName, String operationId) { + // Generated convenience method for getCampaignWithResponse + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.addQueryParam("operation_id", operationId, false); + } + return getCampaignWithResponse(agentName, campaignName, requestOptions).getValue() + .toObject(TelephonyCampaign.class); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public TelephonyCampaign getCampaign(String agentName, String campaignName) { + // Generated convenience method for getCampaignWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getCampaignWithResponse(agentName, campaignName, requestOptions).getValue() + .toObject(TelephonyCampaign.class); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param order Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + * for descending order. + * @param before Opaque first_id for backward paging with unchanged scope/filters/order; exclusive with after. + * @param status Filter by Campaign business state. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaigns(String agentName, Integer limit, PageOrder order, + String before, TelephonyCampaignStatus status) { + // Generated convenience method for listCampaigns + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + if (status != null) { + requestOptions.addQueryParam("status", status.toString(), false); + } + return serviceClient.listCampaigns(null, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCampaign.class)); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaigns(String agentName) { + // Generated convenience method for listCampaigns + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.listCampaigns(null, agentName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCampaign.class)); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param operationId Optional retry key, generated if omitted. Original If-Match/key replays 202 even after + * deletion/name reuse, never touching a replacement; conflicts return 409. Failed cancellation needs a fresh + * key/current token. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCancelCampaign(String agentName, + String campaignName, String ifMatch, String operationId) { + // Generated convenience method for beginCancelCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + return serviceClient.beginCancelCampaignWithModel(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCancelCampaign(String agentName, + String campaignName, String ifMatch) { + // Generated convenience method for beginCancelCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginCancelCampaignWithModel(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param operationId Optional retry key. Original If-Match/key replays 202 even after deletion/name reuse, never + * touching a new instance; conflicts return 409. Failed cleanup needs a fresh key/current token. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginDeleteCampaign(String agentName, String campaignName, + String ifMatch, String operationId) { + // Generated convenience method for beginDeleteCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + if (operationId != null) { + requestOptions.setHeader(HttpHeaderName.fromString("Operation-Id"), operationId); + } + return serviceClient.beginDeleteCampaignWithModel(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link SyncPoller} for polling of long-running operation. + */ + @Generated + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginDeleteCampaign(String agentName, String campaignName, + String ifMatch) { + // Generated convenience method for beginDeleteCampaignWithModel + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.beginDeleteCampaignWithModel(agentName, campaignName, ifMatch, requestOptions); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + * default is 20. + * @param before Opaque first_id for backward paging with unchanged scope/filters/order; exclusive with after. + * @param order Sort invalid rows by their original row_number. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return error-only page as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaignValidationErrors(String agentName, + String campaignName, Integer limit, String before, PageOrder order) { + // Generated convenience method for listCampaignValidationErrors + RequestOptions requestOptions = new RequestOptions(); + if (limit != null) { + requestOptions.addQueryParam("limit", String.valueOf(limit), false); + } + if (before != null) { + requestOptions.addQueryParam("before", before, false); + } + if (order != null) { + requestOptions.addQueryParam("order", order.toString(), false); + } + return serviceClient.listCampaignValidationErrors(null, agentName, campaignName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCampaignValidationError.class)); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return error-only page as paginated response with {@link PagedIterable}. + */ + @Generated + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaignValidationErrors(String agentName, + String campaignName) { + // Generated convenience method for listCampaignValidationErrors + RequestOptions requestOptions = new RequestOptions(); + return serviceClient.listCampaignValidationErrors(null, agentName, campaignName, requestOptions) + .mapPage(bodyItemValue -> bodyItemValue.toObject(TelephonyCampaignValidationError.class)); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return a campaign operation + * + * Gets the initiating operation's status. + */ + @Generated + @ServiceMethod(returns = ReturnType.SINGLE) + public TelephonyCampaignOperation getCampaignOperation(String agentName, String campaignName, String operationId) { + // Generated convenience method for getCampaignOperationWithResponse + RequestOptions requestOptions = new RequestOptions(); + return getCampaignOperationWithResponse(agentName, campaignName, operationId, requestOptions).getValue() + .toObject(TelephonyCampaignOperation.class); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketAsyncClient.java similarity index 57% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketAsyncClient.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketAsyncClient.java index 4b5ed49dece92..f3a4fa41d0fc6 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketAsyncClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketAsyncClient.java @@ -4,10 +4,14 @@ package com.azure.ai.agents; import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionAsyncTransport; +import com.azure.ai.agents.implementation.realtime.WebSocketTransportOptions; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; import com.azure.core.annotation.ServiceClient; import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; import java.util.Objects; @@ -16,10 +20,10 @@ */ @ServiceClient(builder = AgentsClientBuilder.class, isAsync = true) @Beta(warningText = "This class is in preview and may change in future releases.") -public final class BetaVoiceAgentWebSocketAsyncClient { +public final class BetaVoiceAgentsWebSocketAsyncClient { private final VoiceAgentWebSocketClientConfiguration configuration; - BetaVoiceAgentWebSocketAsyncClient(VoiceAgentWebSocketClientConfiguration configuration) { + BetaVoiceAgentsWebSocketAsyncClient(VoiceAgentWebSocketClientConfiguration configuration) { this.configuration = Objects.requireNonNull(configuration, "'configuration' cannot be null."); } @@ -29,7 +33,7 @@ public final class BetaVoiceAgentWebSocketAsyncClient { * @param agentName the voice agent name. * @return a connected session. */ - public Mono openWebSocketSession(String agentName) { + public Mono openWebSocketSession(String agentName) { return openWebSocketSession(agentName, new VoiceAgentWebSocketConnectionOptions()); } @@ -40,15 +44,20 @@ public Mono openWebSocketSession(Stri * @param options connection options. * @return a connected session. */ - public Mono openWebSocketSession(String agentName, + public Mono openWebSocketSession(String agentName, VoiceAgentWebSocketConnectionOptions options) { Objects.requireNonNull(agentName, "'agentName' cannot be null."); Objects.requireNonNull(options, "'options' cannot be null."); VoiceAgentWebSocketConnectionOptions optionsSnapshot = new VoiceAgentWebSocketConnectionOptions(options); return Mono.defer(() -> { - BetaVoiceAgentWebSocketSessionAsyncClient session - = new BetaVoiceAgentWebSocketSessionAsyncClient(configuration, agentName, optionsSnapshot); - return session.connect().thenReturn(session); + WebSocketSessionAsyncTransport transport = new WebSocketSessionAsyncTransport(configuration, + VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, agentName, optionsSnapshot), + new WebSocketTransportOptions(optionsSnapshot), HttpClient.create(), + VoiceAgentWebSocketUtils.SUBPROTOCOL, + token -> VoiceAgentWebSocketUtils.buildHeaders(configuration, optionsSnapshot, token)); + return transport.connect() + .thenReturn(new BetaVoiceAgentsWebSocketSessionAsyncClient(transport, + optionsSnapshot.getMalformedEventHandler())); }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketClient.java similarity index 59% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketClient.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketClient.java index 232c956f84313..b895f9de9f48e 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketClient.java @@ -4,6 +4,9 @@ package com.azure.ai.agents; import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionTransport; +import com.azure.ai.agents.implementation.realtime.WebSocketTransportOptions; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; import com.azure.core.annotation.ServiceClient; @@ -16,11 +19,11 @@ */ @ServiceClient(builder = AgentsClientBuilder.class) @Beta(warningText = "This class is in preview and may change in future releases.") -public final class BetaVoiceAgentWebSocketClient { - private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentWebSocketClient.class); +public final class BetaVoiceAgentsWebSocketClient { + private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentsWebSocketClient.class); private final VoiceAgentWebSocketClientConfiguration configuration; - BetaVoiceAgentWebSocketClient(VoiceAgentWebSocketClientConfiguration configuration) { + BetaVoiceAgentsWebSocketClient(VoiceAgentWebSocketClientConfiguration configuration) { this.configuration = Objects.requireNonNull(configuration, "'configuration' cannot be null."); } @@ -30,7 +33,7 @@ public final class BetaVoiceAgentWebSocketClient { * @param agentName the voice agent name. * @return a connected session. */ - public BetaVoiceAgentWebSocketSessionClient openWebSocketSession(String agentName) { + public BetaVoiceAgentsWebSocketSessionClient openWebSocketSession(String agentName) { return openWebSocketSession(agentName, new VoiceAgentWebSocketConnectionOptions()); } @@ -39,17 +42,22 @@ public BetaVoiceAgentWebSocketSessionClient openWebSocketSession(String agentNam * * @param agentName the voice agent name. * @param options connection options. - * @throws IllegalArgumentException if {@code agentName} is empty. * @return a connected session. + * @throws IllegalArgumentException if {@code agentName} is empty. */ - public BetaVoiceAgentWebSocketSessionClient openWebSocketSession(String agentName, + public BetaVoiceAgentsWebSocketSessionClient openWebSocketSession(String agentName, VoiceAgentWebSocketConnectionOptions options) { Objects.requireNonNull(agentName, "'agentName' cannot be null."); if (agentName.isEmpty()) { throw LOGGER.logExceptionAsError(new IllegalArgumentException("'agentName' cannot be empty.")); } Objects.requireNonNull(options, "'options' cannot be null."); - return BetaVoiceAgentWebSocketSessionClient.connect(configuration, agentName, - new VoiceAgentWebSocketConnectionOptions(options)); + VoiceAgentWebSocketConnectionOptions snapshot = new VoiceAgentWebSocketConnectionOptions(options); + return new BetaVoiceAgentsWebSocketSessionClient( + WebSocketSessionTransport.connect(configuration, + VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, agentName, snapshot), + new WebSocketTransportOptions(snapshot), VoiceAgentWebSocketUtils.SUBPROTOCOL, + token -> VoiceAgentWebSocketUtils.buildHeaders(configuration, snapshot, token)), + snapshot.getMalformedEventHandler()); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionAsyncClient.java new file mode 100644 index 0000000000000..b5c58bacf8bbd --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionAsyncClient.java @@ -0,0 +1,271 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionAsyncTransport; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.RealtimeClientEvent; +import com.azure.ai.agents.models.RealtimeConversationItem; +import com.azure.ai.agents.models.RealtimeConversationItemCreateEvent; +import com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput; +import com.azure.ai.agents.models.RealtimeConversationItemUserMessage; +import com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent; +import com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent; +import com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent; +import com.azure.ai.agents.models.RealtimeResponseCancelEvent; +import com.azure.ai.agents.models.RealtimeResponseCreateEvent; +import com.azure.ai.agents.models.RealtimeServerEvent; +import com.azure.ai.agents.models.VoiceAgentResponseCreateOptions; +import com.azure.core.util.AsyncCloseable; +import com.azure.core.util.BinaryData; +import com.openai.models.realtime.RealtimeConversationItemUserMessage.Content; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.io.IOException; +import java.util.Base64; +import java.util.Collections; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * An asynchronous bidirectional realtime session connected to a Foundry voice agent. + * + *

Instances are created by {@link BetaVoiceAgentsWebSocketAsyncClient#openWebSocketSession(String)}. A session supports one + * subscriber to {@link #receiveEvents()}. Close the session when it is no longer needed.

+ */ +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsWebSocketSessionAsyncClient implements AsyncCloseable, AutoCloseable { + private final WebSocketSessionAsyncTransport transport; + private final Consumer malformedEventHandler; + + BetaVoiceAgentsWebSocketSessionAsyncClient(WebSocketSessionAsyncTransport transport, + Consumer malformedEventHandler) { + this.transport = transport; + this.malformedEventHandler = malformedEventHandler; + } + + /** + * Gets the WebSocket endpoint used by this session. + * + * @return the WebSocket endpoint. + */ + public String getEndpoint() { + return transport.getEndpoint(); + } + + /** + * Determines whether the WebSocket session is open. + * + * @return {@code true} when the session is open. + */ + public boolean isOpen() { + return transport.isOpen(); + } + + /** + * Gets the peer close code after the session closes. + * + * @return the close code, or {@code null} when no close frame has been received. + */ + public Integer getCloseCode() { + return transport.getCloseCode(); + } + + /** + * Gets the peer close reason after the session closes. + * + * @return the close reason, or {@code null} when no close frame has been received. + */ + public String getCloseReason() { + return transport.getCloseReason(); + } + + /** + * Receives typed server events in wire order. Only one subscriber is supported per session. + * + * @return the server event stream. + */ + public Flux receiveEvents() { + return VoiceAgentWebSocketUtils.decodeEvents(transport.receiveEvents(), + VoiceAgentWebSocketUtils::deserializeEvent, malformedEventHandler, + () -> transport.closeAsync(1007, "Invalid JSON event").subscribe()); + } + + /** + * Sends a typed realtime client event. + * + * @param event the event to send. + * @return a completion signal emitted after the frame is written. + */ + public Mono sendEvent(RealtimeClientEvent event) { + Objects.requireNonNull(event, "'event' cannot be null."); + return Mono.defer(() -> { + try { + return transport.sendEvent(BinaryData.fromString(event.toJsonString())); + } catch (IOException error) { + return Mono + .error(new IllegalArgumentException("Failed to serialize the realtime client event.", error)); + } + }); + } + + /** + * Sends a JSON object, including event types and fields unknown to this SDK. + * + * @param event the complete JSON event. + * @return completion after the frame is written, or an error for invalid JSON or a closed session. + */ + public Mono sendEvent(BinaryData event) { + return transport.sendEvent(event); + } + + /** + * Adds an item to the session conversation. + * + * @param item the item to add. + * @return a completion signal emitted after the event is written. + */ + public Mono createConversationItem(RealtimeConversationItem item) { + return createConversationItem(item, null); + } + + /** + * Adds an item after a specific conversation item. + * + * @param item the item to add. + * @param previousItemId the preceding item identifier, or {@code null} to append. + * @return a completion signal emitted after the event is written. + */ + public Mono createConversationItem(RealtimeConversationItem item, String previousItemId) { + Objects.requireNonNull(item, "'item' cannot be null."); + return sendEvent(new RealtimeConversationItemCreateEvent(item).setPreviousItemId(previousItemId)); + } + + /** + * Adds a user text message to the session conversation. + * + * @param text the user message. + * @return a completion signal emitted after the event is written. + */ + public Mono sendText(String text) { + Objects.requireNonNull(text, "'text' cannot be null."); + Content content = Content.builder().type(Content.Type.INPUT_TEXT).text(text).build(); + return createConversationItem(new RealtimeConversationItemUserMessage(Collections.singletonList(content))); + } + + /** + * Appends PCM or encoded audio bytes to the input audio buffer. + * + * @param audio the bytes in the input format configured by the voice agent. + * @return a completion signal emitted after the event is written. + */ + public Mono appendInputAudio(BinaryData audio) { + Objects.requireNonNull(audio, "'audio' cannot be null."); + String encoded = Base64.getEncoder().encodeToString(audio.toBytes()); + return sendEvent(new RealtimeInputAudioBufferAppendEvent(encoded)); + } + + /** + * Clears the input audio buffer. + * + * @return a completion signal emitted after the event is written. + */ + public Mono clearInputAudio() { + return sendEvent(new RealtimeInputAudioBufferClearEvent()); + } + + /** + * Commits the input audio buffer. + * + * @return a completion signal emitted after the event is written. + */ + public Mono commitInputAudio() { + return sendEvent(new RealtimeInputAudioBufferCommitEvent()); + } + + /** + * Requests a response using the persisted voice-agent configuration. + * + * @return a completion signal emitted after the event is written. + */ + public Mono createResponse() { + return sendEvent(new RealtimeResponseCreateEvent()); + } + + /** + * Requests a response with per-response options. + * + * @param responseOptions the response options. + * @return a completion signal emitted after the event is written. + */ + public Mono createResponse(VoiceAgentResponseCreateOptions responseOptions) { + Objects.requireNonNull(responseOptions, "'responseOptions' cannot be null."); + return sendEvent(new RealtimeResponseCreateEvent().setResponse(responseOptions)); + } + + /** + * Cancels the response currently writing to the default conversation. + * + * @return a completion signal emitted after the event is written. + */ + public Mono cancelResponse() { + return sendEvent(new RealtimeResponseCancelEvent()); + } + + /** + * Cancels a specific response. + * + * @param responseId the response identifier. + * @return a completion signal emitted after the event is written. + */ + public Mono cancelResponse(String responseId) { + Objects.requireNonNull(responseId, "'responseId' cannot be null."); + return sendEvent(new RealtimeResponseCancelEvent().setResponseId(responseId)); + } + + /** + * Sends a function-call result and requests the next response. + * + * @param callId the function call identifier. + * @param output the serialized function result. + * @return a completion signal emitted after both events are written. + */ + public Mono sendFunctionCallOutput(String callId, String output) { + RealtimeConversationItemFunctionCallOutput item + = new RealtimeConversationItemFunctionCallOutput(callId, output); + return createConversationItem(item).then(createResponse()); + } + + /** + * Closes the WebSocket session. + * + * @return a completion signal for closing the session. + */ + @Override + public Mono closeAsync() { + return transport.closeAsync(); + } + + /** + * Closes the session with an application-selected WebSocket close frame. + * The first requested close frame wins when close is called more than once. + * + * @param code a valid WebSocket close code. + * @param reason non-null reason of at most 123 UTF-8 bytes. + * @return a completion signal, or an error if the code or reason is invalid. + */ + public Mono closeAsync(int code, String reason) { + return transport.closeAsync(code, reason); + } + + /** + * Closes the WebSocket session synchronously. + */ + @Override + public void close() { + transport.close(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClient.java new file mode 100644 index 0000000000000..422090b0aae86 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClient.java @@ -0,0 +1,254 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionTransport; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.ai.agents.models.RealtimeClientEvent; +import com.azure.ai.agents.models.RealtimeConversationItem; +import com.azure.ai.agents.models.RealtimeConversationItemCreateEvent; +import com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput; +import com.azure.ai.agents.models.RealtimeConversationItemUserMessage; +import com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent; +import com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent; +import com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent; +import com.azure.ai.agents.models.RealtimeResponseCancelEvent; +import com.azure.ai.agents.models.RealtimeResponseCreateEvent; +import com.azure.ai.agents.models.RealtimeServerEvent; +import com.azure.ai.agents.models.VoiceAgentResponseCreateOptions; +import com.azure.core.util.BinaryData; +import com.azure.core.util.IterableStream; +import com.azure.core.util.logging.ClientLogger; +import com.openai.models.realtime.RealtimeConversationItemUserMessage.Content; + +import java.io.IOException; +import java.time.Duration; +import java.util.Base64; +import java.util.Collections; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A synchronous bidirectional realtime session connected to a Foundry voice agent. + */ +@Beta(warningText = "This class is in preview and may change in future releases.") +public final class BetaVoiceAgentsWebSocketSessionClient implements AutoCloseable { + private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentsWebSocketSessionClient.class); + private final WebSocketSessionTransport transport; + private final Consumer malformedEventHandler; + + BetaVoiceAgentsWebSocketSessionClient(WebSocketSessionTransport transport, + Consumer malformedEventHandler) { + this.transport = transport; + this.malformedEventHandler = malformedEventHandler; + } + + /** + * Gets the WebSocket endpoint used by this session. + * + * @return the WebSocket endpoint. + */ + public String getEndpoint() { + return transport.getEndpoint(); + } + + /** + * Determines whether the session is open. + * + * @return {@code true} when the session is open. + */ + public boolean isOpen() { + return transport.isOpen(); + } + + /** + * Gets the peer close code. + * + * @return the close code, or {@code null}. + */ + public Integer getCloseCode() { + return transport.getCloseCode(); + } + + /** + * Gets the peer close reason. + * + * @return the close reason, or {@code null}. + */ + public String getCloseReason() { + return transport.getCloseReason(); + } + + /** + * Receives typed server events in wire order. The returned stream may be iterated once. + * + * @return the server event stream. + * @throws IllegalStateException if the event stream has already been claimed. + */ + public IterableStream receiveEvents() { + return receiveEvents(null); + } + + /** + * Receives events with a timeout for each wait. A timeout leaves the session open and the iterator can be retried. + * + * @param timeout positive per-event timeout, or null to wait indefinitely. + * @return the single-consumer event stream. + * @throws IllegalArgumentException if timeout is zero or negative. + * @throws IllegalStateException if another receiver exists or a wait times out (with a TimeoutException cause). + */ + public IterableStream receiveEvents(Duration timeout) { + return VoiceAgentWebSocketUtils.decodeEvents(transport.receiveEvents(timeout), + VoiceAgentWebSocketUtils::deserializeEvent, malformedEventHandler, + () -> transport.close(1007, "Invalid JSON event")); + } + + /** + * Sends a typed realtime client event. + * + * @param event the event to send. + * @throws IllegalArgumentException if the event cannot be serialized. + * @throws IllegalStateException if the session is closed or cannot accept another event. + */ + public void sendEvent(RealtimeClientEvent event) { + Objects.requireNonNull(event, "'event' cannot be null."); + try { + transport.sendEvent(BinaryData.fromString(event.toJsonString())); + } catch (IOException error) { + throw LOGGER.logExceptionAsError( + new IllegalArgumentException("Failed to serialize the realtime client event.", error)); + } + } + + /** + * Sends a JSON object, including event types and fields unknown to this SDK. + * + * @param event the complete JSON event. + * @throws IllegalArgumentException if the event is not a JSON object. + * @throws IllegalStateException if the session cannot accept the event. + */ + public void sendEvent(BinaryData event) { + transport.sendEvent(event); + } + + /** + * Adds a conversation item. + * + * @param item the item to add. + */ + public void createConversationItem(RealtimeConversationItem item) { + createConversationItem(item, null); + } + + /** + * Adds a conversation item after another item. + * + * @param item the item to add. + * @param previousItemId the preceding item identifier. + */ + public void createConversationItem(RealtimeConversationItem item, String previousItemId) { + Objects.requireNonNull(item, "'item' cannot be null."); + sendEvent(new RealtimeConversationItemCreateEvent(item).setPreviousItemId(previousItemId)); + } + + /** + * Adds a user text message. + * + * @param text the user message. + */ + public void sendText(String text) { + Objects.requireNonNull(text, "'text' cannot be null."); + Content content = Content.builder().type(Content.Type.INPUT_TEXT).text(text).build(); + createConversationItem(new RealtimeConversationItemUserMessage(Collections.singletonList(content))); + } + + /** + * Appends audio to the input buffer. + * + * @param audio the audio bytes. + */ + public void appendInputAudio(BinaryData audio) { + Objects.requireNonNull(audio, "'audio' cannot be null."); + sendEvent(new RealtimeInputAudioBufferAppendEvent(Base64.getEncoder().encodeToString(audio.toBytes()))); + } + + /** + * Clears the input audio buffer. + */ + public void clearInputAudio() { + sendEvent(new RealtimeInputAudioBufferClearEvent()); + } + + /** + * Commits the input audio buffer. + */ + public void commitInputAudio() { + sendEvent(new RealtimeInputAudioBufferCommitEvent()); + } + + /** + * Requests a response using the voice agent's configuration. + */ + public void createResponse() { + sendEvent(new RealtimeResponseCreateEvent()); + } + + /** + * Requests a response with per-response options. + * + * @param responseOptions response options. + */ + public void createResponse(VoiceAgentResponseCreateOptions responseOptions) { + Objects.requireNonNull(responseOptions, "'responseOptions' cannot be null."); + sendEvent(new RealtimeResponseCreateEvent().setResponse(responseOptions)); + } + + /** + * Cancels the active response. + */ + public void cancelResponse() { + sendEvent(new RealtimeResponseCancelEvent()); + } + + /** + * Cancels a specific response. + * + * @param responseId the response identifier. + */ + public void cancelResponse(String responseId) { + Objects.requireNonNull(responseId, "'responseId' cannot be null."); + sendEvent(new RealtimeResponseCancelEvent().setResponseId(responseId)); + } + + /** + * Sends a function-call result and requests the next response. + * + * @param callId the function call identifier. + * @param output the serialized function output. + */ + public void sendFunctionCallOutput(String callId, String output) { + createConversationItem(new RealtimeConversationItemFunctionCallOutput(callId, output)); + createResponse(); + } + + /** + * Closes the session. + */ + @Override + public void close() { + transport.close(); + } + + /** + * Closes the session with an application-selected WebSocket close frame. + * + * @param code a valid WebSocket close code. + * @param reason non-null reason of at most 123 UTF-8 bytes. + * @throws IllegalArgumentException if the code or reason is invalid. + */ + public void close(int code, String reason) { + transport.close(code, reason); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java index 4af5042801ecc..48ddd1f600ea3 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java @@ -94,6 +94,20 @@ public BetaVoiceAgentsConversationsImpl getBetaVoiceAgentsConversations() { return this.betaVoiceAgentsConversations; } + /** + * The BetaVoiceAgentsLiveConversationsImpl object to access its operations. + */ + private final BetaVoiceAgentsLiveConversationsImpl betaVoiceAgentsLiveConversations; + + /** + * Gets the BetaVoiceAgentsLiveConversationsImpl object to access its operations. + * + * @return the BetaVoiceAgentsLiveConversationsImpl object. + */ + public BetaVoiceAgentsLiveConversationsImpl getBetaVoiceAgentsLiveConversations() { + return this.betaVoiceAgentsLiveConversations; + } + /** * The BetaVoiceAgentsTelephoniesImpl object to access its operations. */ @@ -213,6 +227,7 @@ public AgentsClientImpl(HttpPipeline httpPipeline, SerializerAdapter serializerA this.endpoint = endpoint; this.serviceVersion = serviceVersion; this.betaVoiceAgentsConversations = new BetaVoiceAgentsConversationsImpl(this); + this.betaVoiceAgentsLiveConversations = new BetaVoiceAgentsLiveConversationsImpl(this); this.betaVoiceAgentsTelephonies = new BetaVoiceAgentsTelephoniesImpl(this); this.betaMemoryStores = new BetaMemoryStoresImpl(this); this.betaAgents = new BetaAgentsImpl(this); diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsServicePollUtils.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsServicePollUtils.java index dd9a4d7513cf9..1a9e66608c4d6 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsServicePollUtils.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/AgentsServicePollUtils.java @@ -4,9 +4,17 @@ package com.azure.ai.agents.implementation; import com.azure.ai.agents.models.MemoryStoreUpdateStatus; +import com.azure.core.exception.AzureException; +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; import com.azure.core.util.BinaryData; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.polling.LongRunningOperationStatus; import com.azure.core.util.polling.PollResponse; +import com.azure.core.util.polling.PollingContext; import com.azure.core.util.serializer.TypeReference; import java.util.Map; @@ -20,6 +28,10 @@ *

This class is package-private; it is not part of the public API.

*/ final class AgentsServicePollUtils { + private static final ClientLogger LOGGER = new ClientLogger(AgentsServicePollUtils.class); + private static final HttpHeaderName OPERATION_ID = HttpHeaderName.fromString("Operation-Id"); + private static final String CAMPAIGN_OPERATION_ID = "campaignOperationId"; + private static final TypeReference> MAP_TYPE_REFERENCE = new TypeReference>() { }; @@ -39,6 +51,72 @@ static String getOptimizationPollingUrl(Object initialResponse, String endpoint) return endpoint + (endpoint.endsWith("/") ? "" : "/") + "agent_optimization_jobs/" + jobId; } + static boolean canPollCampaign(Response response) { + int statusCode = response.getStatusCode(); + return statusCode == 200 + || statusCode == 201 + || statusCode == 202 + || (statusCode == 204 && response.getRequest().getHttpMethod() == HttpMethod.DELETE); + } + + static boolean initializeCampaignPollingContext(Response response, PollingContext pollingContext) { + HttpMethod method = response.getRequest().getHttpMethod(); + pollingContext.setData(PollingUtils.HTTP_METHOD, method.name()); + if (method == HttpMethod.DELETE && response.getStatusCode() == 204) { + return true; + } + int statusCode = response.getStatusCode(); + if (statusCode != 200 && statusCode != 201 && statusCode != 202) { + throw LOGGER.logExceptionAsError( + new AzureException("Campaign operation failed with HTTP status " + statusCode + ".")); + } + String pollingUrl = response.getHeaders().getValue(PollingUtils.OPERATION_LOCATION_HEADER); + if (pollingUrl == null || pollingUrl.isEmpty()) { + throw LOGGER.logExceptionAsError( + new IllegalStateException("Campaign operation response is missing Operation-Location.")); + } + if (method != HttpMethod.DELETE) { + String operationId = response.getHeaders().getValue(OPERATION_ID); + if (operationId == null || operationId.isEmpty()) { + throw LOGGER.logExceptionAsError( + new IllegalStateException("Campaign operation response is missing Operation-Id.")); + } + pollingContext.setData(CAMPAIGN_OPERATION_ID, operationId); + } + return false; + } + + static boolean isCompletedCampaignDeletion(PollingContext pollingContext) { + LongRunningOperationStatus status = pollingContext.getLatestResponse().getStatus(); + if (status == LongRunningOperationStatus.FAILED) { + throw LOGGER.logExceptionAsError(new AzureException("Long running operation failed.")); + } else if (status == LongRunningOperationStatus.USER_CANCELLED) { + throw LOGGER.logExceptionAsError(new AzureException("Long running operation cancelled.")); + } else if (status != LongRunningOperationStatus.SUCCESSFULLY_COMPLETED) { + throw LOGGER + .logExceptionAsError(new IllegalStateException("Campaign operation has not completed successfully.")); + } + return HttpMethod.DELETE.name().equals(pollingContext.getData(PollingUtils.HTTP_METHOD)); + } + + static RequestOptions getCampaignFinalRequestOptions(PollingContext pollingContext, Context context) { + String operationId = pollingContext.getData(CAMPAIGN_OPERATION_ID); + if (operationId == null || operationId.isEmpty()) { + throw LOGGER.logExceptionAsError( + new IllegalStateException("Campaign polling context is missing the original Operation-Id.")); + } + return new RequestOptions().setContext(context).addQueryParam("operation_id", operationId); + } + + static BinaryData getCampaignResponseBody(Response response) { + BinaryData body = response.getValue(); + if (body == null || (body.getLength() != null && body.getLength() == 0)) { + throw LOGGER + .logExceptionAsError(new IllegalStateException("Campaign final GET did not contain a response body.")); + } + return body; + } + /** * Remaps a {@link PollResponse} whose status may contain a custom service terminal state * ({@code "completed"}, {@code "superseded"}) that the base {@code OperationResourcePollingStrategy} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java index 2e27f33269546..bcb9ffe2f1226 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java @@ -1110,7 +1110,7 @@ public Response deleteAgentConversationWithResponse(String agentName, Stri * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1148,7 +1148,6 @@ public Response deleteAgentConversationWithResponse(String agentName, Stri * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1226,7 +1225,7 @@ private Mono> listAgentConversationResponsesSinglePage * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1264,7 +1263,6 @@ private Mono> listAgentConversationResponsesSinglePage * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1364,7 +1362,7 @@ public PagedFlux listAgentConversationResponsesAsync(String initialC * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1402,7 +1400,6 @@ public PagedFlux listAgentConversationResponsesAsync(String initialC * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1478,7 +1475,7 @@ private PagedResponse listAgentConversationResponsesSinglePage(Strin * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1516,7 +1513,6 @@ private PagedResponse listAgentConversationResponsesSinglePage(Strin * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1595,7 +1591,7 @@ public PagedIterable listAgentConversationResponses(String initialCo * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1633,7 +1629,6 @@ public PagedIterable listAgentConversationResponses(String initialCo * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1691,7 +1686,7 @@ public Mono> getAgentConversationResponseWithResponseAsync( * } * output (Optional): [ * (Optional){ - * type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) + * type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required) * } * ] * metadata (Optional): { @@ -1729,7 +1724,6 @@ public Mono> getAgentConversationResponseWithResponseAsync( * voice_type: String(openai/azure-standard/azure-custom/azure-personal/avatar-voice-sync/azure-realtime-native) (Optional) * voice_locale: String (Optional) * format (Optional): { - * type: String(audio/pcm/audio/pcmu/audio/pcma) (Required) * } * } * } @@ -1793,7 +1787,7 @@ public Response getAgentConversationResponseWithResponse(String agen *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -1853,7 +1847,7 @@ private Mono> listAgentConversationResponseItemsSingle *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -1936,7 +1930,7 @@ public PagedFlux listAgentConversationResponseItemsAsync(String init *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -1994,7 +1988,7 @@ private PagedResponse listAgentConversationResponseItemsSinglePage(S *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2076,7 +2070,7 @@ public PagedIterable listAgentConversationResponseItems(String initi *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2133,7 +2127,7 @@ private Mono> listAgentConversationItemsSinglePageAsyn *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2212,7 +2206,7 @@ public PagedFlux listAgentConversationItemsAsync(String initialConti *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2267,7 +2261,7 @@ private PagedResponse listAgentConversationItemsSinglePage(String ag *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2328,7 +2322,7 @@ public PagedIterable listAgentConversationItems(String initialContin *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2367,7 +2361,7 @@ public Mono> getAgentConversationItemWithResponseAsync(Stri *
      * {@code
      * {
-     *     type: String(function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
+     *     type: String(system_tool/function_call/function_call_output/mcp_approval_response/mcp_list_tools/mcp_call/mcp_approval_request/message) (Required)
      * }
      * }
      * 
@@ -2757,8 +2751,8 @@ public Response downloadAgentConversationGeneratedAudioItemWithRespo * sample_rate: int (Required) * channels: int (Required) * channel_layout (Required): { - * left: String (Required) - * right: String (Required) + * left: String(user/agent) (Required) + * right: String(user/agent) (Required) * } * duration_ms: long (Required) * blob_uri: String (Optional) @@ -2809,8 +2803,8 @@ public Mono> getAgentConversationAudioWithResponseAsync(Str * sample_rate: int (Required) * channels: int (Required) * channel_layout (Required): { - * left: String (Required) - * right: String (Required) + * left: String(user/agent) (Required) + * right: String(user/agent) (Required) * } * duration_ms: long (Required) * blob_uri: String (Optional) diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsLiveConversationsImpl.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsLiveConversationsImpl.java new file mode 100644 index 0000000000000..61292e2e055b3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsLiveConversationsImpl.java @@ -0,0 +1,1508 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.implementation; + +import com.azure.ai.agents.AgentsServiceVersion; +import com.azure.core.annotation.Delete; +import com.azure.core.annotation.ExpectedResponses; +import com.azure.core.annotation.Get; +import com.azure.core.annotation.HeaderParam; +import com.azure.core.annotation.Host; +import com.azure.core.annotation.HostParam; +import com.azure.core.annotation.PathParam; +import com.azure.core.annotation.QueryParam; +import com.azure.core.annotation.ReturnType; +import com.azure.core.annotation.ServiceInterface; +import com.azure.core.annotation.ServiceMethod; +import com.azure.core.annotation.UnexpectedResponseExceptionType; +import com.azure.core.exception.ClientAuthenticationException; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.exception.ResourceModifiedException; +import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.rest.PagedFlux; +import com.azure.core.http.rest.PagedIterable; +import com.azure.core.http.rest.PagedResponse; +import com.azure.core.http.rest.PagedResponseBase; +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.RestProxy; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Context; +import com.azure.core.util.FluxUtil; +import com.azure.core.util.UrlBuilder; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import reactor.core.publisher.Mono; + +/** + * An instance of this class provides access to all the operations defined in BetaVoiceAgentsLiveConversations. + */ +public final class BetaVoiceAgentsLiveConversationsImpl { + + /** + * The proxy service used to perform REST calls. + */ + private final BetaVoiceAgentsLiveConversationsService service; + + /** + * The service client containing this operation class. + */ + private final AgentsClientImpl client; + + /** + * Initializes an instance of BetaVoiceAgentsLiveConversationsImpl. + * + * @param client the instance of the service client containing this operation class. + */ + BetaVoiceAgentsLiveConversationsImpl(AgentsClientImpl client) { + this.service = RestProxy.create(BetaVoiceAgentsLiveConversationsService.class, client.getHttpPipeline(), + client.getSerializerAdapter()); + this.client = client; + } + + /** + * Gets Service version. + * + * @return the serviceVersion value. + */ + public AgentsServiceVersion getServiceVersion() { + return client.getServiceVersion(); + } + + /** + * The interface defining all the services for AgentsClientBetaVoiceAgentsLiveConversations to be used by the proxy + * service to perform REST calls. + */ + @Host("{endpoint}") + @ServiceInterface(name = "AgentsClientBetaVoiceAgentsLiveConversations") + public interface BetaVoiceAgentsLiveConversationsService { + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> listAgentConversations(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response listAgentConversationsSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getAgentConversation(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getAgentConversationSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}") + @ExpectedResponses({ 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> deleteAgentConversation(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}") + @ExpectedResponses({ 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response deleteAgentConversationSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> listAgentConversationItems(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response listAgentConversationItemsSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getAgentConversationItem(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getAgentConversationItemSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}/audio") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getAgentConversationAudioItem(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}/audio") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getAgentConversationAudioItemSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}/audio/content") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> downloadAgentConversationAudioItem(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/items/{item_id}/audio/content") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response downloadAgentConversationAudioItemSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @PathParam("item_id") String itemId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/audio") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getAgentConversationAudio(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/audio") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getAgentConversationAudioSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/audio/content") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> downloadAgentConversationAudio(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/endpoint/protocols/voice/live/conversations/{conversation_id}/audio/content") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response downloadAgentConversationAudioSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("conversation_id") String conversationId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items along with {@link PagedResponse} on successful completion + * of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> listAgentConversationsSinglePageAsync(String agentName, + RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.listAgentConversations(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null)); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationsAsync(String agentName, RequestOptions requestOptions) { + return listAgentConversationsAsync(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationsAsync(String initialContinuationToken, String agentName, + RequestOptions requestOptions) { + return new PagedFlux<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listAgentConversationsSinglePageAsync(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listAgentConversationsSinglePageAsync(agentName, requestOptionsLocal); + }); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private PagedResponse listAgentConversationsSinglePage(String agentName, + RequestOptions requestOptions) { + final String accept = "application/json"; + Response res = service.listAgentConversationsSync(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null); + } + + /** + * List Live voice agent conversations + * + * Lists stored Live conversations for this agent, including sessions stored via an override. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversations(String agentName, RequestOptions requestOptions) { + return listAgentConversations(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversations(String initialContinuationToken, String agentName, + RequestOptions requestOptions) { + return new PagedIterable<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listAgentConversationsSinglePage(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listAgentConversationsSinglePage(agentName, requestOptionsLocal); + }); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationWithResponseAsync(String agentName, String conversationId, + RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.getAgentConversation(this.client.getEndpoint(), agentName, + conversationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately. Returns 404 if absent or not stored. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     object: String (Required)
+     *     status: String(in_progress/completed/failed) (Required)
+     *     created_at: long (Required)
+     *     completed_at: Long (Optional)
+     *     metadata (Optional): {
+     *         String: String (Required)
+     *     }
+     *     last_error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     usage (Optional): {
+     *         seconds: double (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation + * + * Gets a stored Live conversation; fetch items separately along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getAgentConversationSync(this.client.getEndpoint(), agentName, conversationId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteAgentConversationWithResponseAsync(String agentName, String conversationId, + RequestOptions requestOptions) { + return FluxUtil.withContext(context -> service.deleteAgentConversation(this.client.getEndpoint(), agentName, + conversationId, this.client.getServiceVersion().getVersion(), requestOptions, context)); + } + + /** + * Delete a Live voice agent conversation + * + * Deletes the stored conversation and its items/audio, without closing the Live session. + * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteAgentConversationWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + return service.deleteAgentConversationSync(this.client.getEndpoint(), agentName, conversationId, + this.client.getServiceVersion().getVersion(), requestOptions, Context.NONE); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items along with {@link PagedResponse} on successful completion + * of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> listAgentConversationItemsSinglePageAsync(String agentName, + String conversationId, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.listAgentConversationItems(this.client.getEndpoint(), agentName, + conversationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null)); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationItemsAsync(String agentName, String conversationId, + RequestOptions requestOptions) { + return listAgentConversationItemsAsync(null, agentName, conversationId, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAgentConversationItemsAsync(String initialContinuationToken, String agentName, + String conversationId, RequestOptions requestOptions) { + return new PagedFlux<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listAgentConversationItemsSinglePageAsync(agentName, conversationId, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listAgentConversationItemsSinglePageAsync(agentName, conversationId, requestOptionsLocal); + }); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private PagedResponse listAgentConversationItemsSinglePage(String agentName, String conversationId, + RequestOptions requestOptions) { + final String accept = "application/json"; + Response res = service.listAgentConversationItemsSync(this.client.getEndpoint(), agentName, + conversationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null); + } + + /** + * List items in a Live voice agent conversation + * + * Lists stored speech and delegation items in order; cursors use item IDs. Returns 404 if the conversation is + * absent or not stored. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversationItems(String agentName, String conversationId, + RequestOptions requestOptions) { + return listAgentConversationItems(null, agentName, conversationId, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listAgentConversationItems(String initialContinuationToken, String agentName, + String conversationId, RequestOptions requestOptions) { + return new PagedIterable<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listAgentConversationItemsSinglePage(agentName, conversationId, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listAgentConversationItemsSinglePage(agentName, conversationId, requestOptionsLocal); + }); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationItemWithResponseAsync(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.getAgentConversationItem(this.client.getEndpoint(), agentName, + conversationId, itemId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a Live voice agent conversation item + * + * Gets a stored item by ID. Returns 404 if the item or conversation is absent. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     type: String(input/output/delegation) (Required)
+     *     id: String (Required)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live voice agent conversation item + * + * Gets a stored item by ID along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getAgentConversationItemSync(this.client.getEndpoint(), agentName, conversationId, itemId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     item_id: String (Required)
+     *     role: String(user/agent) (Optional)
+     *     format: String(wav) (Optional)
+     *     codec: String(pcm16/pcmu/pcma) (Optional)
+     *     sample_rate: Integer (Optional)
+     *     channels: Integer (Optional)
+     *     start_offset_ms: Long (Optional)
+     *     duration_ms: Long (Optional)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationAudioItemWithResponseAsync(String agentName, + String conversationId, String itemId, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.getAgentConversationAudioItem(this.client.getEndpoint(), agentName, + conversationId, itemId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata. BYOS uses unsigned blob_uri. Returns 404 for missing audio, conversations + * not stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     item_id: String (Required)
+     *     role: String(user/agent) (Optional)
+     *     format: String(wav) (Optional)
+     *     codec: String(pcm16/pcmu/pcma) (Optional)
+     *     sample_rate: Integer (Optional)
+     *     channels: Integer (Optional)
+     *     start_offset_ms: Long (Optional)
+     *     duration_ms: Long (Optional)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation item's audio metadata + * + * Gets captured speech-audio metadata along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationAudioItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getAgentConversationAudioItemSync(this.client.getEndpoint(), agentName, conversationId, itemId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> downloadAgentConversationAudioItemWithResponseAsync(String agentName, + String conversationId, String itemId, RequestOptions requestOptions) { + final String accept = "audio/wav"; + return FluxUtil + .withContext(context -> service.downloadAgentConversationAudioItem(this.client.getEndpoint(), agentName, + conversationId, itemId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Stream a Live conversation item's audio + * + * Streams captured speech as WAV. BYOS returns 409; use blob_uri. Returns 404 for missing audio, conversations not + * stored, or delegation items. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param itemId The id returned on the persisted item. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response downloadAgentConversationAudioItemWithResponse(String agentName, String conversationId, + String itemId, RequestOptions requestOptions) { + final String accept = "audio/wav"; + return service.downloadAgentConversationAudioItemSync(this.client.getEndpoint(), agentName, conversationId, + itemId, this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     format: String(wav) (Required)
+     *     sample_rate: int (Required)
+     *     channels: int (Required)
+     *     channel_layout (Required): {
+     *         left: String(user/agent) (Required)
+     *         right: String(user/agent) (Required)
+     *     }
+     *     duration_ms: long (Required)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right) along with {@link Response} on successful + * completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getAgentConversationAudioWithResponseAsync(String agentName, + String conversationId, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.getAgentConversationAudio(this.client.getEndpoint(), agentName, + conversationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right). BYOS uses unsigned blob_uri. Returns 404 for + * no audio, or 409 recording_not_ready/recording_unavailable for pending/failed finalization; pending responses may + * include Retry-After. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     conversation_id: String (Required)
+     *     format: String(wav) (Required)
+     *     sample_rate: int (Required)
+     *     channels: int (Required)
+     *     channel_layout (Required): {
+     *         left: String(user/agent) (Required)
+     *         right: String(user/agent) (Required)
+     *     }
+     *     duration_ms: long (Required)
+     *     blob_uri: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a Live conversation's merged recording metadata + * + * Gets merged stereo recording metadata (user left, assistant right) along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getAgentConversationAudioWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getAgentConversationAudioSync(this.client.getEndpoint(), agentName, conversationId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> downloadAgentConversationAudioWithResponseAsync(String agentName, + String conversationId, RequestOptions requestOptions) { + final String accept = "audio/wav"; + return FluxUtil.withContext(context -> service.downloadAgentConversationAudio(this.client.getEndpoint(), + agentName, conversationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Stream a Live conversation's merged recording + * + * Streams the merged stereo WAV. BYOS returns 409; use blob_uri. Returns 404 for no audio, or 409 + * recording_not_ready/recording_unavailable for pending/failed finalization. + *

Response Body Schema

+ * + *
+     * {@code
+     * BinaryData
+     * }
+     * 
+ * + * @param agentName The name of the Live voice agent. + * @param conversationId The Foundry conversation ID returned in session.started.conversation_id. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response body along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response downloadAgentConversationAudioWithResponse(String agentName, String conversationId, + RequestOptions requestOptions) { + final String accept = "audio/wav"; + return service.downloadAgentConversationAudioSync(this.client.getEndpoint(), agentName, conversationId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + private List getValues(BinaryData binaryData, String... path) { + try { + Object value = binaryData.toObject(Map.class); + for (String segment : path) { + value = ((Map) value).get(segment); + } + List values = (List) value; + return values.stream().map(BinaryData::fromObject).collect(Collectors.toList()); + } catch (RuntimeException e) { + return null; + } + } + + private String getNextLink(BinaryData binaryData, String... path) { + try { + Object value = binaryData.toObject(Map.class); + if (Boolean.FALSE.equals(((Map) value).get("has_more"))) { + return null; + } + for (String segment : path) { + value = ((Map) value).get(segment); + } + return (String) value; + } catch (RuntimeException e) { + return null; + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java index d2a19abea17d4..a40f81543c2d4 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java @@ -4,6 +4,8 @@ package com.azure.ai.agents.implementation; import com.azure.ai.agents.AgentsServiceVersion; +import com.azure.ai.agents.models.TelephonyCampaign; +import com.azure.ai.agents.models.TelephonyCampaignOperation; import com.azure.core.annotation.BodyParam; import com.azure.core.annotation.Delete; import com.azure.core.annotation.ExpectedResponses; @@ -38,6 +40,11 @@ import com.azure.core.util.DateTimeRfc1123; import com.azure.core.util.FluxUtil; import com.azure.core.util.UrlBuilder; +import com.azure.core.util.polling.PollerFlux; +import com.azure.core.util.polling.PollingStrategyOptions; +import com.azure.core.util.polling.SyncPoller; +import com.azure.core.util.serializer.TypeReference; +import java.time.Duration; import java.time.OffsetDateTime; import java.util.List; import java.util.Map; @@ -96,7 +103,7 @@ public interface BetaVoiceAgentsTelephoniesService { Mono> createTelephonyBinding(@HostParam("endpoint") String endpoint, @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, @HeaderParam("Accept") String accept, - @BodyParam("application/json") BinaryData telephonyBinding, RequestOptions requestOptions, Context context); + @BodyParam("application/json") BinaryData binding, RequestOptions requestOptions, Context context); @Post("/agents/{agent_name}/telephony/bindings") @ExpectedResponses({ 201 }) @@ -107,7 +114,7 @@ Mono> createTelephonyBinding(@HostParam("endpoint") String Response createTelephonyBindingSync(@HostParam("endpoint") String endpoint, @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, @HeaderParam("Accept") String accept, - @BodyParam("application/json") BinaryData telephonyBinding, RequestOptions requestOptions, Context context); + @BodyParam("application/json") BinaryData binding, RequestOptions requestOptions, Context context); @Get("/agents/{agent_name}/telephony/bindings") @ExpectedResponses({ 200 }) @@ -333,7 +340,7 @@ Response replaceTelephonyTransferTargetsSync(@HostParam("endpoint") @BodyParam("application/json") BinaryData replaceTelephonyTransferTargetsRequest, RequestOptions requestOptions, Context context); - @Post("/agents/{agent_name}/telephony/call_jobs") + @Post("/agents/{agent_name}/telephony_call_jobs") @ExpectedResponses({ 202 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -342,10 +349,10 @@ Response replaceTelephonyTransferTargetsSync(@HostParam("endpoint") Mono> createTelephonyCallJob(@HostParam("endpoint") String endpoint, @PathParam("agent_name") String agentName, @HeaderParam("Idempotency-Key") String idempotencyKey, @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, - @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData body, + @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData job, RequestOptions requestOptions, Context context); - @Post("/agents/{agent_name}/telephony/call_jobs") + @Post("/agents/{agent_name}/telephony_call_jobs") @ExpectedResponses({ 202 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -354,10 +361,50 @@ Mono> createTelephonyCallJob(@HostParam("endpoint") String Response createTelephonyCallJobSync(@HostParam("endpoint") String endpoint, @PathParam("agent_name") String agentName, @HeaderParam("Idempotency-Key") String idempotencyKey, @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, - @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData body, + @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData job, RequestOptions requestOptions, Context context); - @Get("/agents/{agent_name}/telephony/call_jobs/{call_job_id}") + @Get("/agents/{agent_name}/telephony_call_jobs") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> listTelephonyCallJobs(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_call_jobs") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response listTelephonyCallJobsSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/telephony_call_jobs/{call_job_id}") + @ExpectedResponses({ 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> deleteTelephonyCallJob(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("call_job_id") String callJobId, + @QueryParam("api-version") String apiVersion, RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/telephony_call_jobs/{call_job_id}") + @ExpectedResponses({ 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response deleteTelephonyCallJobSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("call_job_id") String callJobId, + @QueryParam("api-version") String apiVersion, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_call_jobs/{call_job_id}") @ExpectedResponses({ 200 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -368,7 +415,7 @@ Mono> getTelephonyCallJob(@HostParam("endpoint") String end @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); - @Get("/agents/{agent_name}/telephony/call_jobs/{call_job_id}") + @Get("/agents/{agent_name}/telephony_call_jobs/{call_job_id}") @ExpectedResponses({ 200 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -379,7 +426,7 @@ Response getTelephonyCallJobSync(@HostParam("endpoint") String endpo @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); - @Post("/agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel") + @Post("/agents/{agent_name}/telephony_call_jobs/{call_job_id}:cancel") @ExpectedResponses({ 200, 202 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -390,7 +437,7 @@ Mono> cancelTelephonyCallJob(@HostParam("endpoint") String @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); - @Post("/agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel") + @Post("/agents/{agent_name}/telephony_call_jobs/{call_job_id}:cancel") @ExpectedResponses({ 200, 202 }) @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) @@ -400,6 +447,160 @@ Response cancelTelephonyCallJobSync(@HostParam("endpoint") String en @PathParam("agent_name") String agentName, @PathParam("call_job_id") String callJobId, @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Put("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 200, 201 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> createCampaign(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, + @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData campaign, + RequestOptions requestOptions, Context context); + + @Put("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 200, 201 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response createCampaignSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Content-Type") String contentType, + @HeaderParam("Accept") String accept, @BodyParam("application/json") BinaryData campaign, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getCampaign(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getCampaignSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> listCampaigns(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response listCampaignsSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Post("/agents/{agent_name}/telephony_campaigns/{campaign_name}:cancel") + @ExpectedResponses({ 202 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> cancelCampaign(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Post("/agents/{agent_name}/telephony_campaigns/{campaign_name}:cancel") + @ExpectedResponses({ 202 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response cancelCampaignSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 202, 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> deleteCampaign(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, + RequestOptions requestOptions, Context context); + + @Delete("/agents/{agent_name}/telephony_campaigns/{campaign_name}") + @ExpectedResponses({ 202, 204 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response deleteCampaignSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @HeaderParam("If-Match") String ifMatch, @QueryParam("api-version") String apiVersion, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}/validation_errors") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> listCampaignValidationErrors(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}/validation_errors") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response listCampaignValidationErrorsSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}/operations/{operation_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Mono> getCampaignOperation(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @PathParam("operation_id") String operationId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + + @Get("/agents/{agent_name}/telephony_campaigns/{campaign_name}/operations/{operation_id}") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 }) + @UnexpectedResponseExceptionType(value = ResourceNotFoundException.class, code = { 404 }) + @UnexpectedResponseExceptionType(value = ResourceModifiedException.class, code = { 409 }) + @UnexpectedResponseExceptionType(HttpResponseException.class) + Response getCampaignOperationSync(@HostParam("endpoint") String endpoint, + @PathParam("agent_name") String agentName, @PathParam("campaign_name") String campaignName, + @PathParam("operation_id") String operationId, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); } /** @@ -420,9 +621,11 @@ Response cancelTelephonyCallJobSync(@HostParam("endpoint") String en *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
+     *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
+     *     incoming_call_url: String (Required)
      * }
      * }
      * 
@@ -432,11 +635,10 @@ Response cancelTelephonyCallJobSync(@HostParam("endpoint") String en *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -451,7 +653,7 @@ Response cancelTelephonyCallJobSync(@HostParam("endpoint") String en
      * 
      *
      * @param agentName The name of the voice agent that owns the binding.
-     * @param telephonyBinding The provider-specific binding to create.
+     * @param binding The provider-specific binding to create.
      * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
      * @throws HttpResponseException thrown if the request is rejected by server.
      * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
@@ -461,8 +663,8 @@ Response cancelTelephonyCallJobSync(@HostParam("endpoint") String en
      * {@link Mono}.
      */
     @ServiceMethod(returns = ReturnType.SINGLE)
-    public Mono> createTelephonyBindingWithResponseAsync(String agentName,
-        BinaryData telephonyBinding, RequestOptions requestOptions) {
+    public Mono> createTelephonyBindingWithResponseAsync(String agentName, BinaryData binding,
+        RequestOptions requestOptions) {
         final String contentType = "application/json";
         final String accept = "application/json";
         RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions;
@@ -480,8 +682,7 @@ public Mono> createTelephonyBindingWithResponseAsync(String
             }
         });
         return FluxUtil.withContext(context -> service.createTelephonyBinding(this.client.getEndpoint(), agentName,
-            this.client.getServiceVersion().getVersion(), contentType, accept, telephonyBinding, requestOptionsLocal,
-            context));
+            this.client.getServiceVersion().getVersion(), contentType, accept, binding, requestOptionsLocal, context));
     }
 
     /**
@@ -502,9 +703,11 @@ public Mono> createTelephonyBindingWithResponseAsync(String
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
+     *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
+     *     incoming_call_url: String (Required)
      * }
      * }
      * 
@@ -514,11 +717,10 @@ public Mono> createTelephonyBindingWithResponseAsync(String *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -533,7 +735,7 @@ public Mono> createTelephonyBindingWithResponseAsync(String
      * 
      *
      * @param agentName The name of the voice agent that owns the binding.
-     * @param telephonyBinding The provider-specific binding to create.
+     * @param binding The provider-specific binding to create.
      * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
      * @throws HttpResponseException thrown if the request is rejected by server.
      * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
@@ -542,7 +744,7 @@ public Mono> createTelephonyBindingWithResponseAsync(String
      * @return a telephony binding owned by a voice agent along with {@link Response}.
      */
     @ServiceMethod(returns = ReturnType.SINGLE)
-    public Response createTelephonyBindingWithResponse(String agentName, BinaryData telephonyBinding,
+    public Response createTelephonyBindingWithResponse(String agentName, BinaryData binding,
         RequestOptions requestOptions) {
         final String contentType = "application/json";
         final String accept = "application/json";
@@ -561,7 +763,7 @@ public Response createTelephonyBindingWithResponse(String agentName,
             }
         });
         return service.createTelephonyBindingSync(this.client.getEndpoint(), agentName,
-            this.client.getServiceVersion().getVersion(), contentType, accept, telephonyBinding, requestOptionsLocal,
+            this.client.getServiceVersion().getVersion(), contentType, accept, binding, requestOptionsLocal,
             Context.NONE);
     }
 
@@ -574,9 +776,7 @@ public Response createTelephonyBindingWithResponse(String agentName,
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -598,11 +798,10 @@ public Response createTelephonyBindingWithResponse(String agentName,
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -638,9 +837,7 @@ private Mono> listTelephonyBindingsSinglePageAsync(Str
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -662,11 +859,10 @@ private Mono> listTelephonyBindingsSinglePageAsync(Str
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -723,9 +919,7 @@ public PagedFlux listTelephonyBindingsAsync(String initialContinuati
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -747,11 +941,10 @@ public PagedFlux listTelephonyBindingsAsync(String initialContinuati
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -784,9 +977,7 @@ private PagedResponse listTelephonyBindingsSinglePage(String agentNa
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters bindings by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
-     * statusStringNoFilters bindings by lifecycle status. Allowed values: "active",
-     * "suspended".
+     * "teams_phone_extensibility", "twilio", "sip".
      * limitIntegerNoA limit on the number of objects to be returned. Limit can range
      * between 1 and 100, and the
      * default is 20.
@@ -808,11 +999,10 @@ private PagedResponse listTelephonyBindingsSinglePage(String agentNa
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      *     etag: String (Required)
      * }
@@ -869,11 +1059,10 @@ public PagedIterable listTelephonyBindings(String initialContinuatio
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -916,11 +1105,10 @@ public Mono> getTelephonyBindingWithResponseAsync(String ag
      * 
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -962,10 +1150,12 @@ public Response getTelephonyBindingWithResponse(String agentName, St
      * 
      * {@code
      * {
-     *     status: String(active/suspended) (Optional)
      *     label: String (Optional)
      *     connection_name: String (Optional)
      *     phone_number: String (Optional)
+     *     allowed_calling_numbers (Optional): [
+     *         String (Optional)
+     *     ]
      * }
      * }
      * 
@@ -975,11 +1165,10 @@ public Response getTelephonyBindingWithResponse(String agentName, St *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -1025,10 +1214,12 @@ public Mono> updateTelephonyBindingWithResponseAsync(String
      * 
      * {@code
      * {
-     *     status: String(active/suspended) (Optional)
      *     label: String (Optional)
      *     connection_name: String (Optional)
      *     phone_number: String (Optional)
+     *     allowed_calling_numbers (Optional): [
+     *         String (Optional)
+     *     ]
      * }
      * }
      * 
@@ -1038,11 +1229,10 @@ public Mono> updateTelephonyBindingWithResponseAsync(String *
      * {@code
      * {
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     id: String (Required)
      *     connection_name: String (Required)
      *     label: String (Optional)
-     *     status: String(active/suspended) (Required)
      *     incoming_call_url: String (Required)
      * }
      * }
@@ -1132,7 +1322,7 @@ public Response deleteTelephonyBindingWithResponse(String agentName, Strin
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -1161,7 +1351,7 @@ public Response deleteTelephonyBindingWithResponse(String agentName, Strin
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1210,7 +1400,7 @@ private Mono> listTelephonyCallsSinglePageAsync(String
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -1239,7 +1429,7 @@ private Mono> listTelephonyCallsSinglePageAsync(String
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1309,7 +1499,7 @@ public PagedFlux listTelephonyCallsAsync(String initialContinuationT
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -1338,7 +1528,7 @@ public PagedFlux listTelephonyCallsAsync(String initialContinuationT
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1384,7 +1574,7 @@ private PagedResponse listTelephonyCallsSinglePage(String agentName,
      * Query Parameters
      * NameTypeRequiredDescription
      * providerStringNoFilters calls by provider. Allowed values:
-     * "teams_phone_extensibility", "twilio".
+     * "teams_phone_extensibility", "twilio", "sip".
      * statusStringNoFilters calls by lifecycle status. Allowed values:
      * "in_progress", "success", "failed".
      * started_afterOffsetDateTimeNoIncludes calls that started at or after this Unix
@@ -1413,7 +1603,7 @@ private PagedResponse listTelephonyCallsSinglePage(String agentName,
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1484,7 +1674,7 @@ public PagedIterable listTelephonyCalls(String initialContinuationTo
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1572,7 +1762,7 @@ public Mono> getTelephonyCallWithResponseAsync(String agent
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1669,7 +1859,7 @@ public Response getTelephonyCallWithResponse(String agentName, Strin
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1768,7 +1958,7 @@ public Mono> transferTelephonyCallWithResponseAsync(String
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1856,7 +2046,7 @@ public Response transferTelephonyCallWithResponse(String agentName,
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -1942,7 +2132,7 @@ public Mono> endTelephonyCallWithResponseAsync(String agent
      * {@code
      * {
      *     id: String (Required)
-     *     provider: String(teams_phone_extensibility/twilio) (Required)
+     *     provider: String(teams_phone_extensibility/twilio/sip) (Required)
      *     provider_call_id: String (Optional)
      *     caller_number: String (Optional)
      *     provider_number: String (Optional)
@@ -2031,7 +2221,8 @@ public Response endTelephonyCallWithResponse(String agentName, Strin
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2080,7 +2271,8 @@ public Mono> getTelephonyTransferTargetsWithResponseAsync(S
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2128,7 +2320,8 @@ public Response getTelephonyTransferTargetsWithResponse(String agent
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2146,7 +2339,8 @@ public Response getTelephonyTransferTargetsWithResponse(String agent
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2198,7 +2392,8 @@ public Mono> replaceTelephonyTransferTargetsWithResponseAsy
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2216,7 +2411,8 @@ public Mono> replaceTelephonyTransferTargetsWithResponseAsy
      *             name: String (Required)
      *             description: String (Required)
      *             destination (Required): {
-     *                 kind: String(pstn/teams/sip) (Required)
+     *                 type: String(phone_number/teams/sip) (Required)
+     *                 value: String (Required)
      *             }
      *         }
      *     ]
@@ -2256,18 +2452,18 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a
     /**
      * Create an outbound telephony call job
      *
-     * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes.
+     * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and
+     * its voice session.
      * 

Request Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2280,6 +2476,7 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a
      *         type: String(fixed_interval) (Required)
      *         max_attempts: Integer (Optional)
      *     }
+     *     source (Required): (recursive schema, see source above)
      * }
      * }
      * 
@@ -2290,11 +2487,10 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -2304,7 +2500,6 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -2323,6 +2518,8 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -2331,15 +2528,18 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -2350,29 +2550,29 @@ public Response replaceTelephonyTransferTargetsWithResponse(String a */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> createTelephonyCallJobWithResponseAsync(String agentName, String idempotencyKey, - BinaryData body, RequestOptions requestOptions) { + BinaryData job, RequestOptions requestOptions) { final String contentType = "application/json"; final String accept = "application/json"; return FluxUtil .withContext(context -> service.createTelephonyCallJob(this.client.getEndpoint(), agentName, idempotencyKey, - this.client.getServiceVersion().getVersion(), contentType, accept, body, requestOptions, context)); + this.client.getServiceVersion().getVersion(), contentType, accept, job, requestOptions, context)); } /** * Create an outbound telephony call job * - * Creates one durable direct outbound call job. The latest agent definition is resolved when each attempt executes. + * Creates one durable outbound CallJob. Each attempt pins the Agent endpoint's execution version for validation and + * its voice session. *

Request Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2385,6 +2585,7 @@ public Mono> createTelephonyCallJobWithResponseAsync(String
      *         type: String(fixed_interval) (Required)
      *         max_attempts: Integer (Optional)
      *     }
+     *     source (Required): (recursive schema, see source above)
      * }
      * }
      * 
@@ -2395,11 +2596,10 @@ public Mono> createTelephonyCallJobWithResponseAsync(String * {@code * { * destination (Required): { - * type: String(phone_number) (Required) + * type: String(phone_number/teams/sip) (Required) * value: String (Required) * } * connection_name: String (Required) - * source: String (Required) * purpose: String (Optional) * structured_inputs (Optional): { * String: BinaryData (Required) @@ -2409,7 +2609,6 @@ public Mono> createTelephonyCallJobWithResponseAsync(String * expires_at: Long (Optional) * } * id: String (Required) - * object: String (Required) * agent_name: String (Required) * status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required) * cancellation (Optional): { @@ -2428,6 +2627,8 @@ public Mono> createTelephonyCallJobWithResponseAsync(String * revision: long (Required) * created_at: long (Required) * updated_at: long (Required) + * source (Required): (recursive schema, see source above) + * campaign_name: String (Optional) * } * } *
@@ -2436,15 +2637,18 @@ public Mono> createTelephonyCallJobWithResponseAsync(String * * * - * - * - * + * + * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
* * @param agentName The name of the voice agent that executes the call. - * @param idempotencyKey A customer-generated idempotency key. Reusing it with an equivalent request returns the - * same call job. - * @param body The direct outbound call to create. + * @param idempotencyKey Customer retry key. Equivalent requests return the same job; retained keys for deleted jobs + * return 409 call_job_deleted, never redial. + * @param job The direct outbound call to create. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -2454,28 +2658,53 @@ public Mono> createTelephonyCallJobWithResponseAsync(String */ @ServiceMethod(returns = ReturnType.SINGLE) public Response createTelephonyCallJobWithResponse(String agentName, String idempotencyKey, - BinaryData body, RequestOptions requestOptions) { + BinaryData job, RequestOptions requestOptions) { final String contentType = "application/json"; final String accept = "application/json"; return service.createTelephonyCallJobSync(this.client.getEndpoint(), agentName, idempotencyKey, - this.client.getServiceVersion().getVersion(), contentType, accept, body, requestOptions, Context.NONE); + this.client.getServiceVersion().getVersion(), contentType, accept, job, requestOptions, Context.NONE); } /** - * Get an outbound telephony call job + * List outbound telephony call jobs * - * Retrieves a durable direct or campaign-created outbound call job. + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + *

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2485,7 +2714,6 @@ public Response createTelephonyCallJobWithResponse(String agentName,
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -2504,52 +2732,72 @@ public Response createTelephonyCallJobWithResponse(String agentName,
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
- * - *

Response Headers

- * - * - * - * - *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The owning voice agent. Authorization is applied before pagination. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @return an outbound telephony call job - * - * Retrieves a durable direct or campaign-created outbound call job along with {@link Response} on successful - * completion of {@link Mono}. + * @return the response data for a requested list of items along with {@link PagedResponse} on successful completion + * of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> getTelephonyCallJobWithResponseAsync(String agentName, String callJobId, + private Mono> listTelephonyCallJobsSinglePageAsync(String agentName, RequestOptions requestOptions) { final String accept = "application/json"; - return FluxUtil.withContext(context -> service.getTelephonyCallJob(this.client.getEndpoint(), agentName, - callJobId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + return FluxUtil + .withContext(context -> service.listTelephonyCallJobs(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null)); } /** - * Get an outbound telephony call job + * List outbound telephony call jobs * - * Retrieves a durable direct or campaign-created outbound call job. + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + *

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2559,7 +2807,6 @@ public Mono> getTelephonyCallJobWithResponseAsync(String ag
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -2578,51 +2825,315 @@ public Mono> getTelephonyCallJobWithResponseAsync(String ag
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
- * - *

Response Headers

- * - * - * - * - *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. + * @param agentName The owning voice agent. Authorization is applied before pagination. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @return an outbound telephony call job - * - * Retrieves a durable direct or campaign-created outbound call job along with {@link Response}. + * @return the response data for a requested list of items as paginated response with {@link PagedFlux}. */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Response getTelephonyCallJobWithResponse(String agentName, String callJobId, + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listTelephonyCallJobsAsync(String agentName, RequestOptions requestOptions) { + return listTelephonyCallJobsAsync(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listTelephonyCallJobsAsync(String initialContinuationToken, String agentName, RequestOptions requestOptions) { - final String accept = "application/json"; - return service.getTelephonyCallJobSync(this.client.getEndpoint(), agentName, callJobId, - this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedFlux<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listTelephonyCallJobsSinglePageAsync(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listTelephonyCallJobsSinglePageAsync(agentName, requestOptionsLocal); + }); } /** - * Cancel an outbound telephony call job + * List outbound telephony call jobs * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. - *

Response Body Schema

- * - *
-     * {@code
-     * {
-     *     destination (Required): {
-     *         type: String(phone_number) (Required)
-     *         value: String (Required)
+     * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors
+     * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor).
+     * 

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private PagedResponse listTelephonyCallJobsSinglePage(String agentName, RequestOptions requestOptions) { + final String accept = "application/json"; + Response res = service.listTelephonyCallJobsSync(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null); + } + + /** + * List outbound telephony call jobs + * + * Lists current direct/Campaign jobs, excluding deleted or superseded rounds. Pages are live. Campaign cursors + * survive boundary deletion/cancel, not replacement/name reuse (400 invalid_cursor). + *

Query Parameters

+ * + * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoA cursor for use in pagination. `after` 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 after=obj_foo in order to fetch the next page of the list.
beforeStringNoA 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.
statusStringNoOptional lifecycle filter. Allowed values: "accepted", + * "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", "cancellation_requested", + * "completed", "blocked", "expired", "failed", "cancelled".
campaign_nameStringNoCurrent Campaign round: 404 if absent, empty while + * deleting. Omit for direct and Campaign jobs. Replacement/name reuse invalidates cursors.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName The owning voice agent. Authorization is applied before pagination. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the response data for a requested list of items as paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listTelephonyCallJobs(String agentName, RequestOptions requestOptions) { + return listTelephonyCallJobs(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listTelephonyCallJobs(String initialContinuationToken, String agentName, + RequestOptions requestOptions) { + return new PagedIterable<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listTelephonyCallJobsSinglePage(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listTelephonyCallJobsSinglePage(agentName, requestOptionsLocal); + }); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteTelephonyCallJobWithResponseAsync(String agentName, String callJobId, + RequestOptions requestOptions) { + return FluxUtil.withContext(context -> service.deleteTelephonyCallJob(this.client.getEndpoint(), agentName, + callJobId, this.client.getServiceVersion().getVersion(), requestOptions, context)); + } + + /** + * Delete an outbound telephony call job + * + * Deletes a terminal, reconciled job (otherwise 409), without cancelling calls or removing Campaign outcomes/call + * history. Later GET returns 404; repeated DELETE returns 204. + * + * @param agentName The owning voice agent. + * @param callJobId The call-job identifier. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteTelephonyCallJobWithResponse(String agentName, String callJobId, + RequestOptions requestOptions) { + return service.deleteTelephonyCallJobSync(this.client.getEndpoint(), agentName, callJobId, + this.client.getServiceVersion().getVersion(), requestOptions, Context.NONE); + } + + /** + * Get an outbound telephony call job + * + * Retrieves a durable direct or campaign-created outbound call job. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2632,7 +3143,6 @@ public Response getTelephonyCallJobWithResponse(String agentName, St
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -2651,6 +3161,8 @@ public Response getTelephonyCallJobWithResponse(String agentName, St
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
@@ -2659,46 +3171,44 @@ public Response getTelephonyCallJobWithResponse(String agentName, St * * * - * - * - * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. - * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that - * read. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @return a durable direct or campaign-created outbound call intent along with {@link Response} on successful + * @return an outbound telephony call job + * + * Retrieves a durable direct or campaign-created outbound call job along with {@link Response} on successful * completion of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> cancelTelephonyCallJobWithResponseAsync(String agentName, String callJobId, - String ifMatch, RequestOptions requestOptions) { + public Mono> getTelephonyCallJobWithResponseAsync(String agentName, String callJobId, + RequestOptions requestOptions) { final String accept = "application/json"; - return FluxUtil.withContext(context -> service.cancelTelephonyCallJob(this.client.getEndpoint(), agentName, - callJobId, ifMatch, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + return FluxUtil.withContext(context -> service.getTelephonyCallJob(this.client.getEndpoint(), agentName, + callJobId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); } /** - * Cancel an outbound telephony call job + * Get an outbound telephony call job * - * Requests cancellation of a durable outbound call job. A connected call is allowed to finish. + * Retrieves a durable direct or campaign-created outbound call job. *

Response Body Schema

* *
      * {@code
      * {
      *     destination (Required): {
-     *         type: String(phone_number) (Required)
+     *         type: String(phone_number/teams/sip) (Required)
      *         value: String (Required)
      *     }
      *     connection_name: String (Required)
-     *     source: String (Required)
      *     purpose: String (Optional)
      *     structured_inputs (Optional): {
      *         String: BinaryData (Required)
@@ -2708,7 +3218,6 @@ public Mono> cancelTelephonyCallJobWithResponseAsync(String
      *         expires_at: Long (Optional)
      *     }
      *     id: String (Required)
-     *     object: String (Required)
      *     agent_name: String (Required)
      *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
      *     cancellation (Optional): {
@@ -2727,6 +3236,8 @@ public Mono> cancelTelephonyCallJobWithResponseAsync(String
      *     revision: long (Required)
      *     created_at: long (Required)
      *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
      * }
      * }
      * 
@@ -2735,27 +3246,3250 @@ public Mono> cancelTelephonyCallJobWithResponseAsync(String * * * - * - * - * + * *
Response Headers
NameTypeDescription
ETagStringThe ETag response header.
LocationStringThe Location response header.
Retry-AfterDurationThe Retry-After response header.
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
* - * @param agentName The agentName parameter. - * @param callJobId The callJobId parameter. - * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that - * read. + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to retrieve. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. - * @return a durable direct or campaign-created outbound call intent along with {@link Response}. + * @return an outbound telephony call job + * + * Retrieves a durable direct or campaign-created outbound call job along with {@link Response}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Response cancelTelephonyCallJobWithResponse(String agentName, String callJobId, String ifMatch, + public Response getTelephonyCallJobWithResponse(String agentName, String callJobId, RequestOptions requestOptions) { final String accept = "application/json"; - return service.cancelTelephonyCallJobSync(this.client.getEndpoint(), agentName, callJobId, ifMatch, + return service.getTelephonyCallJobSync(this.client.getEndpoint(), agentName, callJobId, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Cancel an outbound telephony call job + * + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + * + * + *
Response Headers
NameTypeDescription
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
+ * + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. + * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that + * read. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a durable direct or campaign-created outbound call intent along with {@link Response} on successful + * completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> cancelTelephonyCallJobWithResponseAsync(String agentName, String callJobId, + String ifMatch, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.cancelTelephonyCallJob(this.client.getEndpoint(), agentName, + callJobId, ifMatch, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Cancel an outbound telephony call job + * + * Cancels future attempts using If-Match; completion may be asynchronous. New cancellation after connection returns + * 409 and lets the active call finish. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     destination (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     connection_name: String (Required)
+     *     purpose: String (Optional)
+     *     structured_inputs (Optional): {
+     *         String: BinaryData (Required)
+     *     }
+     *     schedule (Optional): {
+     *         not_before: Long (Optional)
+     *         expires_at: Long (Optional)
+     *     }
+     *     id: String (Required)
+     *     agent_name: String (Required)
+     *     status: String(accepted/waiting_for_schedule/queued/dispatching/in_progress/waiting_for_retry/cancellation_requested/completed/blocked/expired/failed/cancelled) (Required)
+     *     cancellation (Optional): {
+     *         requested_by: String (Required)
+     *         mode: String (Required)
+     *         requested_at: long (Required)
+     *         revision: long (Required)
+     *     }
+     *     retry_policy (Required): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     attempt_count: int (Required)
+     *     next_attempt_at: Long (Optional)
+     *     terminal_reason: String(no_answer/no_answer_timeout/answer_failed/bridge_cancelled/bridge_failed/voice_session_configuration_invalid/connection_project_mismatch/outbound_connection_changed/outbound_connection_unavailable/telephony_binding_invalid/telephony_binding_not_found/telephony_binding_inactive/telephony_binding_changed/campaign_not_found/campaign_cancelled/campaign_completed/campaign_failed/origination_fence_not_recorded/origination_reconciliation_timeout/cancellation_reconciliation_timeout/provider_callback_timeout_cancellation_reconciliation_timeout) (Optional)
+     *     revision: long (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     source (Required): (recursive schema, see source above)
+     *     campaign_name: String (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + * + * + *
Response Headers
NameTypeDescription
ETagStringThe current call-job entity tag. Send it in If-Match when requesting + * cancellation.
LocationStringThe URI for reading the accepted call-job resource and its execution + * status.
Retry-AfterDurationSuggested delay in seconds before reading the call-job resource + * again.
+ * + * @param agentName The name of the voice agent that owns the call job. + * @param callJobId The service-generated identifier of the call job to cancel. + * @param ifMatch The entity tag returned by the latest read. The request fails if the resource changed since that + * read. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a durable direct or campaign-created outbound call intent along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response cancelTelephonyCallJobWithResponse(String agentName, String callJobId, String ifMatch, + RequestOptions requestOptions) { + final String accept = "application/json"; + return service.cancelTelephonyCallJobSync(this.client.getEndpoint(), agentName, callJobId, ifMatch, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return agent-owned outbound call Campaign along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> createCampaignWithResponseAsync(String agentName, String campaignName, + BinaryData campaign, RequestOptions requestOptions) { + final String contentType = "application/json"; + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.createCampaign(this.client.getEndpoint(), agentName, campaignName, + this.client.getServiceVersion().getVersion(), contentType, accept, campaign, requestOptions, context)); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return agent-owned outbound call Campaign along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Response createCampaignWithResponse(String agentName, String campaignName, BinaryData campaign, + RequestOptions requestOptions) { + final String contentType = "application/json"; + final String accept = "application/json"; + return service.createCampaignSync(this.client.getEndpoint(), agentName, campaignName, + this.client.getServiceVersion().getVersion(), contentType, accept, campaign, requestOptions, Context.NONE); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of agent-owned outbound call Campaign. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCreateCampaignWithModelAsync(String agentName, + String campaignName, BinaryData campaign, RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.createCampaignWithResponseAsync(agentName, campaignName, campaign, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), + TypeReference.createInstance(TelephonyCampaign.class)); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of agent-owned outbound call Campaign. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCreateCampaignWithModel(String agentName, + String campaignName, BinaryData campaign, RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.createCampaignWithResponse(agentName, campaignName, campaign, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), + TypeReference.createInstance(TelephonyCampaign.class)); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of agent-owned outbound call Campaign. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCreateCampaignAsync(String agentName, String campaignName, + BinaryData campaign, RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.createCampaignWithResponseAsync(agentName, campaignName, campaign, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(BinaryData.class)); + } + + /** + * Create or replace a failed telephony campaign + * + * Creates a Campaign or fully replaces failed preparation; no PATCH. All recipients must validate and have CallJobs + * before dialing. Immediate calls may begin before the preparation poller returns. + *

Header Parameters

+ * + * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoRetry key: matching submitted inputs and original If-Match + * replay the saved monitor before current-state checks. Conflicting reuse returns 409 operation_id_conflict; + * retained creation keys after deletion return 409 campaign_deleted.
If-MatchStringNoRequired with a fresh Operation-Id for failed-state + * replacement; no wildcards. Changed input without it returns 409. Missing replacement ID: 400; stale token/absent + * resource: 412; other states: 409.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Request Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Name chosen by the caller; only a failed Campaign permits full replacement. + * @param campaign Complete connection, source, recipients/Dataset, schedule and retry configuration. Omitted + * optional fields reset to defaults; Agent/name and response-only fields cannot change. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of agent-owned outbound call Campaign. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCreateCampaign(String agentName, String campaignName, + BinaryData campaign, RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.createCampaignWithResponse(agentName, campaignName, campaign, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(BinaryData.class)); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
operation_idStringNoOriginal response's Operation-Id guards its instance/round + * and survives same-round actions. Replacement/name reuse: 409 campaign_operation_mismatch; + * missing/expired/wrong-scope operation: 404.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients along with {@link Response} on + * successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getCampaignWithResponseAsync(String agentName, String campaignName, + RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.getCampaign(this.client.getEndpoint(), agentName, campaignName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients. Absent or deleted Campaigns return + * 404. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
operation_idStringNoOriginal response's Operation-Id guards its instance/round + * and survives same-round actions. Replacement/name reuse: 409 campaign_operation_mismatch; + * missing/expired/wrong-scope operation: 404.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a telephony campaign + * + * Gets Campaign configuration and execution state without inline recipients along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getCampaignWithResponse(String agentName, String campaignName, + RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getCampaignSync(this.client.getEndpoint(), agentName, campaignName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position along with + * {@link PagedResponse} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> listCampaignsSinglePageAsync(String agentName, + RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.listCampaigns(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null)); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignsAsync(String agentName, RequestOptions requestOptions) { + return listCampaignsAsync(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignsAsync(String initialContinuationToken, String agentName, + RequestOptions requestOptions) { + return new PagedFlux<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listCampaignsSinglePageAsync(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listCampaignsSinglePageAsync(agentName, requestOptionsLocal); + }); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position along with + * {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private PagedResponse listCampaignsSinglePage(String agentName, RequestOptions requestOptions) { + final String accept = "application/json"; + Response res = service.listCampaignsSync(this.client.getEndpoint(), agentName, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null); + } + + /** + * List telephony campaigns + * + * Lists the Agent's Campaigns without inline recipients. Filters are live views, not snapshots. + *

Query Parameters

+ * + * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
orderStringNoSort order by the `created_at` timestamp of the objects. `asc` + * for ascending order and`desc` + * for descending order. Allowed values: "asc", "desc".
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
statusStringNoFilter by Campaign business state. Allowed values: "validating", + * "running", "cancelling", "completed", "failed", "cancelled", "deleting".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     connection_name: String (Required)
+     *     source (Required): {
+     *         type: String(phone_number/teams/sip) (Required)
+     *         value: String (Required)
+     *     }
+     *     recipients (Optional): [
+     *          (Optional){
+     *             destination (Required): (recursive schema, see destination above)
+     *             structured_inputs (Optional): {
+     *                 String: BinaryData (Required)
+     *             }
+     *             scheduled_at: Long (Optional)
+     *         }
+     *     ]
+     *     recipient_dataset (Optional): {
+     *         name: String (Required)
+     *         version: String (Optional)
+     *     }
+     *     schedule (Optional): {
+     *         type: String(immediate/scheduled/recipient) (Required)
+     *         expires_at: Long (Optional)
+     *     }
+     *     retry_policy (Optional): {
+     *         type: String(fixed_interval) (Required)
+     *         max_attempts: Integer (Optional)
+     *     }
+     *     status: String(validating/running/cancelling/completed/failed/cancelled/deleting) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     name: String (Required)
+     *     created_at: long (Required)
+     *     updated_at: long (Required)
+     *     etag: String (Required)
+     *     operation_id: String (Required)
+     *     finished_at: Long (Optional)
+     *     locked_agent_version: String (Optional)
+     *     progress (Required): {
+     *         total_recipients: Long (Optional)
+     *         pending: long (Required)
+     *         active: long (Required)
+     *         completed: long (Required)
+     *         failed: long (Required)
+     *         cancelled: long (Required)
+     *         expired: long (Required)
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return shared Foundry page shape with opaque boundary tokens bound to the original sort position as paginated + * response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaigns(String agentName, RequestOptions requestOptions) { + return listCampaigns(null, agentName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaigns(String initialContinuationToken, String agentName, + RequestOptions requestOptions) { + return new PagedIterable<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listCampaignsSinglePage(agentName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listCampaignsSinglePage(agentName, requestOptionsLocal); + }); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return preparation/cancel/delete monitor bound to its original Campaign instance/round, independent of later + * actions along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> cancelCampaignWithResponseAsync(String agentName, String campaignName, + String ifMatch, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.cancelCampaign(this.client.getEndpoint(), agentName, + campaignName, ifMatch, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return preparation/cancel/delete monitor bound to its original Campaign instance/round, independent of later + * actions along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Response cancelCampaignWithResponse(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + final String accept = "application/json"; + return service.cancelCampaignSync(this.client.getEndpoint(), agentName, campaignName, ifMatch, + this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCancelCampaignWithModelAsync(String agentName, + String campaignName, String ifMatch, RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.cancelCampaignWithResponseAsync(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), + TypeReference.createInstance(TelephonyCampaign.class)); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCancelCampaignWithModel(String agentName, + String campaignName, String ifMatch, RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.cancelCampaignWithResponse(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), + TypeReference.createInstance(TelephonyCampaign.class)); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginCancelCampaignAsync(String agentName, String campaignName, + String ifMatch, RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.cancelCampaignWithResponseAsync(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(BinaryData.class)); + } + + /** + * Cancel a telephony campaign + * + * Cancels a validating or running Campaign using If-Match. Stops new calls and retries; connected calls finish + * naturally. Returns 202 with an operation monitor to track completion. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key, generated if omitted. Original + * If-Match/key replays 202 even after deletion/name reuse, never touching a replacement; conflicts return 409. + * Failed cancellation needs a fresh key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, missing Campaigns return 404 and stale tokens + * 412. Starting cancellation outside validating/running returns 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of preparation/cancel/delete monitor bound to its original Campaign + * instance/round, independent of later actions. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginCancelCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.cancelCampaignWithResponse(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(BinaryData.class)); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> deleteCampaignWithResponseAsync(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return FluxUtil.withContext(context -> service.deleteCampaign(this.client.getEndpoint(), agentName, + campaignName, ifMatch, this.client.getServiceVersion().getVersion(), requestOptions, context)); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Response deleteCampaignWithResponse(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return service.deleteCampaignSync(this.client.getEndpoint(), agentName, campaignName, ifMatch, + this.client.getServiceVersion().getVersion(), requestOptions, Context.NONE); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of long-running operation. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginDeleteCampaignWithModelAsync(String agentName, + String campaignName, String ifMatch, RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.deleteCampaignWithResponseAsync(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), TypeReference.createInstance(Void.class)); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of long-running operation. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginDeleteCampaignWithModel(String agentName, + String campaignName, String ifMatch, RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.deleteCampaignWithResponse(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(TelephonyCampaignOperation.class), TypeReference.createInstance(Void.class)); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link PollerFlux} for polling of long-running operation. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public PollerFlux beginDeleteCampaignAsync(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return PollerFlux.create(Duration.ofSeconds(1), + () -> this.deleteCampaignWithResponseAsync(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.CampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponseAsync(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(Void.class)); + } + + /** + * Delete a telephony campaign + * + * Deletes a terminal Campaign and its recipient/task data asynchronously. Returns bodyless 202 with a monitor, not + * a tombstone; completion makes GET return 404 and lists omit it. Dataset, connections, Agent, independent jobs and + * call history are preserved. + *

Header Parameters

+ * + * + * + * + *
Header Parameters
NameTypeRequiredDescription
Operation-IdStringNoOptional retry key. Original If-Match/key replays 202 even + * after deletion/name reuse, never touching a new instance; conflicts return 409. Failed cleanup needs a fresh + * key/current token.
+ * You can add these to a request with {@link RequestOptions#addHeader} + * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Immutable Campaign name. + * @param ifMatch Exact current token; no wildcards. Without replay, absent Campaigns return 204 and stale tokens + * 412. Active calls/workers or unfinished cancellation return 409. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return the {@link SyncPoller} for polling of long-running operation. + */ + @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) + public SyncPoller beginDeleteCampaign(String agentName, String campaignName, String ifMatch, + RequestOptions requestOptions) { + return SyncPoller.createPoller(Duration.ofSeconds(1), + () -> this.deleteCampaignWithResponse(agentName, campaignName, ifMatch, requestOptions), + new com.azure.ai.agents.implementation.SyncCampaignOperationLocationPollingStrategy<>( + new PollingStrategyOptions(this.client.getHttpPipeline()) + .setEndpoint("{endpoint}".replace("{endpoint}", this.client.getEndpoint())) + .setContext(requestOptions != null && requestOptions.getContext() != null + ? requestOptions.getContext() + : Context.NONE) + .setServiceVersion(this.client.getServiceVersion().getVersion()), + finalRequestOptions -> this.getCampaignWithResponse(agentName, campaignName, finalRequestOptions)), + TypeReference.createInstance(BinaryData.class), TypeReference.createInstance(Void.class)); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page along with {@link PagedResponse} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private Mono> listCampaignValidationErrorsSinglePageAsync(String agentName, + String campaignName, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil + .withContext(context -> service.listCampaignValidationErrors(this.client.getEndpoint(), agentName, + campaignName, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null)); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page as paginated response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignValidationErrorsAsync(String agentName, String campaignName, + RequestOptions requestOptions) { + return listCampaignValidationErrorsAsync(null, agentName, campaignName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listCampaignValidationErrorsAsync(String initialContinuationToken, String agentName, + String campaignName, RequestOptions requestOptions) { + return new PagedFlux<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listCampaignValidationErrorsSinglePageAsync(agentName, campaignName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listCampaignValidationErrorsSinglePageAsync(agentName, campaignName, requestOptionsLocal); + }); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + private PagedResponse listCampaignValidationErrorsSinglePage(String agentName, String campaignName, + RequestOptions requestOptions) { + final String accept = "application/json"; + Response res = service.listCampaignValidationErrorsSync(this.client.getEndpoint(), agentName, + campaignName, this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + getValues(res.getValue(), "data"), getNextLink(res.getValue(), "last_id"), null); + } + + /** + * List campaign validation errors + * + * Lists current-round row validation errors. Results may be partial during preparation; an empty page does not + * establish success. Execution errors are in CallJobs; non-row failures are in Campaign.error. + *

Query Parameters

+ * + * + * + * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
limitIntegerNoA limit on the number of objects to be returned. Limit can range + * between 1 and 100, and the + * default is 20.
afterStringNoOpaque last_id bound to scope/filters/order; error cursors also + * bind instance/round/snapshot and survive cancel, not replacement. Exclusive with before; invalid tokens return + * 400 invalid_cursor.
beforeStringNoOpaque first_id for backward paging with unchanged + * scope/filters/order; exclusive with after.
orderStringNoSort invalid rows by their original row_number. Allowed values: + * "asc", "desc".
+ * You can add these to a request with {@link RequestOptions#addQueryParam} + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     row_number: long (Required)
+     *     error (Required): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @param agentName Owning Agent; never overridden in recipient inputs. + * @param campaignName Campaign name. Deleting returns 409 campaign_deleting; absent/deleted returns 404. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return error-only page as paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaignValidationErrors(String agentName, String campaignName, + RequestOptions requestOptions) { + return listCampaignValidationErrors(null, agentName, campaignName, requestOptions); + } + + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listCampaignValidationErrors(String initialContinuationToken, String agentName, + String campaignName, RequestOptions requestOptions) { + return new PagedIterable<>(() -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (initialContinuationToken != null) { + requestOptionsLocal.addQueryParam("after", initialContinuationToken, false); + } + return listCampaignValidationErrorsSinglePage(agentName, campaignName, requestOptionsLocal); + }, (after) -> { + RequestOptions requestOptionsLocal = requestOptions == null ? new RequestOptions() : requestOptions; + requestOptionsLocal.addRequestCallback(requestLocal -> { + UrlBuilder urlBuilder = UrlBuilder.parse(requestLocal.getUrl()); + urlBuilder.setQueryParameter("after", null); + requestLocal.setUrl(urlBuilder.toString()); + }); + if (after != null) { + requestOptionsLocal.addQueryParam("after", after, false); + } + return listCampaignValidationErrorsSinglePage(agentName, campaignName, requestOptionsLocal); + }); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + *
Response Headers
NameTypeDescription
Retry-AfterintRecommended number of seconds to wait before polling again.
+ * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a campaign operation + * + * Gets the initiating operation's status along with {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getCampaignOperationWithResponseAsync(String agentName, String campaignName, + String operationId, RequestOptions requestOptions) { + final String accept = "application/json"; + return FluxUtil.withContext(context -> service.getCampaignOperation(this.client.getEndpoint(), agentName, + campaignName, operationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, context)); + } + + /** + * Get a campaign operation + * + * Gets the initiating operation's status. PUT/cancel pollers finish with a guarded Campaign GET; deletion completes + * without a resource result. + *

Response Body Schema

+ * + *
+     * {@code
+     * {
+     *     id: String (Required)
+     *     status: String(queued/in_progress/succeeded/failed/cancelled) (Required)
+     *     error (Optional): {
+     *         code: String (Required)
+     *         message: String (Required)
+     *         param: String (Optional)
+     *         type: String (Optional)
+     *         misalignment (Optional): {
+     *             review_target: String (Optional)
+     *             error_type: String(potentially_unintended_data_transfer/potentially_unintended_data_access/potentially_unintended_destructive_activity/other) (Optional)
+     *             detailed_explanation: String (Optional)
+     *             steer (Optional): {
+     *                 message: String (Required)
+     *             }
+     *         }
+     *         details (Optional): [
+     *             (recursive schema, see above)
+     *         ]
+     *         additionalInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *         debugInfo (Optional): {
+     *             String: BinaryData (Required)
+     *         }
+     *     }
+     *     kind: String(validation/cancel/delete) (Required)
+     *     created_at: long (Required)
+     *     finished_at: Long (Optional)
+     * }
+     * }
+     * 
+ * + *

Response Headers

+ * + * + * + * + *
Response Headers
NameTypeDescription
Retry-AfterintRecommended number of seconds to wait before polling again.
+ * + * @param agentName Owning Agent. + * @param campaignName Immutable Campaign name. + * @param operationId Operation-Id from the initiating response. Saved project/Agent authorization still applies + * after resource deletion. + * @param requestOptions The options to configure the HTTP request before HTTP client sends it. + * @throws HttpResponseException thrown if the request is rejected by server. + * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. + * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. + * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. + * @return a campaign operation + * + * Gets the initiating operation's status along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getCampaignOperationWithResponse(String agentName, String campaignName, + String operationId, RequestOptions requestOptions) { + final String accept = "application/json"; + return service.getCampaignOperationSync(this.client.getEndpoint(), agentName, campaignName, operationId, this.client.getServiceVersion().getVersion(), accept, requestOptions, Context.NONE); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategy.java new file mode 100644 index 0000000000000..0f3733f8f423a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategy.java @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation; + +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.polling.LongRunningOperationStatus; +import com.azure.core.util.polling.PollResponse; +import com.azure.core.util.polling.PollingContext; +import com.azure.core.util.polling.PollingStrategyOptions; +import com.azure.core.util.serializer.JsonSerializerProviders; +import com.azure.core.util.serializer.ObjectSerializer; +import com.azure.core.util.serializer.TypeReference; +import java.util.Objects; +import java.util.function.Function; +import reactor.core.publisher.Mono; + +/** + * Polls campaign monitors and retrieves the original campaign instance, or no result for deletion. + * The initial Operation-Id guards the final GET against campaign replacement or name reuse. + * A bodyless DELETE 204 completes immediately without polling. + * + * @param the operation monitor type + * @param the final campaign type, BinaryData, or Void for deletion + */ +final class CampaignOperationLocationPollingStrategy extends OperationLocationPollingStrategy { + private static final ClientLogger LOGGER = new ClientLogger(CampaignOperationLocationPollingStrategy.class); + private final Function>> getCampaign; + private final ObjectSerializer serializer; + private final Context context; + + CampaignOperationLocationPollingStrategy(PollingStrategyOptions options, + Function>> getCampaign) { + super(options); + this.getCampaign = Objects.requireNonNull(getCampaign, "'getCampaign' cannot be null."); + this.serializer + = options.getSerializer() == null ? JsonSerializerProviders.createInstance(true) : options.getSerializer(); + this.context = options.getContext() == null ? Context.NONE : options.getContext(); + } + + @Override + public Mono canPoll(Response response) { + return Mono.fromSupplier(() -> AgentsServicePollUtils.canPollCampaign(response)); + } + + @Override + public Mono> onInitialResponse(Response response, PollingContext pollingContext, + TypeReference pollResponseType) { + return Mono.defer(() -> { + if (AgentsServicePollUtils.initializeCampaignPollingContext(response, pollingContext)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, null)); + } + return super.onInitialResponse(response, pollingContext, pollResponseType); + }); + } + + @Override + public Mono getResult(PollingContext pollingContext, TypeReference resultType) { + return Mono.defer(() -> { + if (AgentsServicePollUtils.isCompletedCampaignDeletion(pollingContext)) { + return Mono.empty(); + } + RequestOptions requestOptions + = AgentsServicePollUtils.getCampaignFinalRequestOptions(pollingContext, context); + return getCampaign.apply(requestOptions) + .flatMap(response -> PollingUtils.deserializeResponse( + AgentsServicePollUtils.getCampaignResponseBody(response), serializer, resultType)) + .switchIfEmpty(Mono.defer(() -> Mono.error(LOGGER.logExceptionAsError( + new IllegalStateException("Campaign final GET did not contain a response body."))))); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/OpenAIJsonHelper.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/OpenAIJsonHelper.java index 6d7c41624bd0f..ed80f517b9b6a 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/OpenAIJsonHelper.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/OpenAIJsonHelper.java @@ -4,6 +4,8 @@ package com.azure.ai.agents.implementation; import com.azure.core.util.BinaryData; +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.serializer.JsonSerializer; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; @@ -16,16 +18,53 @@ import com.openai.models.responses.ResponseCreateParams; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.StringReader; +import java.io.UncheckedIOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import reactor.core.publisher.Mono; public final class OpenAIJsonHelper { + private static final ClientLogger LOGGER = new ClientLogger(OpenAIJsonHelper.class); private static final ObjectMapper OPENAI_MODEL_MAPPER = ObjectMappers.jsonMapper(); + private static final JsonSerializer OPENAI_MODEL_SERIALIZER = new JsonSerializer() { + @Override + public T deserialize(InputStream stream, com.azure.core.util.serializer.TypeReference typeReference) { + try { + return OPENAI_MODEL_MAPPER.readValue(stream, + OPENAI_MODEL_MAPPER.constructType(typeReference.getJavaType())); + } catch (IOException error) { + throw LOGGER.logExceptionAsError(new UncheckedIOException(error)); + } + } + + @Override + public Mono deserializeAsync(InputStream stream, + com.azure.core.util.serializer.TypeReference typeReference) { + return Mono.fromCallable(() -> deserialize(stream, typeReference)); + } + + @Override + public void serialize(OutputStream stream, Object value) { + try { + stream.write(OPENAI_MODEL_MAPPER.writeValueAsBytes(value)); + } catch (IOException error) { + throw LOGGER.logExceptionAsError(new UncheckedIOException(error)); + } + } + + @Override + public Mono serializeAsync(OutputStream stream, Object value) { + return Mono.fromRunnable(() -> serialize(stream, value)); + } + }; + private static final ObjectMapper MAPPER = ObjectMappers.jsonMapper() .rebuild() .configure(MapperFeature.AUTO_DETECT_FIELDS, true) @@ -114,10 +153,7 @@ public static BinaryData toBinaryData(Object openAIObject) { } try { String json = OPENAI_MODEL_MAPPER.writeValueAsString(openAIObject); - try (JsonReader reader = JsonProviders.createReader(new StringReader(json))) { - reader.nextToken(); - return BinaryData.fromObject(reader.readUntyped()); - } + return BinaryData.fromObject(OPENAI_MODEL_MAPPER.readTree(json), OPENAI_MODEL_SERIALIZER); } catch (IOException e) { throw new RuntimeException("Failed to convert OpenAI type to BinaryData", e); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/StructuredInputJsonHelper.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/StructuredInputJsonHelper.java new file mode 100644 index 0000000000000..3f36ed0cff466 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/StructuredInputJsonHelper.java @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation; + +import com.azure.core.util.BinaryData; +import com.azure.core.util.logging.ClientLogger; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Reads structured input JSON without coercing its numbers to Java numeric types. + */ +public final class StructuredInputJsonHelper { + private static final ClientLogger LOGGER = new ClientLogger(StructuredInputJsonHelper.class); + + private StructuredInputJsonHelper() { + } + + /** + * Reads a non-null JSON value while retaining its numeric precision and JSON types. + * + * @param reader the reader positioned at the value. + * @return the JSON value as serializable BinaryData. + * @throws IOException if the JSON cannot be read. + * @throws IllegalStateException if the reader is not positioned at a non-null JSON value. + */ + public static BinaryData readJsonValue(JsonReader reader) throws IOException { + JsonToken token = reader.currentToken(); + if (token == JsonToken.STRING) { + return BinaryData.fromObject(reader.getString()); + } + String json; + if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) { + json = reader.readChildren(); + } else if (token == JsonToken.NUMBER || token == JsonToken.BOOLEAN) { + json = reader.getText(); + } else { + throw LOGGER + .logExceptionAsError(new IllegalStateException("Expected a non-null JSON value, found " + token)); + } + return BinaryData.fromObject(new JsonValue(json)); + } + + private static final class JsonValue implements JsonSerializable { + private final String json; + + private JsonValue(String json) { + this.json = json; + } + + @Override + public JsonWriter toJson(JsonWriter writer) throws IOException { + return writer.writeRawValue(json); + } + + public static JsonValue fromJson(JsonReader reader) throws IOException { + if (reader.currentToken() == null) { + reader.nextToken(); + } + return reader.getNullable(nonNullReader -> new JsonValue(readJsonValue(nonNullReader).toString())); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/SyncCampaignOperationLocationPollingStrategy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/SyncCampaignOperationLocationPollingStrategy.java new file mode 100644 index 0000000000000..859fcd2a58165 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/SyncCampaignOperationLocationPollingStrategy.java @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation; + +import com.azure.core.http.rest.RequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.polling.LongRunningOperationStatus; +import com.azure.core.util.polling.PollResponse; +import com.azure.core.util.polling.PollingContext; +import com.azure.core.util.polling.PollingStrategyOptions; +import com.azure.core.util.serializer.JsonSerializerProviders; +import com.azure.core.util.serializer.ObjectSerializer; +import com.azure.core.util.serializer.TypeReference; +import java.util.Objects; +import java.util.function.Function; + +/** + * Polls campaign monitors synchronously and retrieves the original campaign instance, or no result for deletion. + * The initial Operation-Id guards the final GET against campaign replacement or name reuse. + * A bodyless DELETE 204 completes immediately without polling. + * + * @param the operation monitor type + * @param the final campaign type, BinaryData, or Void for deletion + */ +final class SyncCampaignOperationLocationPollingStrategy extends SyncOperationLocationPollingStrategy { + private static final ClientLogger LOGGER = new ClientLogger(SyncCampaignOperationLocationPollingStrategy.class); + private final Function> getCampaign; + private final ObjectSerializer serializer; + private final Context context; + + SyncCampaignOperationLocationPollingStrategy(PollingStrategyOptions options, + Function> getCampaign) { + super(options); + this.getCampaign = Objects.requireNonNull(getCampaign, "'getCampaign' cannot be null."); + this.serializer + = options.getSerializer() == null ? JsonSerializerProviders.createInstance(true) : options.getSerializer(); + this.context = options.getContext() == null ? Context.NONE : options.getContext(); + } + + @Override + public boolean canPoll(Response response) { + return AgentsServicePollUtils.canPollCampaign(response); + } + + @Override + public PollResponse onInitialResponse(Response response, PollingContext pollingContext, + TypeReference pollResponseType) { + if (AgentsServicePollUtils.initializeCampaignPollingContext(response, pollingContext)) { + return new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, null); + } + return super.onInitialResponse(response, pollingContext, pollResponseType); + } + + @Override + public U getResult(PollingContext pollingContext, TypeReference resultType) { + if (AgentsServicePollUtils.isCompletedCampaignDeletion(pollingContext)) { + return null; + } + RequestOptions requestOptions = AgentsServicePollUtils.getCampaignFinalRequestOptions(pollingContext, context); + BinaryData body = AgentsServicePollUtils.getCampaignResponseBody(getCampaign.apply(requestOptions)); + U result = PollingUtils.deserializeResponseSync(body, serializer, resultType); + if (result == null) { + throw LOGGER + .logExceptionAsError(new IllegalStateException("Campaign final GET did not contain a response body.")); + } + return result; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketClientConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketClientConfiguration.java index d123c4d966303..3b154026caa09 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketClientConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketClientConfiguration.java @@ -80,7 +80,7 @@ public String getUserAgent() { /** * Gets safe additional headers. * - * @return safe additional headers, or {@code null}. + * @return safe additional headers, or {@code null}. */ public HttpHeaders getHeaders() { return headers; diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketUtils.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketUtils.java index 97aade8190dd7..fe292a2882e1e 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketUtils.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/VoiceAgentWebSocketUtils.java @@ -6,6 +6,7 @@ import com.azure.ai.agents.implementation.models.AgentDefinitionOptInKeys; import com.azure.ai.agents.models.RawRealtimeServerEvent; import com.azure.ai.agents.models.RealtimeServerEvent; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; import com.azure.ai.agents.models.VoiceAgentTransport; import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; import com.azure.core.credential.TokenRequestContext; @@ -13,10 +14,14 @@ import com.azure.core.http.HttpHeaderName; import com.azure.core.http.HttpHeaders; import com.azure.core.util.BinaryData; +import com.azure.core.util.IterableStream; import com.azure.core.util.UrlBuilder; +import com.azure.core.util.logging.ClientLogger; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; import com.azure.json.JsonToken; +import reactor.core.publisher.Flux; + import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -25,10 +30,77 @@ import java.nio.charset.CharacterCodingException; import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; +import java.util.Iterator; import java.util.Locale; +import java.util.NoSuchElementException; import java.util.Objects; +import java.util.function.Consumer; public final class VoiceAgentWebSocketUtils { + private static final ClientLogger LOGGER = new ClientLogger(VoiceAgentWebSocketUtils.class); + + public static IterableStream decodeEvents(IterableStream messages, + WebSocketEventDecoder decoder, Consumer malformedEventHandler, Runnable closeOnError) { + return IterableStream.of(() -> new Iterator() { + private final Iterator source = messages.iterator(); + private T next; + private boolean terminated; + + @Override + public boolean hasNext() { + while (next == null && !terminated && source.hasNext()) { + BinaryData message = source.next(); + try { + next = decodeEvent(message, decoder, malformedEventHandler); + } catch (RuntimeException error) { + terminated = true; + closeOnError.run(); + throw LOGGER.logExceptionAsError(error); + } + } + return next != null; + } + + @Override + public T next() { + if (!hasNext()) { + throw LOGGER.logExceptionAsError(new NoSuchElementException()); + } + T event = next; + next = null; + return event; + } + }); + } + + public static Flux decodeEvents(Flux messages, WebSocketEventDecoder decoder, + Consumer malformedEventHandler, Runnable closeOnError) { + return messages.handle((message, sink) -> { + try { + T event = decodeEvent(message, decoder, malformedEventHandler); + if (event != null) { + sink.next(event); + } + } catch (RuntimeException error) { + closeOnError.run(); + sink.error(error); + } + }); + } + + private static T decodeEvent(BinaryData message, WebSocketEventDecoder decoder, + Consumer malformedEventHandler) { + try { + return decoder.decode(message.toString()); + } catch (IOException | RuntimeException error) { + if (malformedEventHandler != null) { + malformedEventHandler.accept(error); + return null; + } + throw LOGGER.logExceptionAsError(new IllegalArgumentException("Invalid JSON event.", error)); + } + } + public static String decodeEvent(byte[] bytes) throws CharacterCodingException { return StandardCharsets.UTF_8.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) @@ -71,6 +143,12 @@ public static RealtimeServerEvent deserializeEvent(String json) throws IOExcepti private VoiceAgentWebSocketUtils() { } + public static BinaryData deserializeRawEvent(String json) { + BinaryData event = BinaryData.fromString(json); + validateEvent(event); + return event; + } + public static void validateClose(int code, String reason) { if (code < 1000 || code >= 5000 @@ -98,11 +176,37 @@ private static boolean isProtectedHeader(String name) { public static URI buildWebSocketUri(VoiceAgentWebSocketClientConfiguration configuration, String agentName, VoiceAgentWebSocketConnectionOptions options) { + UrlBuilder url = buildSessionUrl(configuration, agentName, "", options.isStoreEnabled(), + options.getAgentVersionOverride()); + VoiceAgentTransport transport = options.getTransportType(); + url.setQueryParameter("transport", transport == null ? "websocket" : encode(transport.toString())); + if (options.getAgentSessionId() != null) { + url.setQueryParameter("agent_session_id", encode(options.getAgentSessionId())); + } + return URI.create(url.toString()); + } + + public static URI buildLiveWebSocketUri(VoiceAgentWebSocketClientConfiguration configuration, String agentName, + VoiceAgentLiveWebSocketConnectionOptions options) { + UrlBuilder url = buildSessionUrl(configuration, agentName, "/live/sessions", options.isStoreEnabled(), + options.getAgentVersionOverride()); + if (options.getStructuredInputs() != null) { + url.setQueryParameter("structured_inputs", encode(options.getStructuredInputs())); + } + return URI.create(url.toString()); + } + + private static UrlBuilder buildSessionUrl(VoiceAgentWebSocketClientConfiguration configuration, String agentName, + String suffix, Boolean store, String agentVersionOverride) { + Objects.requireNonNull(agentName, "'agentName' cannot be null."); + if (agentName.isEmpty()) { + throw new IllegalArgumentException("'agentName' cannot be empty."); + } + if (!suffix.isEmpty() && !suffix.startsWith("/")) { + throw new IllegalArgumentException("A voice-agent route suffix must start with '/'."); + } URI endpoint = configuration.getEndpoint(); - String scheme; - if ("https".equalsIgnoreCase(endpoint.getScheme()) || "wss".equalsIgnoreCase(endpoint.getScheme())) { - scheme = "wss"; - } else { + if (!"https".equalsIgnoreCase(endpoint.getScheme()) && !"wss".equalsIgnoreCase(endpoint.getScheme())) { throw new IllegalArgumentException( "Voice-agent WebSocket endpoints must use https or wss to protect credentials."); } @@ -112,23 +216,20 @@ public static URI buildWebSocketUri(VoiceAgentWebSocketClientConfiguration confi } String basePath = endpoint.getRawPath() == null ? "" : endpoint.getRawPath().replaceAll("/$", ""); - String path = basePath + "/agents/" + encode(agentName) + "/endpoint/protocols/voice"; - URI baseUri = URI.create(scheme + "://" + endpoint.getRawAuthority() + path); - UrlBuilder url = UrlBuilder.parse(baseUri.toString()); + String path = basePath + "/agents/" + encode(agentName) + "/endpoint/protocols/voice" + suffix; + UrlBuilder url = UrlBuilder.parse(endpoint.toString()).setScheme("wss").setPath(path); + // Initialize the lazy query before clearing it; the pinned Azure Core version otherwise retains it. + url.getQuery(); + url.clearQuery(); url.setQueryParameter("api-version", encode(configuration.getApiVersion())); url.setQueryParameter("x-ms-client-sdk", encode(configuration.getUserAgent())); - VoiceAgentTransport transport = options.getTransport(); - url.setQueryParameter("transport", transport == null ? "websocket" : encode(transport.toString())); - if (options.isStoreEnabled() != null) { - url.setQueryParameter("store", options.isStoreEnabled().toString()); + if (store != null) { + url.setQueryParameter("store", store.toString()); } - if (options.getAgentVersionOverride() != null) { - url.setQueryParameter("x-agent-version-override", encode(options.getAgentVersionOverride())); + if (agentVersionOverride != null) { + url.setQueryParameter("x-agent-version-override", encode(agentVersionOverride)); } - if (options.getAgentSessionId() != null) { - url.setQueryParameter("agent_session_id", encode(options.getAgentSessionId())); - } - return URI.create(url.toString()); + return url; } public static TokenRequestContext createTokenRequestContext() { @@ -137,6 +238,14 @@ public static TokenRequestContext createTokenRequestContext() { public static HttpHeaders buildHeaders(VoiceAgentWebSocketClientConfiguration configuration, VoiceAgentWebSocketConnectionOptions options, String token) { + HttpHeaders headers = buildHeaders(configuration, token); + if (options.getStructuredInputs() != null) { + headers.set(HttpHeaderName.fromString("x-ms-voice-structured-inputs"), options.getStructuredInputs()); + } + return headers; + } + + public static HttpHeaders buildHeaders(VoiceAgentWebSocketClientConfiguration configuration, String token) { HttpHeaders headers = new HttpHeaders().set(HttpHeaderName.USER_AGENT, configuration.getUserAgent()); if (configuration.getHeaders() != null) { for (HttpHeader header : configuration.getHeaders()) { @@ -147,9 +256,6 @@ public static HttpHeaders buildHeaders(VoiceAgentWebSocketClientConfiguration co } headers.set(HttpHeaderName.fromString("Foundry-Features"), AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.toString()); - if (options.getStructuredInputs() != null) { - headers.set(HttpHeaderName.fromString("x-ms-voice-structured-inputs"), options.getStructuredInputs()); - } return headers.set(HttpHeaderName.AUTHORIZATION, "Bearer " + token); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketEventDecoder.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketEventDecoder.java new file mode 100644 index 0000000000000..487f459f81e66 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketEventDecoder.java @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation.realtime; + +import java.io.IOException; + +/** + * Decodes a raw message in a protocol session client. + * @param the decoded event type. + */ +@FunctionalInterface +public interface WebSocketEventDecoder { + T decode(String json) throws IOException; +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionAsyncClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionAsyncTransport.java similarity index 51% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionAsyncClient.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionAsyncTransport.java index 06cba1221d988..2e867c929c615 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionAsyncClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionAsyncTransport.java @@ -1,37 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.azure.ai.agents; - -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketHandshakeHandler; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketHttpResponse; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.ai.agents.models.RealtimeClientEvent; -import com.azure.ai.agents.models.RealtimeConversationItemCreateEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent; -import com.azure.ai.agents.models.RealtimeResponseCancelEvent; -import com.azure.ai.agents.models.RealtimeResponseCreateEvent; -import com.azure.ai.agents.models.RealtimeConversationItem; -import com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput; -import com.azure.ai.agents.models.RealtimeConversationItemUserMessage; -import com.azure.ai.agents.models.RealtimeServerEvent; -import com.azure.ai.agents.models.VoiceAgentResponseCreateOptions; -import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; +package com.azure.ai.agents.implementation.realtime; + import com.azure.core.credential.AccessToken; -import com.azure.core.credential.TokenRequestContext; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.HttpResponseException; import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.HttpHeader; +import com.azure.core.http.HttpHeaders; import com.azure.core.http.ProxyOptions; -import com.azure.core.util.AsyncCloseable; import com.azure.core.util.BinaryData; -import com.openai.models.realtime.RealtimeConversationItemUserMessage.Content; import com.azure.core.util.logging.ClientLogger; import io.netty.channel.Channel; import io.netty.channel.ChannelOption; @@ -39,18 +19,6 @@ import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakeException; import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import java.io.IOException; -import java.net.URI; -import java.time.Duration; -import java.util.Base64; -import java.util.Collections; -import java.util.Objects; -import java.util.Queue; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CancellationException; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import reactor.core.Disposable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -62,161 +30,100 @@ import reactor.netty.http.websocket.WebsocketOutbound; import reactor.netty.transport.ProxyProvider; +import java.io.IOException; +import java.net.URI; +import java.time.Duration; +import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CancellationException; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + /** - * An asynchronous bidirectional realtime session connected to a Foundry voice agent. - * - *

Instances are created by {@link BetaVoiceAgentWebSocketAsyncClient#openWebSocketSession(String)}. A session supports one - * subscriber to {@link #receiveEvents()}. Close the session when it is no longer needed.

+ * Shared asynchronous WebSocket connection and raw message I/O. */ -@Beta(warningText = "This class is in preview and may change in future releases.") -public final class BetaVoiceAgentWebSocketSessionAsyncClient implements AsyncCloseable, AutoCloseable { - private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentWebSocketSessionAsyncClient.class); +public final class WebSocketSessionAsyncTransport implements AutoCloseable { + private static final ClientLogger LOGGER = new ClientLogger(WebSocketSessionAsyncTransport.class); private static final int MAX_OUTSTANDING_SENDS = 256; - private final VoiceAgentWebSocketClientConfiguration configuration; - private final VoiceAgentWebSocketConnectionOptions options; + private final WebSocketTransportOptions options; private final HttpClient httpClient; private final URI websocketUri; - private final AtomicReference state = new AtomicReference<>(State.NEW); + private final String subprotocol; + private final Function headersFactory; + private final AtomicReference state = new AtomicReference<>(WebSocketSessionState.NEW); private final AtomicReference channel = new AtomicReference<>(); private final AtomicReference outbound = new AtomicReference<>(); private final AtomicReference connectionOperation = new AtomicReference<>(); private final AtomicReference lifecycle = new AtomicReference<>(); private final AtomicBoolean receiveClaimed = new AtomicBoolean(); private final Semaphore sendPermits = new Semaphore(MAX_OUTSTANDING_SENDS); - private final Queue eventQueue; - private final Sinks.Many events; + private final Queue eventQueue; + private final Sinks.Many events; private final Sinks.One ready = Sinks.one(); private final Sinks.One closeSignal = Sinks.one(); private final AtomicReference> closeOperation = new AtomicReference<>(); - private volatile Integer closeCode; private volatile String closeReason; - BetaVoiceAgentWebSocketSessionAsyncClient(VoiceAgentWebSocketClientConfiguration configuration, String agentName, - VoiceAgentWebSocketConnectionOptions options) { - this(configuration, agentName, options, HttpClient.create()); - } - - BetaVoiceAgentWebSocketSessionAsyncClient(VoiceAgentWebSocketClientConfiguration configuration, String agentName, - VoiceAgentWebSocketConnectionOptions options, HttpClient httpClient) { + public WebSocketSessionAsyncTransport(VoiceAgentWebSocketClientConfiguration configuration, URI websocketUri, + WebSocketTransportOptions options, HttpClient httpClient, String subprotocol, + Function headersFactory) { this.configuration = Objects.requireNonNull(configuration, "'configuration' cannot be null."); - Objects.requireNonNull(agentName, "'agentName' cannot be null."); - if (agentName.isEmpty()) { - throw new IllegalArgumentException("'agentName' cannot be empty."); - } - this.options = options == null ? new VoiceAgentWebSocketConnectionOptions() : options; + this.options = Objects.requireNonNull(options, "'options' cannot be null."); this.eventQueue = new ArrayBlockingQueue<>(this.options.getReceiveBufferCapacity()); this.events = Sinks.many().unicast().onBackpressureBuffer(eventQueue); this.httpClient = Objects.requireNonNull(httpClient, "'httpClient' cannot be null."); - this.websocketUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, agentName, this.options); + this.websocketUri = Objects.requireNonNull(websocketUri, "'websocketUri' cannot be null."); + this.subprotocol = subprotocol; + this.headersFactory = Objects.requireNonNull(headersFactory, "'headersFactory' cannot be null."); } - Mono connect() { + public Mono connect() { return Mono.defer(() -> { - if (!state.compareAndSet(State.NEW, State.CONNECTING)) { + if (!state.compareAndSet(WebSocketSessionState.NEW, WebSocketSessionState.CONNECTING)) { return Mono.error(new IllegalStateException("The voice-agent session has already been started.")); } - - TokenRequestContext tokenContext = VoiceAgentWebSocketUtils.createTokenRequestContext(); - return configuration.getCredential().getToken(tokenContext).map(AccessToken::getToken).flatMap(token -> { - Disposable connection = openWebSocket(token).subscribe(unused -> { - }, this::terminateWithError, this::terminateNormally); - connectionOperation.set(connection); - return ready.asMono().timeout(options.getHandshakeTimeout()); - }) + return configuration.getCredential() + .getToken(VoiceAgentWebSocketUtils.createTokenRequestContext()) + .map(AccessToken::getToken) + .flatMap(token -> { + Disposable connection = openWebSocket(token).subscribe(unused -> { + }, this::terminateWithError, this::terminateNormally); + connectionOperation.set(connection); + return ready.asMono().timeout(options.getHandshakeTimeout()); + }) .doOnError(this::terminateWithError) .doOnCancel(() -> terminateWithError(new CancellationException("WebSocket connection cancelled."))); }); } - /** - * Gets the WebSocket endpoint used by this session. - * - * @return the WebSocket endpoint. - */ public String getEndpoint() { return websocketUri.toString(); } - /** - * Determines whether the WebSocket session is open. - * - * @return {@code true} when the session is open. - */ public boolean isOpen() { Channel current = channel.get(); - return state.get() == State.OPEN && current != null && current.isActive(); + return state.get() == WebSocketSessionState.OPEN && current != null && current.isActive(); } - /** - * Gets the peer close code after the session closes. - * - * @return the close code, or {@code null} when no close frame has been received. - */ public Integer getCloseCode() { return closeCode; } - /** - * Gets the peer close reason after the session closes. - * - * @return the close reason, or {@code null} when no close frame has been received. - */ public String getCloseReason() { return closeReason; } - /** - * Receives typed server events in wire order. Only one subscriber is supported per session. - * - * @return the server event stream. - */ - public Flux receiveEvents() { + public Flux receiveEvents() { return Flux.defer(() -> receiveClaimed.compareAndSet(false, true) ? events.asFlux() : Flux.error(new IllegalStateException("Only one receiveEvents subscriber is supported per session."))); } - /** - * Sends a typed realtime client event. - * - * @param event the event to send. - * @return a completion signal emitted after the frame is written. - */ - public Mono sendEvent(RealtimeClientEvent event) { - Objects.requireNonNull(event, "'event' cannot be null."); - return Mono.defer(() -> { - Channel current = requireOpenChannel(); - if (!sendPermits.tryAcquire()) { - return Mono.error(new IllegalStateException("Too many voice-agent WebSocket sends are outstanding.")); - } - - final String json; - try { - json = serialize(event); - } catch (IOException error) { - sendPermits.release(); - return Mono - .error(new IllegalArgumentException("Failed to serialize the realtime client event.", error)); - } - - return Mono.create(sink -> current.writeAndFlush(new TextWebSocketFrame(json)).addListener(result -> { - sendPermits.release(); - if (result.isSuccess()) { - sink.success(); - } else { - sink.error(result.cause()); - } - })); - }); - } - - /** - * Sends a JSON object, including event types and fields unknown to this SDK. - * @param event the complete JSON event. - * @return completion after the frame is written, or an error for invalid JSON or a closed session. - */ public Mono sendEvent(BinaryData event) { Objects.requireNonNull(event, "'event' cannot be null."); return Mono.defer(() -> { @@ -236,140 +143,10 @@ public Mono sendEvent(BinaryData event) { }); } - /** - * Adds an item to the session conversation. - * - * @param item the item to add. - * @return a completion signal emitted after the event is written. - */ - public Mono createConversationItem(RealtimeConversationItem item) { - return createConversationItem(item, null); - } - - /** - * Adds an item after a specific conversation item. - * - * @param item the item to add. - * @param previousItemId the preceding item identifier, or {@code null} to append. - * @return a completion signal emitted after the event is written. - */ - public Mono createConversationItem(RealtimeConversationItem item, String previousItemId) { - Objects.requireNonNull(item, "'item' cannot be null."); - return sendEvent(new RealtimeConversationItemCreateEvent(item).setPreviousItemId(previousItemId)); - } - - /** - * Adds a user text message to the session conversation. - * - * @param text the user message. - * @return a completion signal emitted after the event is written. - */ - public Mono sendText(String text) { - Objects.requireNonNull(text, "'text' cannot be null."); - Content content = Content.builder().type(Content.Type.INPUT_TEXT).text(text).build(); - return createConversationItem(new RealtimeConversationItemUserMessage(Collections.singletonList(content))); - } - - /** - * Appends PCM or encoded audio bytes to the input audio buffer. - * - * @param audio the bytes in the input format configured by the voice agent. - * @return a completion signal emitted after the event is written. - */ - public Mono appendInputAudio(BinaryData audio) { - Objects.requireNonNull(audio, "'audio' cannot be null."); - String encoded = Base64.getEncoder().encodeToString(audio.toBytes()); - return sendEvent(new RealtimeInputAudioBufferAppendEvent(encoded)); - } - - /** - * Clears the input audio buffer. - * - * @return a completion signal emitted after the event is written. - */ - public Mono clearInputAudio() { - return sendEvent(new RealtimeInputAudioBufferClearEvent()); - } - - /** - * Commits the input audio buffer. - * - * @return a completion signal emitted after the event is written. - */ - public Mono commitInputAudio() { - return sendEvent(new RealtimeInputAudioBufferCommitEvent()); - } - - /** - * Requests a response using the persisted voice-agent configuration. - * - * @return a completion signal emitted after the event is written. - */ - public Mono createResponse() { - return sendEvent(new RealtimeResponseCreateEvent()); - } - - /** - * Requests a response with per-response options. - * - * @param responseOptions the response options. - * @return a completion signal emitted after the event is written. - */ - public Mono createResponse(VoiceAgentResponseCreateOptions responseOptions) { - Objects.requireNonNull(responseOptions, "'responseOptions' cannot be null."); - return sendEvent(new RealtimeResponseCreateEvent().setResponse(responseOptions)); - } - - /** - * Cancels the response currently writing to the default conversation. - * - * @return a completion signal emitted after the event is written. - */ - public Mono cancelResponse() { - return sendEvent(new RealtimeResponseCancelEvent()); - } - - /** - * Cancels a specific response. - * - * @param responseId the response identifier. - * @return a completion signal emitted after the event is written. - */ - public Mono cancelResponse(String responseId) { - Objects.requireNonNull(responseId, "'responseId' cannot be null."); - return sendEvent(new RealtimeResponseCancelEvent().setResponseId(responseId)); - } - - /** - * Sends a function-call result and requests the next response. - * - * @param callId the function call identifier. - * @param output the serialized function result. - * @return a completion signal emitted after both events are written. - */ - public Mono sendFunctionCallOutput(String callId, String output) { - RealtimeConversationItemFunctionCallOutput item - = new RealtimeConversationItemFunctionCallOutput(callId, output); - return createConversationItem(item).then(createResponse()); - } - - /** - * Closes the WebSocket session. - * - * @return a completion signal for closing the session. - */ - @Override public Mono closeAsync() { return closeAsync(1000, ""); } - /** - * Closes the session with an application-selected WebSocket close frame. - * The first requested close frame wins when close is called more than once. - * @param code a valid WebSocket close code. - * @param reason non-null reason of at most 123 UTF-8 bytes. - * @return a completion signal, or an error if the code or reason is invalid. - */ public Mono closeAsync(int code, String reason) { try { VoiceAgentWebSocketUtils.validateClose(code, reason); @@ -380,15 +157,14 @@ public Mono closeAsync(int code, String reason) { if (existing != null) { return existing; } - Mono created = Mono.defer(() -> { - State current = state.get(); - if (current == State.CLOSED || current == State.NEW) { - state.set(State.CLOSED); + WebSocketSessionState current = state.get(); + if (current == WebSocketSessionState.CLOSED || current == WebSocketSessionState.NEW) { + state.set(WebSocketSessionState.CLOSED); events.tryEmitComplete(); return Mono.empty(); } - state.set(State.CLOSING); + state.set(WebSocketSessionState.CLOSING); WebsocketOutbound currentOutbound = outbound.get(); Channel currentChannel = channel.get(); Mono graceful = currentOutbound == null ? Mono.empty() : currentOutbound.sendClose(code, reason); @@ -400,16 +176,9 @@ public Mono closeAsync(int code, String reason) { return Mono.empty(); }).doFinally(signal -> terminateNormally()); }).cache(); - - if (closeOperation.compareAndSet(null, created)) { - return created; - } - return closeOperation.get(); + return closeOperation.compareAndSet(null, created) ? created : closeOperation.get(); } - /** - * Closes the WebSocket session synchronously. - */ @Override public void close() { closeAsync().block(options.getCloseTimeout().plusSeconds(1)); @@ -421,16 +190,16 @@ private Mono openWebSocket(String token) { .doOnConnected(connection -> connection.addHandlerLast("voiceAgentHandshakeResponseObserver", new VoiceAgentWebSocketHandshakeHandler(this::terminateWithError))) .headers(headers -> { - for (HttpHeader header : VoiceAgentWebSocketUtils.buildHeaders(configuration, options, token)) { + for (HttpHeader header : headersFactory.apply(token)) { headers.set(header.getName(), header.getValue()); } }); - WebsocketClientSpec spec = WebsocketClientSpec.builder() - .protocols(VoiceAgentWebSocketUtils.SUBPROTOCOL) - .maxFramePayloadLength(options.getMaxMessageSize()) - .build(); - - return client.websocket(spec).uri(websocketUri.toString()).connect().flatMap(connection -> { + WebsocketClientSpec.Builder specBuilder + = WebsocketClientSpec.builder().maxFramePayloadLength(options.getMaxMessageSize()); + if (subprotocol != null) { + specBuilder.protocols(subprotocol); + } + return client.websocket(specBuilder.build()).uri(websocketUri.toString()).connect().flatMap(connection -> { if (!(connection instanceof WebsocketInbound) || !(connection instanceof WebsocketOutbound)) { return Mono.error(new IllegalStateException("The WebSocket transport returned an invalid connection.")); } @@ -448,14 +217,12 @@ private static int toConnectTimeoutMillis(Duration timeout) { private Mono handleConnection(WebsocketInbound inbound, WebsocketOutbound outbound) { this.outbound.set(outbound); inbound.withConnection(connection -> channel.set(connection.channel())); - state.set(State.OPEN); + state.set(WebSocketSessionState.OPEN); ready.tryEmitEmpty(); - inbound.receiveCloseStatus().subscribe(status -> { closeCode = status.code(); closeReason = status.reasonText(); }, error -> LOGGER.atVerbose().addKeyValue("error", error.getMessage()).log("Close status unavailable.")); - Disposable receive = inbound.aggregateFrames(options.getMaxMessageSize()) .receiveFrames() .subscribe(this::handleFrame, this::terminateWithError, this::terminateNormally); @@ -468,8 +235,8 @@ private void handleFrame(WebSocketFrame frame) { try { byte[] bytes = new byte[frame.content().readableBytes()]; frame.content().getBytes(frame.content().readerIndex(), bytes); - RealtimeServerEvent event - = VoiceAgentWebSocketUtils.deserializeEvent(VoiceAgentWebSocketUtils.decodeEvent(bytes)); + String json = VoiceAgentWebSocketUtils.decodeEvent(bytes); + BinaryData event = BinaryData.fromString(json); Sinks.EmitResult result = events.tryEmitNext(event); if (result == Sinks.EmitResult.FAIL_OVERFLOW || result == Sinks.EmitResult.FAIL_ZERO_SUBSCRIBER) { switch (options.getOverflowStrategy()) { @@ -498,7 +265,7 @@ private void handleFrame(WebSocketFrame frame) { failure = callbackError; } } - closeWithProtocolError(1007, "Invalid JSON event", failure); + closeWithProtocolError(1007, "Invalid UTF-8 message", failure); } } } @@ -515,8 +282,8 @@ private void closeWithProtocolError(int code, String reason, Throwable error) { private void terminateWithError(Throwable error) { Throwable mappedError = mapHandshakeError(error); - State previous = state.getAndSet(State.CLOSED); - if (previous == State.CLOSED) { + WebSocketSessionState previous = state.getAndSet(WebSocketSessionState.CLOSED); + if (previous == WebSocketSessionState.CLOSED) { return; } ready.tryEmitError(mappedError); @@ -556,11 +323,11 @@ private Throwable mapHandshakeError(Throwable error) { } private void terminateNormally() { - State previous = state.getAndSet(State.CLOSED); - if (previous == State.CLOSED) { + WebSocketSessionState previous = state.getAndSet(WebSocketSessionState.CLOSED); + if (previous == WebSocketSessionState.CLOSED) { return; } - if (previous == State.CONNECTING) { + if (previous == WebSocketSessionState.CONNECTING) { ready.tryEmitError(new IllegalStateException("The WebSocket closed before the handshake completed.")); } events.tryEmitComplete(); @@ -581,7 +348,7 @@ private void disposeReceive() { private Channel requireOpenChannel() { Channel current = channel.get(); - if (state.get() != State.OPEN || current == null || !current.isActive()) { + if (state.get() != WebSocketSessionState.OPEN || current == null || !current.isActive()) { throw LOGGER .logExceptionAsError(new IllegalStateException("The voice-agent WebSocket session is not open.")); } @@ -618,11 +385,4 @@ private HttpClient configureProxy(HttpClient client) { }); } - private static String serialize(RealtimeClientEvent event) throws IOException { - return event.toJsonString(); - } - - private enum State { - NEW, CONNECTING, OPEN, CLOSING, CLOSED - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionState.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionState.java new file mode 100644 index 0000000000000..9a88118abc8cf --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionState.java @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation.realtime; + +/** + * Connection lifecycle shared by the blocking and asynchronous WebSocket transports. + */ +public enum WebSocketSessionState { + NEW, CONNECTING, OPEN, CLOSING, CLOSED +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionTransport.java similarity index 60% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClient.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionTransport.java index 7227280cd8326..1992a3fcc74f7 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClient.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketSessionTransport.java @@ -1,35 +1,26 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.azure.ai.agents; - -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketHttpResponse; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.ai.agents.models.RealtimeClientEvent; -import com.azure.ai.agents.models.RealtimeConversationItemCreateEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent; -import com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent; -import com.azure.ai.agents.models.RealtimeResponseCancelEvent; -import com.azure.ai.agents.models.RealtimeResponseCreateEvent; -import com.azure.ai.agents.models.RealtimeConversationItem; -import com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput; -import com.azure.ai.agents.models.RealtimeConversationItemUserMessage; -import com.azure.ai.agents.models.RealtimeServerEvent; -import com.azure.ai.agents.models.VoiceAgentResponseCreateOptions; -import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; +package com.azure.ai.agents.implementation.realtime; + import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.HttpResponseException; import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.HttpHeader; +import com.azure.core.http.HttpHeaders; import com.azure.core.http.ProxyOptions; import com.azure.core.util.BinaryData; -import com.openai.models.realtime.RealtimeConversationItemUserMessage.Content; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; +import okhttp3.Credentials; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + import java.io.IOException; import java.net.Proxy; import java.net.ProxySelector; @@ -38,7 +29,6 @@ import java.nio.charset.CharacterCodingException; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.Base64; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -51,125 +41,88 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import java.util.regex.Pattern; -import okhttp3.Credentials; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okhttp3.WebSocketListener; -import okio.ByteString; /** - * A synchronous bidirectional realtime session connected to a Foundry voice agent. + * Shared blocking WebSocket connection and I/O, independent of the asynchronous transport. */ -@Beta(warningText = "This class is in preview and may change in future releases.") -public final class BetaVoiceAgentWebSocketSessionClient implements AutoCloseable { - private static final ClientLogger LOGGER = new ClientLogger(BetaVoiceAgentWebSocketSessionClient.class); +public final class WebSocketSessionTransport implements AutoCloseable { + private static final ClientLogger LOGGER = new ClientLogger(WebSocketSessionTransport.class); private final URI websocketUri; - private final VoiceAgentWebSocketConnectionOptions options; + private final WebSocketTransportOptions options; private final OkHttpClient httpClient; private final BlockingQueue events; private final int receiveBufferCapacity; private final CountDownLatch handshakeCompleted = new CountDownLatch(1); private final CountDownLatch closeCompleted = new CountDownLatch(1); private final AtomicReference connectionError = new AtomicReference<>(); - private final AtomicBoolean handshakeSucceeded = new AtomicBoolean(); private final AtomicBoolean receiveClaimed = new AtomicBoolean(); - private final AtomicBoolean open = new AtomicBoolean(); - private final AtomicBoolean closed = new AtomicBoolean(); + private final AtomicReference state = new AtomicReference<>(WebSocketSessionState.NEW); private final AtomicBoolean clientShutdown = new AtomicBoolean(); - private volatile WebSocket webSocket; private volatile Integer closeCode; private volatile String closeReason; - private BetaVoiceAgentWebSocketSessionClient(VoiceAgentWebSocketClientConfiguration configuration, String agentName, - VoiceAgentWebSocketConnectionOptions options) { + private WebSocketSessionTransport(VoiceAgentWebSocketClientConfiguration configuration, URI websocketUri, + WebSocketTransportOptions options) { this.options = options; this.receiveBufferCapacity = options.getReceiveBufferCapacity(); this.events = new ArrayBlockingQueue<>(receiveBufferCapacity + 1); - this.websocketUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, agentName, options); + this.websocketUri = Objects.requireNonNull(websocketUri, "'websocketUri' cannot be null."); + this.httpClient = createHttpClient(configuration, options); + } + + private void open(VoiceAgentWebSocketClientConfiguration configuration, String subprotocol, + Function headersFactory) { + state.set(WebSocketSessionState.CONNECTING); String token = configuration.getCredential() .getTokenSync(VoiceAgentWebSocketUtils.createTokenRequestContext()) .getToken(); - this.httpClient = createHttpClient(configuration, options); - Request.Builder request = new Request.Builder().url(websocketUri.toString()) - .header("Sec-WebSocket-Protocol", VoiceAgentWebSocketUtils.SUBPROTOCOL); - for (HttpHeader header : VoiceAgentWebSocketUtils.buildHeaders(configuration, options, token)) { + Request.Builder request = new Request.Builder().url(websocketUri.toString()); + if (subprotocol != null) { + request.header("Sec-WebSocket-Protocol", subprotocol); + } + for (HttpHeader header : headersFactory.apply(token)) { request.header(header.getName(), header.getValue()); } this.webSocket = httpClient.newWebSocket(request.build(), new Listener()); } - static BetaVoiceAgentWebSocketSessionClient connect(VoiceAgentWebSocketClientConfiguration configuration, - String agentName, VoiceAgentWebSocketConnectionOptions options) { - BetaVoiceAgentWebSocketSessionClient session - = new BetaVoiceAgentWebSocketSessionClient(configuration, agentName, options); + public static WebSocketSessionTransport connect(VoiceAgentWebSocketClientConfiguration configuration, + URI websocketUri, WebSocketTransportOptions options, String subprotocol, + Function headersFactory) { + WebSocketSessionTransport session = new WebSocketSessionTransport(configuration, websocketUri, options); try { + session.open(configuration, subprotocol, headersFactory); session.awaitHandshake(); return session; } catch (RuntimeException error) { - session.webSocket.cancel(); + if (session.webSocket != null) { + session.webSocket.cancel(); + } session.shutdownHttpClient(); throw error; } } - /** - * Gets the WebSocket endpoint used by this session. - * - * @return the WebSocket endpoint. - */ public String getEndpoint() { return websocketUri.toString(); } - /** - * Determines whether the session is open. - * - * @return {@code true} when the session is open. - */ public boolean isOpen() { - return open.get() && !closed.get(); + return state.get() == WebSocketSessionState.OPEN; } - /** - * Gets the peer close code. - * - * @return the close code, or {@code null}. - */ public Integer getCloseCode() { return closeCode; } - /** - * Gets the peer close reason. - * - * @return the close reason, or {@code null}. - */ public String getCloseReason() { return closeReason; } - /** - * Receives typed server events in wire order. The returned stream may be iterated once. - * - * @throws IllegalStateException if the event stream has already been claimed. - * @return the server event stream. - */ - public IterableStream receiveEvents() { - return receiveEvents(null); - } - - /** - * Receives events with a timeout for each wait. A timeout leaves the session open and the iterator can be retried. - * @param timeout positive per-event timeout, or null to wait indefinitely. - * @return the single-consumer event stream. - * @throws IllegalArgumentException if timeout is zero or negative. - * @throws IllegalStateException if another receiver exists or a wait times out (with a TimeoutException cause). - */ - public IterableStream receiveEvents(Duration timeout) { + public IterableStream receiveEvents(Duration timeout) { if (timeout != null && (timeout.isZero() || timeout.isNegative())) { throw LOGGER.logExceptionAsError(new IllegalArgumentException("Receive timeout must be positive.")); } @@ -187,155 +140,29 @@ public IterableStream receiveEvents(Duration timeout) { }); } - /** - * Sends a typed realtime client event. - * - * @param event the event to send. - * @throws IllegalArgumentException if the event cannot be serialized. - * @throws IllegalStateException if the session is closed or cannot accept another event. - */ - public void sendEvent(RealtimeClientEvent event) { - Objects.requireNonNull(event, "'event' cannot be null."); - ensureOpen(); - final String json; - try { - json = event.toJsonString(); - } catch (IOException error) { - throw LOGGER.logExceptionAsError( - new IllegalArgumentException("Failed to serialize the realtime client event.", error)); - } - if (!webSocket.send(json)) { - throw LOGGER.logExceptionAsError( - new IllegalStateException("The voice-agent WebSocket send queue is full or closed.")); - } - } - - /** - * Sends a JSON object, including event types and fields unknown to this SDK. - * @param event the complete JSON event. - * @throws IllegalArgumentException if the event is not a JSON object. - * @throws IllegalStateException if the session cannot accept the event. - */ public void sendEvent(BinaryData event) { String json = VoiceAgentWebSocketUtils.validateEvent(event); - ensureOpen(); + if (!isOpen()) { + throw LOGGER + .logExceptionAsError(new IllegalStateException("The voice-agent WebSocket session is not open.")); + } if (!webSocket.send(json)) { throw LOGGER.logExceptionAsError( new IllegalStateException("The voice-agent WebSocket send queue is full or closed.")); } } - /** - * Adds a conversation item. - * - * @param item the item to add. - */ - public void createConversationItem(RealtimeConversationItem item) { - createConversationItem(item, null); - } - - /** - * Adds a conversation item after another item. - * - * @param item the item to add. - * @param previousItemId the preceding item identifier. - */ - public void createConversationItem(RealtimeConversationItem item, String previousItemId) { - Objects.requireNonNull(item, "'item' cannot be null."); - sendEvent(new RealtimeConversationItemCreateEvent(item).setPreviousItemId(previousItemId)); - } - - /** - * Adds a user text message. - * - * @param text the user message. - */ - public void sendText(String text) { - Objects.requireNonNull(text, "'text' cannot be null."); - Content content = Content.builder().type(Content.Type.INPUT_TEXT).text(text).build(); - createConversationItem(new RealtimeConversationItemUserMessage(Collections.singletonList(content))); - } - - /** - * Appends audio to the input buffer. - * - * @param audio the audio bytes. - */ - public void appendInputAudio(BinaryData audio) { - Objects.requireNonNull(audio, "'audio' cannot be null."); - sendEvent(new RealtimeInputAudioBufferAppendEvent(Base64.getEncoder().encodeToString(audio.toBytes()))); - } - - /** Clears the input audio buffer. */ - public void clearInputAudio() { - sendEvent(new RealtimeInputAudioBufferClearEvent()); - } - - /** Commits the input audio buffer. */ - public void commitInputAudio() { - sendEvent(new RealtimeInputAudioBufferCommitEvent()); - } - - /** Requests a response using the voice agent's configuration. */ - public void createResponse() { - sendEvent(new RealtimeResponseCreateEvent()); - } - - /** - * Requests a response with per-response options. - * - * @param responseOptions response options. - */ - public void createResponse(VoiceAgentResponseCreateOptions responseOptions) { - Objects.requireNonNull(responseOptions, "'responseOptions' cannot be null."); - sendEvent(new RealtimeResponseCreateEvent().setResponse(responseOptions)); - } - - /** Cancels the active response. */ - public void cancelResponse() { - sendEvent(new RealtimeResponseCancelEvent()); - } - - /** - * Cancels a specific response. - * - * @param responseId the response identifier. - */ - public void cancelResponse(String responseId) { - Objects.requireNonNull(responseId, "'responseId' cannot be null."); - sendEvent(new RealtimeResponseCancelEvent().setResponseId(responseId)); - } - - /** - * Sends a function-call result and requests the next response. - * - * @param callId the function call identifier. - * @param output the serialized function output. - */ - public void sendFunctionCallOutput(String callId, String output) { - createConversationItem(new RealtimeConversationItemFunctionCallOutput(callId, output)); - createResponse(); - } - - /** Closes the session. */ @Override public void close() { close(1000, ""); } - /** - * Closes the session with an application-selected WebSocket close frame. - * @param code a valid WebSocket close code. - * @param reason non-null reason of at most 123 UTF-8 bytes. - * @throws IllegalArgumentException if the code or reason is invalid. - */ public void close(int code, String reason) { VoiceAgentWebSocketUtils.validateClose(code, reason); - if (!closed.compareAndSet(false, true)) { + if (!state.compareAndSet(WebSocketSessionState.OPEN, WebSocketSessionState.CLOSING)) { shutdownHttpClient(); return; } - open.set(false); if (!webSocket.close(code, reason)) { webSocket.cancel(); closeCompleted.countDown(); @@ -348,6 +175,7 @@ public void close(int code, String reason) { Thread.currentThread().interrupt(); webSocket.cancel(); } finally { + state.set(WebSocketSessionState.CLOSED); signal(EventSignal.complete()); shutdownHttpClient(); } @@ -366,9 +194,6 @@ private void awaitHandshake() { throw LOGGER.logExceptionAsError( new IllegalStateException("Interrupted while opening the voice-agent WebSocket session.", error)); } - if (handshakeSucceeded.get()) { - return; - } Throwable error = connectionError.get(); if (error instanceof RuntimeException) { throw LOGGER.logExceptionAsError((RuntimeException) error); @@ -379,13 +204,6 @@ private void awaitHandshake() { } } - private void ensureOpen() { - if (!isOpen()) { - throw LOGGER - .logExceptionAsError(new IllegalStateException("The voice-agent WebSocket session is not open.")); - } - } - private void fail(Throwable error, Response response) { Throwable mapped; try { @@ -395,9 +213,10 @@ private void fail(Throwable error, Response response) { response.close(); } } - connectionError.compareAndSet(null, mapped); - open.set(false); - closed.set(true); + WebSocketSessionState previous = state.getAndSet(WebSocketSessionState.CLOSED); + if (previous == WebSocketSessionState.CONNECTING) { + connectionError.compareAndSet(null, mapped); + } handshakeCompleted.countDown(); signal(EventSignal.error(mapped)); closeCompleted.countDown(); @@ -443,8 +262,7 @@ private synchronized void signal(EventSignal signal) { if (current != null) { current.cancel(); } - open.set(false); - closed.set(true); + state.set(WebSocketSessionState.CLOSED); shutdownHttpClient(); } } @@ -456,8 +274,8 @@ private void shutdownHttpClient() { } } - static OkHttpClient createHttpClient(VoiceAgentWebSocketClientConfiguration configuration, - VoiceAgentWebSocketConnectionOptions options) { + public static OkHttpClient createHttpClient(VoiceAgentWebSocketClientConfiguration configuration, + WebSocketTransportOptions options) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(options.getHandshakeTimeout().toMillis(), TimeUnit.MILLISECONDS) .readTimeout(0, TimeUnit.MILLISECONDS) @@ -483,7 +301,8 @@ public List select(URI uri) { @Override public void connectFailed(URI uri, SocketAddress address, IOException error) { LOGGER.atVerbose() - .addKeyValue("uri", uri) + .addKeyValue("host", uri.getHost()) + .addKeyValue("path", uri.getPath()) .addKeyValue("proxyAddress", address) .log("Failed to connect through the configured proxy."); } @@ -503,8 +322,7 @@ public void connectFailed(URI uri, SocketAddress address, IOException error) { private final class Listener extends WebSocketListener { @Override public void onOpen(WebSocket webSocket, Response response) { - handshakeSucceeded.set(true); - open.set(true); + state.compareAndSet(WebSocketSessionState.CONNECTING, WebSocketSessionState.OPEN); handshakeCompleted.countDown(); } @@ -515,11 +333,7 @@ public void onMessage(WebSocket webSocket, String text) { webSocket.close(1009, "Message too large"); return; } - try { - signal(EventSignal.event(VoiceAgentWebSocketUtils.deserializeEvent(text))); - } catch (IOException | RuntimeException error) { - malformedEvent(webSocket, error); - } + signal(EventSignal.event(BinaryData.fromString(text))); } @Override @@ -545,8 +359,8 @@ private void malformedEvent(WebSocket webSocket, Throwable error) { error = callbackError; } } - fail(new IllegalArgumentException("Invalid JSON event.", error), null); - webSocket.close(1007, "Invalid JSON event"); + fail(new IllegalArgumentException("Invalid UTF-8 message.", error), null); + webSocket.close(1007, "Invalid UTF-8 message"); } @Override @@ -560,8 +374,11 @@ public void onClosing(WebSocket webSocket, int code, String reason) { public void onClosed(WebSocket webSocket, int code, String reason) { closeCode = code; closeReason = reason; - open.set(false); - closed.set(true); + WebSocketSessionState previous = state.getAndSet(WebSocketSessionState.CLOSED); + if (previous == WebSocketSessionState.CONNECTING) { + connectionError.compareAndSet(null, + new IllegalStateException("The WebSocket closed before the handshake completed.")); + } signal(EventSignal.complete()); handshakeCompleted.countDown(); closeCompleted.countDown(); @@ -575,17 +392,17 @@ public void onFailure(WebSocket webSocket, Throwable error, Response response) { } private static final class EventSignal { - private final RealtimeServerEvent event; + private final BinaryData event; private final Throwable error; private final boolean complete; - private EventSignal(RealtimeServerEvent event, Throwable error, boolean complete) { + private EventSignal(BinaryData event, Throwable error, boolean complete) { this.event = event; this.error = error; this.complete = complete; } - private static EventSignal event(RealtimeServerEvent event) { + private static EventSignal event(BinaryData event) { return new EventSignal(event, null, false); } @@ -598,7 +415,7 @@ private static EventSignal complete() { } } - private static final class EventIterator implements Iterator { + private static final class EventIterator implements Iterator { private final BlockingQueue events; private final Duration timeout; private EventSignal next; @@ -634,11 +451,11 @@ public boolean hasNext() { } @Override - public RealtimeServerEvent next() { + public BinaryData next() { if (!hasNext()) { throw new NoSuchElementException(); } - RealtimeServerEvent event = next.event; + BinaryData event = next.event; next = null; return event; } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketTransportOptions.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketTransportOptions.java new file mode 100644 index 0000000000000..71599f32f3b4a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/implementation/realtime/WebSocketTransportOptions.java @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation.realtime; + +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; +import com.azure.ai.agents.models.VoiceAgentWebSocketOverflowStrategy; +import java.time.Duration; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * Immutable transport settings captured from a protocol-specific public options bag. + */ +public final class WebSocketTransportOptions { + private final int receiveBufferCapacity; + private final int maxMessageSize; + private final VoiceAgentWebSocketOverflowStrategy overflowStrategy; + private final Consumer malformedEventHandler; + private final Duration handshakeTimeout; + private final Duration closeTimeout; + + public WebSocketTransportOptions(VoiceAgentWebSocketConnectionOptions options) { + Objects.requireNonNull(options, "'options' cannot be null."); + this.receiveBufferCapacity = options.getReceiveBufferCapacity(); + this.maxMessageSize = options.getMaxMessageSize(); + this.overflowStrategy = options.getOverflowStrategy(); + this.malformedEventHandler = options.getMalformedEventHandler(); + this.handshakeTimeout = options.getHandshakeTimeout(); + this.closeTimeout = options.getCloseTimeout(); + } + + public WebSocketTransportOptions(VoiceAgentLiveWebSocketConnectionOptions options) { + Objects.requireNonNull(options, "'options' cannot be null."); + this.receiveBufferCapacity = options.getReceiveBufferCapacity(); + this.maxMessageSize = options.getMaxMessageSize(); + this.overflowStrategy = options.getOverflowStrategy(); + this.malformedEventHandler = options.getMalformedEventHandler(); + this.handshakeTimeout = options.getHandshakeTimeout(); + this.closeTimeout = options.getCloseTimeout(); + } + + public int getReceiveBufferCapacity() { + return receiveBufferCapacity; + } + + public int getMaxMessageSize() { + return maxMessageSize; + } + + public VoiceAgentWebSocketOverflowStrategy getOverflowStrategy() { + return overflowStrategy; + } + + public Consumer getMalformedEventHandler() { + return malformedEventHandler; + } + + public Duration getHandshakeTimeout() { + return handshakeTimeout; + } + + public Duration getCloseTimeout() { + return closeTimeout; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AgentDefinition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AgentDefinition.java index e592e63909611..e01ddede048ff 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AgentDefinition.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AgentDefinition.java @@ -115,7 +115,7 @@ public static AgentDefinition fromJson(JsonReader jsonReader) throws IOException } else if ("external".equals(discriminatorValue)) { return ExternalAgentDefinition.fromJson(readerToUse.reset()); } else if ("voice".equals(discriminatorValue)) { - return VoiceAgentDefinition.fromJson(readerToUse.reset()); + return VoiceAgentBaseDefinition.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscription.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscription.java deleted file mode 100644 index 3f141148b5b06..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscription.java +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.AudioTranscription.Delay; -import java.io.IOException; -import java.util.List; - -/** - * The AudioTranscription model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class AudioTranscription implements JsonSerializable { - - /* - * The model to use for transcription. Current options are `whisper-1`, `gpt-transcribe`, `gpt-live-transcribe`, - * `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, `gpt-4o-transcribe`, `gpt-4o-transcribe-diarize`, - * and `gpt-realtime-whisper`. Use `gpt-4o-transcribe-diarize` when you need diarization with speaker labels. - */ - @Generated - private AudioTranscriptionModel model; - - /* - * The language of the input audio. Supplying the input language in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format - * will improve accuracy and latency. - */ - @Generated - private String language; - - /* - * Possible languages of the input audio, in [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) - * format. Supported by `gpt-transcribe` and `gpt-live-transcribe`. - */ - @Generated - private List languages; - - /* - * Words or phrases to guide transcription of the input audio. Supported by `gpt-transcribe` and - * `gpt-live-transcribe`. - */ - @Generated - private List keywords; - - /* - * 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](https://developers.openai.com/api/docs/guides/speech-to-text#prompting). - * 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. - */ - @Generated - private String prompt; - - /* - * 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. - */ - @Generated - private Delay delay; - - /** - * Creates an instance of AudioTranscription class. - */ - @Generated - public AudioTranscription() { - } - - /** - * Get the model property: The model to use for transcription. Current options are `whisper-1`, `gpt-transcribe`, - * `gpt-live-transcribe`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, `gpt-4o-transcribe`, - * `gpt-4o-transcribe-diarize`, and `gpt-realtime-whisper`. Use `gpt-4o-transcribe-diarize` when you need - * diarization with speaker labels. - * - * @return the model value. - */ - @Generated - public AudioTranscriptionModel getModel() { - return this.model; - } - - /** - * Set the model property: The model to use for transcription. Current options are `whisper-1`, `gpt-transcribe`, - * `gpt-live-transcribe`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, `gpt-4o-transcribe`, - * `gpt-4o-transcribe-diarize`, and `gpt-realtime-whisper`. Use `gpt-4o-transcribe-diarize` when you need - * diarization with speaker labels. - * - * @param model the model value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setModel(AudioTranscriptionModel model) { - this.model = model; - return this; - } - - /** - * Get the language property: The language of the input audio. Supplying the input language in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format - * will improve accuracy and latency. - * - * @return the language value. - */ - @Generated - public String getLanguage() { - return this.language; - } - - /** - * Set the language property: The language of the input audio. Supplying the input language in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format - * will improve accuracy and latency. - * - * @param language the language value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setLanguage(String language) { - this.language = language; - return this; - } - - /** - * Get the languages property: Possible languages of the input audio, in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format. Supported by `gpt-transcribe` and - * `gpt-live-transcribe`. - * - * @return the languages value. - */ - @Generated - public List getLanguages() { - return this.languages; - } - - /** - * Set the languages property: Possible languages of the input audio, in - * [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format. Supported by `gpt-transcribe` and - * `gpt-live-transcribe`. - * - * @param languages the languages value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setLanguages(List languages) { - this.languages = languages; - return this; - } - - /** - * Get the keywords property: Words or phrases to guide transcription of the input audio. Supported by - * `gpt-transcribe` and `gpt-live-transcribe`. - * - * @return the keywords value. - */ - @Generated - public List getKeywords() { - return this.keywords; - } - - /** - * Set the keywords property: Words or phrases to guide transcription of the input audio. Supported by - * `gpt-transcribe` and `gpt-live-transcribe`. - * - * @param keywords the keywords value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setKeywords(List keywords) { - this.keywords = keywords; - return this; - } - - /** - * Get the prompt property: 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](https://developers.openai.com/api/docs/guides/speech-to-text#prompting). - * 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. - * - * @return the prompt value. - */ - @Generated - public String getPrompt() { - return this.prompt; - } - - /** - * Set the prompt property: 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](https://developers.openai.com/api/docs/guides/speech-to-text#prompting). - * 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. - * - * @param prompt the prompt value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setPrompt(String prompt) { - this.prompt = prompt; - return this; - } - - /** - * Get the delay property: 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. - * - * @return the delay value. - */ - @Generated - public Delay getDelay() { - return this.delay; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - // AI Tooling: openai-java de-dup - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("model", this.model == null ? null : this.model.toString()); - jsonWriter.writeStringField("language", this.language); - jsonWriter.writeArrayField("languages", this.languages, (writer, element) -> writer.writeString(element)); - jsonWriter.writeArrayField("keywords", this.keywords, (writer, element) -> writer.writeString(element)); - jsonWriter.writeStringField("prompt", this.prompt); - jsonWriter.writeStringField("delay", this.delay == null ? null : this.delay.asString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of AudioTranscription from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of AudioTranscription if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IOException If an error occurs while reading the AudioTranscription. - */ - public static AudioTranscription fromJson(JsonReader jsonReader) throws IOException { - // AI Tooling: openai-java de-dup - return jsonReader.readObject(reader -> { - AudioTranscription deserializedAudioTranscription = new AudioTranscription(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("model".equals(fieldName)) { - deserializedAudioTranscription.model = AudioTranscriptionModel.fromString(reader.getString()); - } else if ("language".equals(fieldName)) { - deserializedAudioTranscription.language = reader.getString(); - } else if ("languages".equals(fieldName)) { - List languages = reader.readArray(reader1 -> reader1.getString()); - deserializedAudioTranscription.languages = languages; - } else if ("keywords".equals(fieldName)) { - List keywords = reader.readArray(reader1 -> reader1.getString()); - deserializedAudioTranscription.keywords = keywords; - } else if ("prompt".equals(fieldName)) { - deserializedAudioTranscription.prompt = reader.getString(); - } else if ("delay".equals(fieldName)) { - deserializedAudioTranscription.delay = reader.getNullable(r -> Delay.of(r.getString())); - } else { - reader.skipChildren(); - } - } - return deserializedAudioTranscription; - }); - } - - /** - * Set the delay property: 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. - * - * @param delay the delay value to set. - * @return the AudioTranscription object itself. - */ - @Generated - public AudioTranscription setDelay(Delay delay) { - this.delay = delay; - return this; - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscriptionModel.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscriptionModel.java deleted file mode 100644 index c0073a3c5aae1..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AudioTranscriptionModel.java +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for AudioTranscriptionModel. - */ -@Beta(warningText = "Preview API.") -public final class AudioTranscriptionModel extends ExpandableStringEnum { - - /** - * Static value whisper-1 for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel WHISPER_1 = fromString("whisper-1"); - - /** - * Static value gpt-transcribe for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_TRANSCRIBE = fromString("gpt-transcribe"); - - /** - * Static value gpt-live-transcribe for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_LIVE_TRANSCRIBE = fromString("gpt-live-transcribe"); - - /** - * Static value gpt-4o-mini-transcribe for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_4O_MINI_TRANSCRIBE = fromString("gpt-4o-mini-transcribe"); - - /** - * Static value gpt-4o-mini-transcribe-2025-12-15 for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_4O_MINI_TRANSCRIBE_2025_12_15 - = fromString("gpt-4o-mini-transcribe-2025-12-15"); - - /** - * Static value gpt-4o-transcribe for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_4O_TRANSCRIBE = fromString("gpt-4o-transcribe"); - - /** - * Static value gpt-4o-transcribe-diarize for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_4O_TRANSCRIBE_DIARIZE = fromString("gpt-4o-transcribe-diarize"); - - /** - * Static value gpt-realtime-whisper for AudioTranscriptionModel. - */ - @Generated - public static final AudioTranscriptionModel GPT_REALTIME_WHISPER = fromString("gpt-realtime-whisper"); - - /** - * Creates a new instance of AudioTranscriptionModel value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public AudioTranscriptionModel() { - } - - /** - * Creates or finds a AudioTranscriptionModel from its string representation. - * - * @param name a name to look for. - * @return the corresponding AudioTranscriptionModel. - */ - @Generated - public static AudioTranscriptionModel fromString(String name) { - return fromString(name, AudioTranscriptionModel.class); - } - - /** - * Gets known AudioTranscriptionModel values. - * - * @return known AudioTranscriptionModel values. - */ - @Generated - public static Collection values() { - return values(AudioTranscriptionModel.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java index 9cfae0c2804d4..e1eb7ee3ac2f9 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java @@ -3,6 +3,7 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.StructuredInputJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; @@ -114,8 +115,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * it was pointing to JSON null. * @throws IOException If an error occurs while reading the AzureCreateResponseOptions. */ - @Generated public static AzureCreateResponseOptions fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: Preserve structured input JSON without numeric coercion. return jsonReader.readObject(reader -> { AzureCreateResponseOptions deserializedAzureCreateResponseOptions = new AzureCreateResponseOptions(); while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -124,8 +125,8 @@ public static AzureCreateResponseOptions fromJson(JsonReader jsonReader) throws if ("agent_reference".equals(fieldName)) { deserializedAzureCreateResponseOptions.agentReference = AgentReference.fromJson(reader); } else if ("structured_inputs".equals(fieldName)) { - Map structuredInputs = reader.readMap(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); + Map structuredInputs + = reader.readMap(reader1 -> reader1.getNullable(StructuredInputJsonHelper::readJsonValue)); deserializedAzureCreateResponseOptions.structuredInputs = structuredInputs; } else if ("user_security_context".equals(fieldName)) { deserializedAzureCreateResponseOptions.userSecurityContext diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTeamsPhoneExtensibilityTelephonyBindingInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTeamsPhoneExtensibilityTelephonyBindingInput.java deleted file mode 100644 index 978a05c0a6678..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTeamsPhoneExtensibilityTelephonyBindingInput.java +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The request to create a Microsoft Teams Phone extensibility binding. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class CreateTeamsPhoneExtensibilityTelephonyBindingInput extends CreateTelephonyBindingInput { - - /* - * The telephony provider. - */ - @Generated - private TelephonyProvider provider = TelephonyProvider.TEAMS_PHONE_EXTENSIBILITY; - - /* - * The optional display phone number for the Teams resource account. - */ - @Generated - private String phoneNumber; - - /* - * The Microsoft Teams resource-account object identifier as a GUID. - */ - @Generated - private final String resourceAccountObjectId; - - /** - * Creates an instance of CreateTeamsPhoneExtensibilityTelephonyBindingInput class. - * - * @param connectionName the connectionName value to set. - * @param resourceAccountObjectId the resourceAccountObjectId value to set. - */ - @Generated - public CreateTeamsPhoneExtensibilityTelephonyBindingInput(String connectionName, String resourceAccountObjectId) { - super(connectionName); - this.resourceAccountObjectId = resourceAccountObjectId; - } - - /** - * Get the provider property: The telephony provider. - * - * @return the provider value. - */ - @Generated - @Override - public TelephonyProvider getProvider() { - return this.provider; - } - - /** - * Get the phoneNumber property: The optional display phone number for the Teams resource account. - * - * @return the phoneNumber value. - */ - @Generated - public String getPhoneNumber() { - return this.phoneNumber; - } - - /** - * Set the phoneNumber property: The optional display phone number for the Teams resource account. - * - * @param phoneNumber the phoneNumber value to set. - * @return the CreateTeamsPhoneExtensibilityTelephonyBindingInput object itself. - */ - @Generated - public CreateTeamsPhoneExtensibilityTelephonyBindingInput setPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; - return this; - } - - /** - * Get the resourceAccountObjectId property: The Microsoft Teams resource-account object identifier as a GUID. - * - * @return the resourceAccountObjectId value. - */ - @Generated - public String getResourceAccountObjectId() { - return this.resourceAccountObjectId; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public CreateTeamsPhoneExtensibilityTelephonyBindingInput setLabel(String label) { - super.setLabel(label); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("label", getLabel()); - jsonWriter.writeStringField("resource_account_object_id", this.resourceAccountObjectId); - jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); - jsonWriter.writeStringField("phone_number", this.phoneNumber); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of CreateTeamsPhoneExtensibilityTelephonyBindingInput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of CreateTeamsPhoneExtensibilityTelephonyBindingInput if the JsonReader was pointing to an - * instance of it, or null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the CreateTeamsPhoneExtensibilityTelephonyBindingInput. - */ - @Generated - public static CreateTeamsPhoneExtensibilityTelephonyBindingInput fromJson(JsonReader jsonReader) - throws IOException { - return jsonReader.readObject(reader -> { - String connectionName = null; - String label = null; - String resourceAccountObjectId = null; - TelephonyProvider provider = TelephonyProvider.TEAMS_PHONE_EXTENSIBILITY; - String phoneNumber = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("connection_name".equals(fieldName)) { - connectionName = reader.getString(); - } else if ("label".equals(fieldName)) { - label = reader.getString(); - } else if ("resource_account_object_id".equals(fieldName)) { - resourceAccountObjectId = reader.getString(); - } else if ("provider".equals(fieldName)) { - provider = TelephonyProvider.fromString(reader.getString()); - } else if ("phone_number".equals(fieldName)) { - phoneNumber = reader.getString(); - } else { - reader.skipChildren(); - } - } - CreateTeamsPhoneExtensibilityTelephonyBindingInput deserializedCreateTeamsPhoneExtensibilityTelephonyBindingInput - = new CreateTeamsPhoneExtensibilityTelephonyBindingInput(connectionName, resourceAccountObjectId); - deserializedCreateTeamsPhoneExtensibilityTelephonyBindingInput.setLabel(label); - deserializedCreateTeamsPhoneExtensibilityTelephonyBindingInput.provider = provider; - deserializedCreateTeamsPhoneExtensibilityTelephonyBindingInput.phoneNumber = phoneNumber; - return deserializedCreateTeamsPhoneExtensibilityTelephonyBindingInput; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyBindingInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyBindingInput.java deleted file mode 100644 index d8e8c0a3c47d6..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyBindingInput.java +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The request to create a telephony binding. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class CreateTelephonyBindingInput implements JsonSerializable { - - /* - * The telephony provider. - */ - @Generated - private TelephonyProvider provider = TelephonyProvider.fromString("CreateTelephonyBindingInput"); - - /* - * The Foundry connection name for the telephony provider. - */ - @Generated - private final String connectionName; - - /* - * An optional display label for the binding. - */ - @Generated - private String label; - - /** - * Creates an instance of CreateTelephonyBindingInput class. - * - * @param connectionName the connectionName value to set. - */ - @Generated - protected CreateTelephonyBindingInput(String connectionName) { - this.connectionName = connectionName; - } - - /** - * Get the provider property: The telephony provider. - * - * @return the provider value. - */ - @Generated - public TelephonyProvider getProvider() { - return this.provider; - } - - /** - * Get the connectionName property: The Foundry connection name for the telephony provider. - * - * @return the connectionName value. - */ - @Generated - public String getConnectionName() { - return this.connectionName; - } - - /** - * Get the label property: An optional display label for the binding. - * - * @return the label value. - */ - @Generated - public String getLabel() { - return this.label; - } - - /** - * Set the label property: An optional display label for the binding. - * - * @param label the label value to set. - * @return the CreateTelephonyBindingInput object itself. - */ - @Generated - public CreateTelephonyBindingInput setLabel(String label) { - this.label = label; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("connection_name", this.connectionName); - jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); - jsonWriter.writeStringField("label", this.label); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of CreateTelephonyBindingInput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of CreateTelephonyBindingInput if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the CreateTelephonyBindingInput. - */ - @Generated - public static CreateTelephonyBindingInput fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String discriminatorValue = null; - try (JsonReader readerToUse = reader.bufferObject()) { - // Prepare for reading - readerToUse.nextToken(); - while (readerToUse.nextToken() != JsonToken.END_OBJECT) { - String fieldName = readerToUse.getFieldName(); - readerToUse.nextToken(); - if ("provider".equals(fieldName)) { - discriminatorValue = readerToUse.getString(); - break; - } else { - readerToUse.skipChildren(); - } - } - // Use the discriminator value to determine which subtype should be deserialized. - if ("teams_phone_extensibility".equals(discriminatorValue)) { - return CreateTeamsPhoneExtensibilityTelephonyBindingInput.fromJson(readerToUse.reset()); - } else if ("twilio".equals(discriminatorValue)) { - return CreateTwilioTelephonyBindingInput.fromJson(readerToUse.reset()); - } else { - return fromJsonKnownDiscriminator(readerToUse.reset()); - } - } - }); - } - - @Generated - static CreateTelephonyBindingInput fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String connectionName = null; - TelephonyProvider provider = null; - String label = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("connection_name".equals(fieldName)) { - connectionName = reader.getString(); - } else if ("provider".equals(fieldName)) { - provider = TelephonyProvider.fromString(reader.getString()); - } else if ("label".equals(fieldName)) { - label = reader.getString(); - } else { - reader.skipChildren(); - } - } - CreateTelephonyBindingInput deserializedCreateTelephonyBindingInput - = new CreateTelephonyBindingInput(connectionName); - deserializedCreateTelephonyBindingInput.provider = provider; - deserializedCreateTelephonyBindingInput.label = label; - return deserializedCreateTelephonyBindingInput; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTwilioTelephonyBindingInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTwilioTelephonyBindingInput.java deleted file mode 100644 index 1c9c3f65edf9a..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTwilioTelephonyBindingInput.java +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The request to create a Twilio binding. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class CreateTwilioTelephonyBindingInput extends CreateTelephonyBindingInput { - - /* - * The telephony provider. - */ - @Generated - private TelephonyProvider provider = TelephonyProvider.TWILIO; - - /* - * The Twilio E.164 phone number. - */ - @Generated - private final String phoneNumber; - - /** - * Creates an instance of CreateTwilioTelephonyBindingInput class. - * - * @param connectionName the connectionName value to set. - * @param phoneNumber the phoneNumber value to set. - */ - @Generated - public CreateTwilioTelephonyBindingInput(String connectionName, String phoneNumber) { - super(connectionName); - this.phoneNumber = phoneNumber; - } - - /** - * Get the provider property: The telephony provider. - * - * @return the provider value. - */ - @Generated - @Override - public TelephonyProvider getProvider() { - return this.provider; - } - - /** - * Get the phoneNumber property: The Twilio E.164 phone number. - * - * @return the phoneNumber value. - */ - @Generated - public String getPhoneNumber() { - return this.phoneNumber; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public CreateTwilioTelephonyBindingInput setLabel(String label) { - super.setLabel(label); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("label", getLabel()); - jsonWriter.writeStringField("phone_number", this.phoneNumber); - jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of CreateTwilioTelephonyBindingInput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of CreateTwilioTelephonyBindingInput if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the CreateTwilioTelephonyBindingInput. - */ - @Generated - public static CreateTwilioTelephonyBindingInput fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String connectionName = null; - String label = null; - String phoneNumber = null; - TelephonyProvider provider = TelephonyProvider.TWILIO; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("connection_name".equals(fieldName)) { - connectionName = reader.getString(); - } else if ("label".equals(fieldName)) { - label = reader.getString(); - } else if ("phone_number".equals(fieldName)) { - phoneNumber = reader.getString(); - } else if ("provider".equals(fieldName)) { - provider = TelephonyProvider.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - CreateTwilioTelephonyBindingInput deserializedCreateTwilioTelephonyBindingInput - = new CreateTwilioTelephonyBindingInput(connectionName, phoneNumber); - deserializedCreateTwilioTelephonyBindingInput.setLabel(label); - deserializedCreateTwilioTelephonyBindingInput.provider = provider; - return deserializedCreateTwilioTelephonyBindingInput; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/DatasetReference.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/DatasetReference.java new file mode 100644 index 0000000000000..9a01d9727e301 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/DatasetReference.java @@ -0,0 +1,121 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Reference to a Foundry Dataset in the current project. Consuming operations define supported Dataset kinds and + * resolution behavior. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class DatasetReference implements JsonSerializable { + + /* + * Dataset name. + */ + @Generated + private final String name; + + /* + * Optional Dataset version. Omit to select latest when the consuming operation resolves the reference. + */ + @Generated + private String version; + + /** + * Creates an instance of DatasetReference class. + * + * @param name the name value to set. + */ + @Generated + public DatasetReference(String name) { + this.name = name; + } + + /** + * Get the name property: Dataset name. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + + /** + * Get the version property: Optional Dataset version. Omit to select latest when the consuming operation resolves + * the reference. + * + * @return the version value. + */ + @Generated + public String getVersion() { + return this.version; + } + + /** + * Set the version property: Optional Dataset version. Omit to select latest when the consuming operation resolves + * the reference. + * + * @param version the version value to set. + * @return the DatasetReference object itself. + */ + @Generated + public DatasetReference setVersion(String version) { + this.version = version; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", this.name); + jsonWriter.writeStringField("version", this.version); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of DatasetReference from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of DatasetReference if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the DatasetReference. + */ + @Generated + public static DatasetReference fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String name = null; + String version = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("name".equals(fieldName)) { + name = reader.getString(); + } else if ("version".equals(fieldName)) { + version = reader.getString(); + } else { + reader.skipChildren(); + } + } + DatasetReference deserializedDatasetReference = new DatasetReference(name); + deserializedDatasetReference.version = version; + return deserializedDatasetReference; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/InlineVoiceSubagent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/InlineVoiceSubagent.java new file mode 100644 index 0000000000000..ed57df4405cf6 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/InlineVoiceSubagent.java @@ -0,0 +1,619 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * One inline voice subagent owned and versioned with its parent Voice Agent, not a separate Agent resource. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class InlineVoiceSubagent implements JsonSerializable { + + /* + * The subagent identifier. New Handoff authoring requires `$entrypoint` as the first subagent; other values use the + * normal handoff ID grammar. + */ + @Generated + private final String id; + + /* + * The definition source. This phase supports only `inline`; referenced Agent resources are deferred. + */ + @Generated + private final String source = "inline"; + + /* + * The interaction interface. This phase supports only `voice`; text delegation is deferred. + */ + @Generated + private final String interfaceProperty = "voice"; + + /* + * A non-empty display-only description of the specialist behavior. This value is not provided to the model. + */ + @Generated + private final String displayDescription; + + /* + * The target model for a cascaded graph. Realtime graphs reject this property and retain the connection model. + */ + @Generated + private String model; + + /* + * Subagent-specific instructions. With default inheritance, non-empty instructions follow the original top-level + * instructions. Omission, null, or an empty string adds nothing after that base. With inheritance disabled, only + * this value applies. + */ + @Generated + private String instructions; + + /* + * Whether the subagent inherits the original top-level instructions before applying its own non-empty instructions. + * Defaults to true; set to false to opt out. + */ + @Generated + private Boolean inheritBaseInstructions; + + /* + * Customer tools available to this subagent. Omission or null selects an empty customer tool set. + */ + @Generated + private List tools; + + /* + * Tool-selection behavior for this subagent. If omitted, the service defaults to auto. Null also selects auto. + */ + @Generated + private BinaryData toolChoice; + + /* + * The output voice configuration activated for this subagent, using the same flat voice fields as the top-level + * audio output. Omission inherits the entrypoint configuration; a supplied object replaces the voice-specific + * settings. + */ + @Generated + private VoiceAgentVoiceConfiguration audioOutput; + + /* + * The sampling temperature for a compatible subagent model, from 0 through 2. + */ + @Generated + private Double temperature; + + /* + * The maximum output-token count for one response while this subagent is active. + */ + @Generated + private BinaryData maxResponseOutputTokens; + + /* + * Reasoning effort for a compatible subagent model. + */ + @Generated + private VoiceAgentHandoffReasoningEffort reasoningEffort; + + /* + * Voice-optimized instruction adaptation for this subagent. Null disables adaptation. + */ + @Generated + private VoiceAgentHandoffVoiceAdaptation voiceAdaptation; + + /* + * Interim-response settings for this subagent. Null disables interim responses. + */ + @Generated + private VoiceAgentInterimResponseConfiguration interimResponse; + + /* + * Outgoing handoffs from this subagent. The containing subagent supplies each condition's source. The service + * permits at most 128 conditions across the entire Agent. + */ + @Generated + private List handoffConditions; + + /** + * Creates an instance of InlineVoiceSubagent class. + * + * @param id the id value to set. + * @param displayDescription the displayDescription value to set. + */ + @Generated + public InlineVoiceSubagent(String id, String displayDescription) { + this.id = id; + this.displayDescription = displayDescription; + } + + /** + * Get the id property: The subagent identifier. New Handoff authoring requires `$entrypoint` as the first subagent; + * other values use the normal handoff ID grammar. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the source property: The definition source. This phase supports only `inline`; referenced Agent resources are + * deferred. + * + * @return the source value. + */ + @Generated + public String getSource() { + return this.source; + } + + /** + * Get the interfaceProperty property: The interaction interface. This phase supports only `voice`; text delegation + * is deferred. + * + * @return the interfaceProperty value. + */ + @Generated + public String getInterfaceProperty() { + return this.interfaceProperty; + } + + /** + * Get the displayDescription property: A non-empty display-only description of the specialist behavior. This value + * is not provided to the model. + * + * @return the displayDescription value. + */ + @Generated + public String getDisplayDescription() { + return this.displayDescription; + } + + /** + * Get the model property: The target model for a cascaded graph. Realtime graphs reject this property and retain + * the connection model. + * + * @return the model value. + */ + @Generated + public String getModel() { + return this.model; + } + + /** + * Set the model property: The target model for a cascaded graph. Realtime graphs reject this property and retain + * the connection model. + * + * @param model the model value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setModel(String model) { + this.model = model; + return this; + } + + /** + * Get the instructions property: Subagent-specific instructions. With default inheritance, non-empty instructions + * follow the original top-level instructions. Omission, null, or an empty string adds nothing after that base. With + * inheritance disabled, only this value applies. + * + * @return the instructions value. + */ + @Generated + public String getInstructions() { + return this.instructions; + } + + /** + * Set the instructions property: Subagent-specific instructions. With default inheritance, non-empty instructions + * follow the original top-level instructions. Omission, null, or an empty string adds nothing after that base. With + * inheritance disabled, only this value applies. + * + * @param instructions the instructions value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setInstructions(String instructions) { + this.instructions = instructions; + return this; + } + + /** + * Get the inheritBaseInstructions property: Whether the subagent inherits the original top-level instructions + * before applying its own non-empty instructions. Defaults to true; set to false to opt out. + * + * @return the inheritBaseInstructions value. + */ + @Generated + public Boolean isInheritBaseInstructions() { + return this.inheritBaseInstructions; + } + + /** + * Set the inheritBaseInstructions property: Whether the subagent inherits the original top-level instructions + * before applying its own non-empty instructions. Defaults to true; set to false to opt out. + * + * @param inheritBaseInstructions the inheritBaseInstructions value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setInheritBaseInstructions(Boolean inheritBaseInstructions) { + this.inheritBaseInstructions = inheritBaseInstructions; + return this; + } + + /** + * Get the tools property: Customer tools available to this subagent. Omission or null selects an empty customer + * tool set. + * + * @return the tools value. + */ + @Generated + public List getTools() { + return this.tools; + } + + /** + * Set the tools property: Customer tools available to this subagent. Omission or null selects an empty customer + * tool set. + * + * @param tools the tools value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setTools(List tools) { + this.tools = tools; + return this; + } + + /** + * Get the toolChoice property: Tool-selection behavior for this subagent. If omitted, the service defaults to auto. + * Null also selects auto. + * + * @return the tool choice, or {@code null} when absent or JSON null. + */ + public VoiceAgentToolChoice getToolChoice() { + return this.toolChoice == null ? null : this.toolChoice.toObject(VoiceAgentToolChoice.class); + } + + /** + * Set the toolChoice property: Tool-selection behavior for this subagent. If omitted, the service defaults to auto. + * Null also selects auto. + * + * @param toolChoice the tool choice, or {@code null} to clear the property. + * @return the InlineVoiceSubagent object itself. + */ + public InlineVoiceSubagent setToolChoice(VoiceAgentToolChoice toolChoice) { + this.toolChoice = toolChoice == null ? null : BinaryData.fromObject(toolChoice); + return this; + } + + /** + * Get the audioOutput property: The output voice configuration activated for this subagent, using the same flat + * voice fields as the top-level audio output. Omission inherits the entrypoint configuration; a supplied object + * replaces the voice-specific settings. + * + * @return the audioOutput value. + */ + @Generated + public VoiceAgentVoiceConfiguration getAudioOutput() { + return this.audioOutput; + } + + /** + * Set the audioOutput property: The output voice configuration activated for this subagent, using the same flat + * voice fields as the top-level audio output. Omission inherits the entrypoint configuration; a supplied object + * replaces the voice-specific settings. + * + * @param audioOutput the audioOutput value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setAudioOutput(VoiceAgentVoiceConfiguration audioOutput) { + this.audioOutput = audioOutput; + return this; + } + + /** + * Get the temperature property: The sampling temperature for a compatible subagent model, from 0 through 2. + * + * @return the temperature value. + */ + @Generated + public Double getTemperature() { + return this.temperature; + } + + /** + * Set the temperature property: The sampling temperature for a compatible subagent model, from 0 through 2. + * + * @param temperature the temperature value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setTemperature(Double temperature) { + this.temperature = temperature; + return this; + } + + /** + * Get the maxResponseOutputTokens property: The maximum output-token count for one response while this subagent is + * active. + * + * @return the maxResponseOutputTokens value. + */ + public VoiceAgentMaxOutputTokens getMaxResponseOutputTokens() { + // AI Tooling: union type + return this.maxResponseOutputTokens == null + ? null + : this.maxResponseOutputTokens.toObject(VoiceAgentMaxOutputTokens.class); + } + + /** + * Set the maxResponseOutputTokens property: The maximum output-token count for one response while this subagent is + * active. + * + * @param maxResponseOutputTokens the maxResponseOutputTokens value to set. + * @return the InlineVoiceSubagent object itself. + */ + public InlineVoiceSubagent setMaxResponseOutputTokens(VoiceAgentMaxOutputTokens maxResponseOutputTokens) { + // AI Tooling: union type + this.maxResponseOutputTokens + = maxResponseOutputTokens == null ? null : BinaryData.fromObject(maxResponseOutputTokens); + return this; + } + + /** + * Get the reasoningEffort property: Reasoning effort for a compatible subagent model. + * + * @return the reasoningEffort value. + */ + @Generated + public VoiceAgentHandoffReasoningEffort getReasoningEffort() { + return this.reasoningEffort; + } + + /** + * Set the reasoningEffort property: Reasoning effort for a compatible subagent model. + * + * @param reasoningEffort the reasoningEffort value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setReasoningEffort(VoiceAgentHandoffReasoningEffort reasoningEffort) { + this.reasoningEffort = reasoningEffort; + return this; + } + + /** + * Get the voiceAdaptation property: Voice-optimized instruction adaptation for this subagent. Null disables + * adaptation. + * + * @return the voiceAdaptation value. + */ + @Generated + public VoiceAgentHandoffVoiceAdaptation getVoiceAdaptation() { + return this.voiceAdaptation; + } + + /** + * Set the voiceAdaptation property: Voice-optimized instruction adaptation for this subagent. Null disables + * adaptation. + * + * @param voiceAdaptation the voiceAdaptation value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setVoiceAdaptation(VoiceAgentHandoffVoiceAdaptation voiceAdaptation) { + this.voiceAdaptation = voiceAdaptation; + return this; + } + + /** + * Get the interimResponse property: Interim-response settings for this subagent. Null disables interim responses. + * + * @return the interimResponse value. + */ + @Generated + public VoiceAgentInterimResponseConfiguration getInterimResponse() { + return this.interimResponse; + } + + /** + * Set the interimResponse property: Interim-response settings for this subagent. Null disables interim responses. + * + * @param interimResponse the interimResponse value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setInterimResponse(VoiceAgentInterimResponseConfiguration interimResponse) { + this.interimResponse = interimResponse; + return this; + } + + /** + * Get the handoffConditions property: Outgoing handoffs from this subagent. The containing subagent supplies each + * condition's source. The service permits at most 128 conditions across the entire Agent. + * + * @return the handoffConditions value. + */ + @Generated + public List getHandoffConditions() { + return this.handoffConditions; + } + + /** + * Set the handoffConditions property: Outgoing handoffs from this subagent. The containing subagent supplies each + * condition's source. The service permits at most 128 conditions across the entire Agent. + * + * @param handoffConditions the handoffConditions value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setHandoffConditions(List handoffConditions) { + this.handoffConditions = handoffConditions; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("source", this.source); + jsonWriter.writeStringField("interface", this.interfaceProperty); + jsonWriter.writeStringField("description", this.displayDescription); + jsonWriter.writeStringField("model", this.model); + jsonWriter.writeStringField("instructions", this.instructions); + jsonWriter.writeBooleanField("inherit_base_instructions", this.inheritBaseInstructions); + jsonWriter.writeArrayField("tools", this.tools, (writer, element) -> writer.writeJson(element)); + if (this.toolChoice != null) { + jsonWriter.writeFieldName("tool_choice"); + this.toolChoice.writeTo(jsonWriter); + } + jsonWriter.writeJsonField("audio_output", this.audioOutput); + jsonWriter.writeNumberField("temperature", this.temperature); + if (this.maxResponseOutputTokens != null) { + jsonWriter.writeFieldName("max_response_output_tokens"); + this.maxResponseOutputTokens.writeTo(jsonWriter); + } + jsonWriter.writeStringField("reasoning_effort", + this.reasoningEffort == null ? null : this.reasoningEffort.toString()); + jsonWriter.writeJsonField("voice_adaptation", this.voiceAdaptation); + jsonWriter.writeJsonField("interim_response", this.interimResponse); + jsonWriter.writeBooleanField("parallel_tool_calls", this.parallelToolCallsEnabled); + jsonWriter.writeArrayField("handoff_conditions", this.handoffConditions, + (writer, element) -> writer.writeJson(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of InlineVoiceSubagent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of InlineVoiceSubagent if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the InlineVoiceSubagent. + */ + @Generated + public static InlineVoiceSubagent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String displayDescription = null; + String model = null; + String instructions = null; + Boolean inheritBaseInstructions = null; + List tools = null; + BinaryData toolChoice = null; + VoiceAgentVoiceConfiguration audioOutput = null; + Double temperature = null; + BinaryData maxResponseOutputTokens = null; + VoiceAgentHandoffReasoningEffort reasoningEffort = null; + VoiceAgentHandoffVoiceAdaptation voiceAdaptation = null; + VoiceAgentInterimResponseConfiguration interimResponse = null; + Boolean parallelToolCallsEnabled = null; + List handoffConditions = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("description".equals(fieldName)) { + displayDescription = reader.getString(); + } else if ("model".equals(fieldName)) { + model = reader.getString(); + } else if ("instructions".equals(fieldName)) { + instructions = reader.getString(); + } else if ("inherit_base_instructions".equals(fieldName)) { + inheritBaseInstructions = reader.getNullable(JsonReader::getBoolean); + } else if ("tools".equals(fieldName)) { + tools = reader.readArray(reader1 -> VoiceAgentTool.fromJson(reader1)); + } else if ("tool_choice".equals(fieldName)) { + toolChoice + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + } else if ("audio_output".equals(fieldName)) { + audioOutput = VoiceAgentVoiceConfiguration.fromJson(reader); + } else if ("temperature".equals(fieldName)) { + temperature = reader.getNullable(JsonReader::getDouble); + } else if ("max_response_output_tokens".equals(fieldName)) { + maxResponseOutputTokens + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + } else if ("reasoning_effort".equals(fieldName)) { + reasoningEffort = VoiceAgentHandoffReasoningEffort.fromString(reader.getString()); + } else if ("voice_adaptation".equals(fieldName)) { + voiceAdaptation = VoiceAgentHandoffVoiceAdaptation.fromJson(reader); + } else if ("interim_response".equals(fieldName)) { + interimResponse = VoiceAgentInterimResponseConfiguration.fromJson(reader); + } else if ("parallel_tool_calls".equals(fieldName)) { + parallelToolCallsEnabled = reader.getNullable(JsonReader::getBoolean); + } else if ("handoff_conditions".equals(fieldName)) { + handoffConditions = reader.readArray(reader1 -> VoiceAgentHandoffCondition.fromJson(reader1)); + } else { + reader.skipChildren(); + } + } + InlineVoiceSubagent deserializedInlineVoiceSubagent = new InlineVoiceSubagent(id, displayDescription); + deserializedInlineVoiceSubagent.model = model; + deserializedInlineVoiceSubagent.instructions = instructions; + deserializedInlineVoiceSubagent.inheritBaseInstructions = inheritBaseInstructions; + deserializedInlineVoiceSubagent.tools = tools; + deserializedInlineVoiceSubagent.toolChoice = toolChoice; + deserializedInlineVoiceSubagent.audioOutput = audioOutput; + deserializedInlineVoiceSubagent.temperature = temperature; + deserializedInlineVoiceSubagent.maxResponseOutputTokens = maxResponseOutputTokens; + deserializedInlineVoiceSubagent.reasoningEffort = reasoningEffort; + deserializedInlineVoiceSubagent.voiceAdaptation = voiceAdaptation; + deserializedInlineVoiceSubagent.interimResponse = interimResponse; + deserializedInlineVoiceSubagent.parallelToolCallsEnabled = parallelToolCallsEnabled; + deserializedInlineVoiceSubagent.handoffConditions = handoffConditions; + return deserializedInlineVoiceSubagent; + }); + } + + /* + * Whether this subagent may call customer tools in parallel. If omitted, the service defaults to false. Subagents + * with outgoing handoff conditions must use `false`. + */ + @Generated + private Boolean parallelToolCallsEnabled; + + /** + * Get the parallelToolCallsEnabled property: Whether this subagent may call customer tools in parallel. If omitted, + * the service defaults to false. Subagents with outgoing handoff conditions must use `false`. + * + * @return the parallelToolCallsEnabled value. + */ + @Generated + public Boolean isParallelToolCallsEnabled() { + return this.parallelToolCallsEnabled; + } + + /** + * Set the parallelToolCallsEnabled property: Whether this subagent may call customer tools in parallel. If omitted, + * the service defaults to false. Subagents with outgoing handoff conditions must use `false`. + * + * @param parallelToolCallsEnabled the parallelToolCallsEnabled value to set. + * @return the InlineVoiceSubagent object itself. + */ + @Generated + public InlineVoiceSubagent setParallelToolCallsEnabled(Boolean parallelToolCallsEnabled) { + this.parallelToolCallsEnabled = parallelToolCallsEnabled; + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsTool.java deleted file mode 100644 index c0aafc8446da0..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsTool.java +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * MCP list tools tool - * - * A tool available on an MCP server. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class McpListToolsTool implements JsonSerializable { - - /* - * The name of the tool. - */ - @Generated - private final String name; - - /* - * The description property. - */ - @Generated - private String description; - - /* - * The JSON schema describing the tool's input. - */ - @Generated - private final McpListToolsToolInputSchema inputSchema; - - /* - * The annotations property. - */ - @Generated - private McpListToolsToolAnnotations annotations; - - /** - * Creates an instance of McpListToolsTool class. - * - * @param name the name value to set. - * @param inputSchema the inputSchema value to set. - */ - @Generated - public McpListToolsTool(String name, McpListToolsToolInputSchema inputSchema) { - this.name = name; - this.inputSchema = inputSchema; - } - - /** - * Get the name property: The name of the tool. - * - * @return the name value. - */ - @Generated - public String getName() { - return this.name; - } - - /** - * Get the description property: The description property. - * - * @return the description value. - */ - @Generated - public String getDescription() { - return this.description; - } - - /** - * Set the description property: The description property. - * - * @param description the description value to set. - * @return the McpListToolsTool object itself. - */ - @Generated - public McpListToolsTool setDescription(String description) { - this.description = description; - return this; - } - - /** - * Get the inputSchema property: The JSON schema describing the tool's input. - * - * @return the inputSchema value. - */ - @Generated - public McpListToolsToolInputSchema getInputSchema() { - return this.inputSchema; - } - - /** - * Get the annotations property: The annotations property. - * - * @return the annotations value. - */ - @Generated - public McpListToolsToolAnnotations getAnnotations() { - return this.annotations; - } - - /** - * Set the annotations property: The annotations property. - * - * @param annotations the annotations value to set. - * @return the McpListToolsTool object itself. - */ - @Generated - public McpListToolsTool setAnnotations(McpListToolsToolAnnotations annotations) { - this.annotations = annotations; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("name", this.name); - jsonWriter.writeJsonField("input_schema", this.inputSchema); - jsonWriter.writeStringField("description", this.description); - jsonWriter.writeJsonField("annotations", this.annotations); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of McpListToolsTool from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of McpListToolsTool if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the McpListToolsTool. - */ - @Generated - public static McpListToolsTool fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String name = null; - McpListToolsToolInputSchema inputSchema = null; - String description = null; - McpListToolsToolAnnotations annotations = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("name".equals(fieldName)) { - name = reader.getString(); - } else if ("input_schema".equals(fieldName)) { - inputSchema = McpListToolsToolInputSchema.fromJson(reader); - } else if ("description".equals(fieldName)) { - description = reader.getString(); - } else if ("annotations".equals(fieldName)) { - annotations = McpListToolsToolAnnotations.fromJson(reader); - } else { - reader.skipChildren(); - } - } - McpListToolsTool deserializedMcpListToolsTool = new McpListToolsTool(name, inputSchema); - deserializedMcpListToolsTool.description = description; - deserializedMcpListToolsTool.annotations = annotations; - return deserializedMcpListToolsTool; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolAnnotations.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolAnnotations.java deleted file mode 100644 index 4980bdb6d7bdc..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolAnnotations.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The McpListToolsToolAnnotations model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class McpListToolsToolAnnotations implements JsonSerializable { - - /** - * Creates an instance of McpListToolsToolAnnotations class. - */ - @Generated - public McpListToolsToolAnnotations() { - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of McpListToolsToolAnnotations from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of McpListToolsToolAnnotations if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the McpListToolsToolAnnotations. - */ - @Generated - public static McpListToolsToolAnnotations fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - McpListToolsToolAnnotations deserializedMcpListToolsToolAnnotations = new McpListToolsToolAnnotations(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - reader.skipChildren(); - } - return deserializedMcpListToolsToolAnnotations; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolInputSchema.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolInputSchema.java deleted file mode 100644 index 6f2b64036f355..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/McpListToolsToolInputSchema.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The McpListToolsToolInputSchema model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class McpListToolsToolInputSchema implements JsonSerializable { - - /** - * Creates an instance of McpListToolsToolInputSchema class. - */ - @Generated - public McpListToolsToolInputSchema() { - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of McpListToolsToolInputSchema from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of McpListToolsToolInputSchema if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the McpListToolsToolInputSchema. - */ - @Generated - public static McpListToolsToolInputSchema fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - McpListToolsToolInputSchema deserializedMcpListToolsToolInputSchema = new McpListToolsToolInputSchema(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - reader.skipChildren(); - } - return deserializedMcpListToolsToolInputSchema; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormat.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormat.java deleted file mode 100644 index 1595dd4eb7477..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormat.java +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimeAudioFormat model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class RealtimeAudioFormat implements JsonSerializable { - - /* - * The type property. - */ - @Generated - private RealtimeAudioFormatType type = RealtimeAudioFormatType.fromString("RealtimeAudioFormat"); - - /** - * Creates an instance of RealtimeAudioFormat class. - */ - @Generated - protected RealtimeAudioFormat() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - public RealtimeAudioFormatType getType() { - return this.type; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeAudioFormat from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeAudioFormat if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeAudioFormat. - */ - @Generated - public static RealtimeAudioFormat fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String discriminatorValue = null; - try (JsonReader readerToUse = reader.bufferObject()) { - // Prepare for reading - readerToUse.nextToken(); - while (readerToUse.nextToken() != JsonToken.END_OBJECT) { - String fieldName = readerToUse.getFieldName(); - readerToUse.nextToken(); - if ("type".equals(fieldName)) { - discriminatorValue = readerToUse.getString(); - break; - } else { - readerToUse.skipChildren(); - } - } - // Use the discriminator value to determine which subtype should be deserialized. - if ("audio/pcm".equals(discriminatorValue)) { - return RealtimePcmAudioFormat.fromJson(readerToUse.reset()); - } else if ("audio/pcmu".equals(discriminatorValue)) { - return RealtimePcmuAudioFormat.fromJson(readerToUse.reset()); - } else if ("audio/pcma".equals(discriminatorValue)) { - return RealtimePcmaAudioFormat.fromJson(readerToUse.reset()); - } else { - return fromJsonKnownDiscriminator(readerToUse.reset()); - } - } - }); - } - - @Generated - static RealtimeAudioFormat fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeAudioFormat deserializedRealtimeAudioFormat = new RealtimeAudioFormat(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeAudioFormat.type = RealtimeAudioFormatType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeAudioFormat; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormatType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormatType.java deleted file mode 100644 index fd43019c2643d..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeAudioFormatType.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for RealtimeAudioFormatType. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeAudioFormatType extends ExpandableStringEnum { - - /** - * Static value audio/pcm for RealtimeAudioFormatType. - */ - @Generated - public static final RealtimeAudioFormatType AUDIO_PCM = fromString("audio/pcm"); - - /** - * Static value audio/pcmu for RealtimeAudioFormatType. - */ - @Generated - public static final RealtimeAudioFormatType AUDIO_PCMU = fromString("audio/pcmu"); - - /** - * Static value audio/pcma for RealtimeAudioFormatType. - */ - @Generated - public static final RealtimeAudioFormatType AUDIO_PCMA = fromString("audio/pcma"); - - /** - * Creates a new instance of RealtimeAudioFormatType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public RealtimeAudioFormatType() { - } - - /** - * Creates or finds a RealtimeAudioFormatType from its string representation. - * - * @param name a name to look for. - * @return the corresponding RealtimeAudioFormatType. - */ - @Generated - public static RealtimeAudioFormatType fromString(String name) { - return fromString(name, RealtimeAudioFormatType.class); - } - - /** - * Gets known RealtimeAudioFormatType values. - * - * @return known RealtimeAudioFormatType values. - */ - @Generated - public static Collection values() { - return values(RealtimeAudioFormatType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java index 7a4f5920be602..5d0e812b240f0 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java @@ -93,6 +93,8 @@ public static RealtimeConversationItem fromJson(JsonReader jsonReader) throws IO return RealtimeMcpToolCall.fromJson(readerToUse.reset()); } else if ("mcp_approval_request".equals(discriminatorValue)) { return RealtimeMcpApprovalInput.fromJson(readerToUse.reset()); + } else if ("system_tool".equals(discriminatorValue)) { + return VoiceAgentSystemToolItem.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java index 04fda01d3c072..696095b904fcf 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java @@ -46,12 +46,6 @@ public final class RealtimeConversationItemAssistantMessage extends RealtimeConv @Generated private String id; - /* - * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. - */ - @Generated - private RealtimeConversationItemObjectType object; - /* * The status of the item. Has no effect on the conversation. */ @@ -130,30 +124,6 @@ public RealtimeConversationItemAssistantMessage setId(String id) { return this; } - /** - * Get the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @return the object value. - */ - @Generated - public RealtimeConversationItemObjectType getObject() { - return this.object; - } - - /** - * Set the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @param object the object value to set. - * @return the RealtimeConversationItemAssistantMessage object itself. - */ - @Generated - public RealtimeConversationItemAssistantMessage setObject(RealtimeConversationItemObjectType object) { - this.object = object; - return this; - } - /** * Get the status property: The status of the item. Has no effect on the conversation. * @@ -214,7 +184,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { }); jsonWriter.writeStringField("role", this.role == null ? null : this.role.toString()); jsonWriter.writeStringField("id", this.id); - jsonWriter.writeStringField("object", this.object == null ? null : this.object.toString()); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); jsonWriter.writeStringField("status", this.status == null ? null : this.status.asString()); jsonWriter.writeNumberField("created_at", this.createdAt); jsonWriter.writeStringField("response_id", this.responseId); @@ -264,7 +234,7 @@ public static RealtimeConversationItemAssistantMessage fromJson(JsonReader jsonR RealtimeConversationItemAssistantMessage deserializedRealtimeConversationItemAssistantMessage = new RealtimeConversationItemAssistantMessage(content); deserializedRealtimeConversationItemAssistantMessage.id = id; - deserializedRealtimeConversationItemAssistantMessage.object = object; + deserializedRealtimeConversationItemAssistantMessage.objectType = object; deserializedRealtimeConversationItemAssistantMessage.status = status; deserializedRealtimeConversationItemAssistantMessage.createdAt = createdAt; deserializedRealtimeConversationItemAssistantMessage.responseId = responseId; @@ -283,4 +253,34 @@ public RealtimeConversationItemAssistantMessage setStatus(Status status) { this.status = status; return this; } + + /* + * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. + */ + @Generated + private RealtimeConversationItemObjectType objectType; + + /** + * Get the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @return the objectType value. + */ + @Generated + public RealtimeConversationItemObjectType getObjectType() { + return this.objectType; + } + + /** + * Set the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @param objectType the objectType value to set. + * @return the RealtimeConversationItemAssistantMessage object itself. + */ + @Generated + public RealtimeConversationItemAssistantMessage setObjectType(RealtimeConversationItemObjectType objectType) { + this.objectType = objectType; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java index c6f534c16e18f..eafc6222b4ac4 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java @@ -36,12 +36,6 @@ public final class RealtimeConversationItemFunctionCall extends RealtimeConversa @Generated private String id; - /* - * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. - */ - @Generated - private RealtimeConversationItemObjectType object; - // AI Tooling: openai-java de-dup private Status status; @@ -121,17 +115,6 @@ public RealtimeConversationItemFunctionCall setId(String id) { return this; } - /** - * Get the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @return the object value. - */ - @Generated - public RealtimeConversationItemObjectType getObject() { - return this.object; - } - /** * Get the status property: The status of the item. Has no effect on the conversation. * @@ -219,7 +202,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("arguments", this.arguments); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("id", this.id); - jsonWriter.writeStringField("object", this.object == null ? null : this.object.toString()); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); jsonWriter.writeStringField("status", this.status == null ? null : this.status.asString()); jsonWriter.writeStringField("call_id", this.callId); jsonWriter.writeNumberField("created_at", this.createdAt); @@ -277,7 +260,7 @@ public static RealtimeConversationItemFunctionCall fromJson(JsonReader jsonReade = new RealtimeConversationItemFunctionCall(name, arguments); deserializedRealtimeConversationItemFunctionCall.type = type; deserializedRealtimeConversationItemFunctionCall.id = id; - deserializedRealtimeConversationItemFunctionCall.object = object; + deserializedRealtimeConversationItemFunctionCall.objectType = object; deserializedRealtimeConversationItemFunctionCall.status = status; deserializedRealtimeConversationItemFunctionCall.callId = callId; deserializedRealtimeConversationItemFunctionCall.createdAt = createdAt; @@ -298,16 +281,33 @@ public RealtimeConversationItemFunctionCall setStatus(Status status) { return this; } + /* + * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. + */ + @Generated + private RealtimeConversationItemObjectType objectType; + + /** + * Get the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @return the objectType value. + */ + @Generated + public RealtimeConversationItemObjectType getObjectType() { + return this.objectType; + } + /** - * Set the object property: Identifier for the API object being returned - always `realtime.item`. Optional when + * Set the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when * creating a new item. * - * @param object the object value to set. + * @param objectType the objectType value to set. * @return the RealtimeConversationItemFunctionCall object itself. */ @Generated - public RealtimeConversationItemFunctionCall setObject(RealtimeConversationItemObjectType object) { - this.object = object; + public RealtimeConversationItemFunctionCall setObjectType(RealtimeConversationItemObjectType objectType) { + this.objectType = objectType; return this; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java index 1d3d7af5f485b..aa1dc4cbc5e4c 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java @@ -36,12 +36,6 @@ public final class RealtimeConversationItemFunctionCallOutput extends RealtimeCo @Generated private String id; - /* - * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. - */ - @Generated - private RealtimeConversationItemObjectType object; - // AI Tooling: openai-java de-dup private Status status; @@ -121,17 +115,6 @@ public RealtimeConversationItemFunctionCallOutput setId(String id) { return this; } - /** - * Get the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @return the object value. - */ - @Generated - public RealtimeConversationItemObjectType getObject() { - return this.object; - } - /** * Get the status property: The status of the item. Has no effect on the conversation. * @@ -221,7 +204,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("output", this.output); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("id", this.id); - jsonWriter.writeStringField("object", this.object == null ? null : this.object.toString()); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); jsonWriter.writeStringField("status", this.status == null ? null : this.status.asString()); jsonWriter.writeStringField("name", this.name); return jsonWriter.writeEndObject(); @@ -277,7 +260,7 @@ public static RealtimeConversationItemFunctionCallOutput fromJson(JsonReader jso = new RealtimeConversationItemFunctionCallOutput(callId, output); deserializedRealtimeConversationItemFunctionCallOutput.type = type; deserializedRealtimeConversationItemFunctionCallOutput.id = id; - deserializedRealtimeConversationItemFunctionCallOutput.object = object; + deserializedRealtimeConversationItemFunctionCallOutput.objectType = object; deserializedRealtimeConversationItemFunctionCallOutput.status = status; deserializedRealtimeConversationItemFunctionCallOutput.createdAt = createdAt; deserializedRealtimeConversationItemFunctionCallOutput.responseId = responseId; @@ -298,16 +281,33 @@ public RealtimeConversationItemFunctionCallOutput setStatus(Status status) { return this; } + /* + * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. + */ + @Generated + private RealtimeConversationItemObjectType objectType; + + /** + * Get the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @return the objectType value. + */ + @Generated + public RealtimeConversationItemObjectType getObjectType() { + return this.objectType; + } + /** - * Set the object property: Identifier for the API object being returned - always `realtime.item`. Optional when + * Set the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when * creating a new item. * - * @param object the object value to set. + * @param objectType the objectType value to set. * @return the RealtimeConversationItemFunctionCallOutput object itself. */ @Generated - public RealtimeConversationItemFunctionCallOutput setObject(RealtimeConversationItemObjectType object) { - this.object = object; + public RealtimeConversationItemFunctionCallOutput setObjectType(RealtimeConversationItemObjectType objectType) { + this.objectType = objectType; return this; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java index 26963e3fd4b1d..c4ce77ccd9883 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java @@ -11,6 +11,8 @@ import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.audio.transcriptions.TranscriptionLanguage; +import com.openai.models.realtime.ConversationItemInputAudioTranscriptionCompletedEvent.Usage; import com.openai.models.realtime.LogProbProperties; import java.io.IOException; import java.util.List; @@ -79,7 +81,7 @@ public final class RealtimeConversationItemInputAudioTranscriptionCompletedEvent * realtime model's pricing. */ @Generated - private final BinaryData usage; + private final Usage usage; /* * Phrase-level transcription timing and confidence details. @@ -96,52 +98,14 @@ public final class RealtimeConversationItemInputAudioTranscriptionCompletedEvent * @param transcript the transcript value to set. * @param usage the usage value to set. */ - RealtimeConversationItemInputAudioTranscriptionCompletedEvent(String eventId, String itemId, long contentIndex, - String transcript, BinaryData usage) { - // AI Tooling: union type - this.eventId = eventId; - this.itemId = itemId; - this.contentIndex = contentIndex; - this.transcript = transcript; - this.usage = usage; - } - - /** - * Creates an instance of RealtimeConversationItemInputAudioTranscriptionCompletedEvent class. - * - * @param eventId the eventId value to set. - * @param itemId the itemId value to set. - * @param contentIndex the contentIndex value to set. - * @param transcript the transcript value to set. - * @param usage the {@link TranscriptTextUsageTokens} usage to set. - */ - public RealtimeConversationItemInputAudioTranscriptionCompletedEvent(String eventId, String itemId, - long contentIndex, String transcript, TranscriptTextUsageTokens usage) { - // AI Tooling: union type - this.eventId = eventId; - this.itemId = itemId; - this.contentIndex = contentIndex; - this.transcript = transcript; - this.usage = usage == null ? null : BinaryData.fromObject(usage); - } - - /** - * Creates an instance of RealtimeConversationItemInputAudioTranscriptionCompletedEvent class. - * - * @param eventId the eventId value to set. - * @param itemId the itemId value to set. - * @param contentIndex the contentIndex value to set. - * @param transcript the transcript value to set. - * @param usage the {@link TranscriptTextUsageDuration} usage to set. - */ public RealtimeConversationItemInputAudioTranscriptionCompletedEvent(String eventId, String itemId, - long contentIndex, String transcript, TranscriptTextUsageDuration usage) { - // AI Tooling: union type + long contentIndex, String transcript, Usage usage) { + // AI Tooling: openai-java de-dup this.eventId = eventId; this.itemId = itemId; this.contentIndex = contentIndex; this.transcript = transcript; - this.usage = usage == null ? null : BinaryData.fromObject(usage); + this.usage = usage; } /** @@ -222,8 +186,8 @@ public List getLogprobs() { * * @return the usage value. */ - BinaryData getUsage() { - // AI Tooling: union type + @Generated + public Usage getUsage() { return this.usage; } @@ -248,9 +212,21 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeLongField("content_index", this.contentIndex); jsonWriter.writeStringField("transcript", this.transcript); jsonWriter.writeFieldName("usage"); - this.usage.writeTo(jsonWriter); + // AI Tooling: openai-java de-dup + if (this.usage == null) { + jsonWriter.writeNull(); + } else { + OpenAIJsonHelper.toBinaryData(this.usage).writeTo(jsonWriter); + } jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeArrayField("languages", this.languages, (writer, element) -> writer.writeJson(element)); + // AI Tooling: openai-java de-dup + jsonWriter.writeArrayField("languages", this.languages, (writer, element) -> { + if (element == null) { + writer.writeNull(); + } else { + OpenAIJsonHelper.toBinaryData(element).writeTo(writer); + } + }); // AI Tooling: openai-java de-dup jsonWriter.writeArrayField("logprobs", this.logprobs, (writer, element) -> { if (element == null) { @@ -280,7 +256,7 @@ public static RealtimeConversationItemInputAudioTranscriptionCompletedEvent from String itemId = null; long contentIndex = 0L; String transcript = null; - BinaryData usage = null; + Usage usage = null; RealtimeServerEventType type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED; List languages = null; @@ -298,11 +274,19 @@ public static RealtimeConversationItemInputAudioTranscriptionCompletedEvent from } else if ("transcript".equals(fieldName)) { transcript = reader.getString(); } else if ("usage".equals(fieldName)) { - usage = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + // AI Tooling: openai-java de-dup + BinaryData usageData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + usage = OpenAIJsonHelper.fromBinaryData(usageData, Usage.class); } else if ("type".equals(fieldName)) { type = RealtimeServerEventType.fromString(reader.getString()); } else if ("languages".equals(fieldName)) { - languages = reader.readArray(reader1 -> TranscriptionLanguage.fromJson(reader1)); + // AI Tooling: openai-java de-dup + languages = reader.readArray(reader1 -> { + BinaryData languageData + = reader1.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + return OpenAIJsonHelper.fromBinaryData(languageData, TranscriptionLanguage.class); + }); } else if ("logprobs".equals(fieldName)) { // AI Tooling: openai-java de-dup logprobs = reader.readArray(reader1 -> { @@ -326,40 +310,4 @@ public static RealtimeConversationItemInputAudioTranscriptionCompletedEvent from return deserializedRealtimeConversationItemInputAudioTranscriptionCompletedEvent; }); } - - /** - * Get the usage property: Usage statistics for the transcription. - * - * @return the usage value as a {@link TranscriptTextUsageTokens}, or {@code null} when it is not set or holds - * another variant. - */ - public TranscriptTextUsageTokens getUsageAsTranscriptTextUsageTokens() { - // AI Tooling: union type - if (this.usage == null) { - return null; - } - TranscriptTextUsage unionValue = this.usage.toObject(TranscriptTextUsage.class); - if (!(unionValue instanceof TranscriptTextUsageTokens)) { - return null; - } - return (TranscriptTextUsageTokens) unionValue; - } - - /** - * Get the usage property: Usage statistics for the transcription. - * - * @return the usage value as a {@link TranscriptTextUsageDuration}, or {@code null} when it is not set or holds - * another variant. - */ - public TranscriptTextUsageDuration getUsageAsTranscriptTextUsageDuration() { - // AI Tooling: union type - if (this.usage == null) { - return null; - } - TranscriptTextUsage unionValue = this.usage.toObject(TranscriptTextUsage.class); - if (!(unionValue instanceof TranscriptTextUsageDuration)) { - return null; - } - return (TranscriptTextUsageDuration) unionValue; - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java index 25eef650d5013..f306e264ff838 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java @@ -49,12 +49,6 @@ public final class RealtimeConversationItemSystemMessage extends RealtimeConvers @Generated private String id; - /* - * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. - */ - @Generated - private RealtimeConversationItemObjectType object; - // AI Tooling: openai-java de-dup private Status status; @@ -127,30 +121,6 @@ public RealtimeConversationItemSystemMessage setId(String id) { return this; } - /** - * Get the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @return the object value. - */ - @Generated - public RealtimeConversationItemObjectType getObject() { - return this.object; - } - - /** - * Set the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @param object the object value to set. - * @return the RealtimeConversationItemSystemMessage object itself. - */ - @Generated - public RealtimeConversationItemSystemMessage setObject(RealtimeConversationItemObjectType object) { - this.object = object; - return this; - } - /** * Get the status property: The status of the item. Has no effect on the conversation. * @@ -211,7 +181,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { }); jsonWriter.writeStringField("role", this.role == null ? null : this.role.toString()); jsonWriter.writeStringField("id", this.id); - jsonWriter.writeStringField("object", this.object == null ? null : this.object.toString()); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); jsonWriter.writeStringField("status", this.status == null ? null : this.status.asString()); return jsonWriter.writeEndObject(); } @@ -259,7 +229,7 @@ public static RealtimeConversationItemSystemMessage fromJson(JsonReader jsonRead RealtimeConversationItemSystemMessage deserializedRealtimeConversationItemSystemMessage = new RealtimeConversationItemSystemMessage(content); deserializedRealtimeConversationItemSystemMessage.id = id; - deserializedRealtimeConversationItemSystemMessage.object = object; + deserializedRealtimeConversationItemSystemMessage.objectType = object; deserializedRealtimeConversationItemSystemMessage.status = status; deserializedRealtimeConversationItemSystemMessage.createdAt = createdAt; deserializedRealtimeConversationItemSystemMessage.responseId = responseId; @@ -278,4 +248,34 @@ public RealtimeConversationItemSystemMessage setStatus(Status status) { this.status = status; return this; } + + /* + * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. + */ + @Generated + private RealtimeConversationItemObjectType objectType; + + /** + * Get the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @return the objectType value. + */ + @Generated + public RealtimeConversationItemObjectType getObjectType() { + return this.objectType; + } + + /** + * Set the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @param objectType the objectType value to set. + * @return the RealtimeConversationItemSystemMessage object itself. + */ + @Generated + public RealtimeConversationItemSystemMessage setObjectType(RealtimeConversationItemObjectType objectType) { + this.objectType = objectType; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java index e5c3700eeaef2..319897e0575f2 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java @@ -86,4 +86,10 @@ public static RealtimeConversationItemType fromString(String name) { public static Collection values() { return values(RealtimeConversationItemType.class); } + + /** + * A service-managed system-tool intent, not a provider result. + */ + @Generated + public static final RealtimeConversationItemType SYSTEM_TOOL = fromString("system_tool"); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java index 74f65c5f08d48..b89a9a7cb4742 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java @@ -46,12 +46,6 @@ public final class RealtimeConversationItemUserMessage extends RealtimeConversat @Generated private String id; - /* - * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. - */ - @Generated - private RealtimeConversationItemObjectType object; - // AI Tooling: openai-java de-dup private Status status; @@ -124,30 +118,6 @@ public RealtimeConversationItemUserMessage setId(String id) { return this; } - /** - * Get the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @return the object value. - */ - @Generated - public RealtimeConversationItemObjectType getObject() { - return this.object; - } - - /** - * Set the object property: Identifier for the API object being returned - always `realtime.item`. Optional when - * creating a new item. - * - * @param object the object value to set. - * @return the RealtimeConversationItemUserMessage object itself. - */ - @Generated - public RealtimeConversationItemUserMessage setObject(RealtimeConversationItemObjectType object) { - this.object = object; - return this; - } - /** * Get the status property: The status of the item. Has no effect on the conversation. * @@ -208,7 +178,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { }); jsonWriter.writeStringField("role", this.role == null ? null : this.role.toString()); jsonWriter.writeStringField("id", this.id); - jsonWriter.writeStringField("object", this.object == null ? null : this.object.toString()); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); jsonWriter.writeStringField("status", this.status == null ? null : this.status.asString()); return jsonWriter.writeEndObject(); } @@ -256,7 +226,7 @@ public static RealtimeConversationItemUserMessage fromJson(JsonReader jsonReader RealtimeConversationItemUserMessage deserializedRealtimeConversationItemUserMessage = new RealtimeConversationItemUserMessage(content); deserializedRealtimeConversationItemUserMessage.id = id; - deserializedRealtimeConversationItemUserMessage.object = object; + deserializedRealtimeConversationItemUserMessage.objectType = object; deserializedRealtimeConversationItemUserMessage.status = status; deserializedRealtimeConversationItemUserMessage.createdAt = createdAt; deserializedRealtimeConversationItemUserMessage.responseId = responseId; @@ -275,4 +245,34 @@ public RealtimeConversationItemUserMessage setStatus(Status status) { this.status = status; return this; } + + /* + * Identifier for the API object being returned - always `realtime.item`. Optional when creating a new item. + */ + @Generated + private RealtimeConversationItemObjectType objectType; + + /** + * Get the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @return the objectType value. + */ + @Generated + public RealtimeConversationItemObjectType getObjectType() { + return this.objectType; + } + + /** + * Set the objectType property: Identifier for the API object being returned - always `realtime.item`. Optional when + * creating a new item. + * + * @param objectType the objectType value to set. + * @return the RealtimeConversationItemUserMessage object itself. + */ + @Generated + public RealtimeConversationItemUserMessage setObjectType(RealtimeConversationItemObjectType objectType) { + this.objectType = objectType; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpErrorType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpErrorType.java deleted file mode 100644 index 08e8800608f82..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpErrorType.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for RealtimeMcpErrorType. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeMcpErrorType extends ExpandableStringEnum { - - /** - * Static value protocol_error for RealtimeMcpErrorType. - */ - @Generated - public static final RealtimeMcpErrorType PROTOCOL_ERROR = fromString("protocol_error"); - - /** - * Static value tool_execution_error for RealtimeMcpErrorType. - */ - @Generated - public static final RealtimeMcpErrorType TOOL_EXECUTION_ERROR = fromString("tool_execution_error"); - - /** - * Static value http_error for RealtimeMcpErrorType. - */ - @Generated - public static final RealtimeMcpErrorType HTTP_ERROR = fromString("http_error"); - - /** - * Creates a new instance of RealtimeMcpErrorType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public RealtimeMcpErrorType() { - } - - /** - * Creates or finds a RealtimeMcpErrorType from its string representation. - * - * @param name a name to look for. - * @return the corresponding RealtimeMcpErrorType. - */ - @Generated - public static RealtimeMcpErrorType fromString(String name) { - return fromString(name, RealtimeMcpErrorType.class); - } - - /** - * Gets known RealtimeMcpErrorType values. - * - * @return known RealtimeMcpErrorType values. - */ - @Generated - public static Collection values() { - return values(RealtimeMcpErrorType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpHttpError.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpHttpError.java deleted file mode 100644 index 8c4cc04ce78f0..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpHttpError.java +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Realtime MCP HTTP error. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeMcpHttpError extends RealtimeMcpError { - - /* - * The type property. - */ - @Generated - private RealtimeMcpErrorType type = RealtimeMcpErrorType.HTTP_ERROR; - - /* - * The code property. - */ - @Generated - private final long code; - - /* - * The message property. - */ - @Generated - private final String message; - - /** - * Creates an instance of RealtimeMcpHttpError class. - * - * @param code the code value to set. - * @param message the message value to set. - */ - @Generated - public RealtimeMcpHttpError(long code, String message) { - this.code = code; - this.message = message; - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeMcpErrorType getType() { - return this.type; - } - - /** - * Get the code property: The code property. - * - * @return the code value. - */ - @Generated - public long getCode() { - return this.code; - } - - /** - * Get the message property: The message property. - * - * @return the message value. - */ - @Generated - public String getMessage() { - return this.message; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeLongField("code", this.code); - jsonWriter.writeStringField("message", this.message); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeMcpHttpError from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeMcpHttpError if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the RealtimeMcpHttpError. - */ - @Generated - public static RealtimeMcpHttpError fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - long code = 0L; - String message = null; - RealtimeMcpErrorType type = RealtimeMcpErrorType.HTTP_ERROR; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("code".equals(fieldName)) { - code = reader.getLong(); - } else if ("message".equals(fieldName)) { - message = reader.getString(); - } else if ("type".equals(fieldName)) { - type = RealtimeMcpErrorType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - RealtimeMcpHttpError deserializedRealtimeMcpHttpError = new RealtimeMcpHttpError(code, message); - deserializedRealtimeMcpHttpError.type = type; - return deserializedRealtimeMcpHttpError; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java index 5e50016afde2c..b69db65871efc 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java @@ -3,12 +3,15 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeMcpListTools.Tool; import java.io.IOException; import java.time.Instant; import java.time.OffsetDateTime; @@ -42,11 +45,8 @@ public final class RealtimeMcpListTools extends RealtimeConversationItem { @Generated private final String serverLabel; - /* - * The tools available on the server. - */ - @Generated - private final List tools; + // AI Tooling: openai-java de-dup + private final List tools; /* * The Unix timestamp (in seconds) for when the item was persisted. @@ -66,8 +66,8 @@ public final class RealtimeMcpListTools extends RealtimeConversationItem { * @param serverLabel the serverLabel value to set. * @param tools the tools value to set. */ - @Generated - public RealtimeMcpListTools(String serverLabel, List tools) { + public RealtimeMcpListTools(String serverLabel, List tools) { + // AI Tooling: openai-java de-dup this.serverLabel = serverLabel; this.tools = tools; } @@ -120,8 +120,8 @@ public String getServerLabel() { * * @return the tools value. */ - @Generated - public List getTools() { + public List getTools() { + // AI Tooling: openai-java de-dup return this.tools; } @@ -151,12 +151,18 @@ public String getResponseId() { /** * {@inheritDoc} */ - @Generated @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup jsonWriter.writeStartObject(); jsonWriter.writeStringField("server_label", this.serverLabel); - jsonWriter.writeArrayField("tools", this.tools, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeArrayField("tools", this.tools, (writer, element) -> { + if (element == null) { + writer.writeNull(); + } else { + OpenAIJsonHelper.toBinaryData(element).writeTo(writer); + } + }); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("id", this.id); return jsonWriter.writeEndObject(); @@ -171,11 +177,11 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * @throws IllegalStateException If the deserialized JSON object was missing any required properties. * @throws IOException If an error occurs while reading the RealtimeMcpListTools. */ - @Generated public static RealtimeMcpListTools fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup return jsonReader.readObject(reader -> { String serverLabel = null; - List tools = null; + List tools = null; RealtimeConversationItemType type = RealtimeConversationItemType.MCP_LIST_TOOLS; String id = null; Long createdAt = null; @@ -186,7 +192,11 @@ public static RealtimeMcpListTools fromJson(JsonReader jsonReader) throws IOExce if ("server_label".equals(fieldName)) { serverLabel = reader.getString(); } else if ("tools".equals(fieldName)) { - tools = reader.readArray(reader1 -> McpListToolsTool.fromJson(reader1)); + tools = reader.readArray(reader1 -> { + BinaryData toolData + = reader1.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + return OpenAIJsonHelper.fromBinaryData(toolData, Tool.class); + }); } else if ("type".equals(fieldName)) { type = RealtimeConversationItemType.fromString(reader.getString()); } else if ("id".equals(fieldName)) { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpProtocolError.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpProtocolError.java deleted file mode 100644 index af3802cf5b078..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpProtocolError.java +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Realtime MCP protocol error. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeMcpProtocolError extends RealtimeMcpError { - - /* - * The type property. - */ - @Generated - private RealtimeMcpErrorType type = RealtimeMcpErrorType.PROTOCOL_ERROR; - - /* - * The code property. - */ - @Generated - private final long code; - - /* - * The message property. - */ - @Generated - private final String message; - - /** - * Creates an instance of RealtimeMcpProtocolError class. - * - * @param code the code value to set. - * @param message the message value to set. - */ - @Generated - public RealtimeMcpProtocolError(long code, String message) { - this.code = code; - this.message = message; - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeMcpErrorType getType() { - return this.type; - } - - /** - * Get the code property: The code property. - * - * @return the code value. - */ - @Generated - public long getCode() { - return this.code; - } - - /** - * Get the message property: The message property. - * - * @return the message value. - */ - @Generated - public String getMessage() { - return this.message; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeLongField("code", this.code); - jsonWriter.writeStringField("message", this.message); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeMcpProtocolError from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeMcpProtocolError if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the RealtimeMcpProtocolError. - */ - @Generated - public static RealtimeMcpProtocolError fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - long code = 0L; - String message = null; - RealtimeMcpErrorType type = RealtimeMcpErrorType.PROTOCOL_ERROR; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("code".equals(fieldName)) { - code = reader.getLong(); - } else if ("message".equals(fieldName)) { - message = reader.getString(); - } else if ("type".equals(fieldName)) { - type = RealtimeMcpErrorType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - RealtimeMcpProtocolError deserializedRealtimeMcpProtocolError = new RealtimeMcpProtocolError(code, message); - deserializedRealtimeMcpProtocolError.type = type; - return deserializedRealtimeMcpProtocolError; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java index 66e3b9713fc48..c8a335cfe4223 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java @@ -3,12 +3,15 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeMcpToolCall.Error; import java.io.IOException; import java.time.Instant; import java.time.OffsetDateTime; @@ -69,7 +72,7 @@ public final class RealtimeMcpToolCall extends RealtimeConversationItem { * The error property. */ @Generated - private RealtimeMcpError error; + private Error error; /* * The Unix timestamp (in seconds) for when the item was persisted. @@ -200,22 +203,10 @@ public RealtimeMcpToolCall setOutput(String output) { * @return the error value. */ @Generated - public RealtimeMcpError getError() { + public Error getError() { return this.error; } - /** - * Set the error property: The error property. - * - * @param error the error value to set. - * @return the RealtimeMcpToolCall object itself. - */ - @Generated - public RealtimeMcpToolCall setError(RealtimeMcpError error) { - this.error = error; - return this; - } - /** * Get the createdAt property: The Unix timestamp (in seconds) for when the item was persisted. * @@ -242,9 +233,9 @@ public String getResponseId() { /** * {@inheritDoc} */ - @Generated @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup jsonWriter.writeStartObject(); jsonWriter.writeStringField("id", this.id); jsonWriter.writeStringField("server_label", this.serverLabel); @@ -253,7 +244,10 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("approval_request_id", this.approvalRequestId); jsonWriter.writeStringField("output", this.output); - jsonWriter.writeJsonField("error", this.error); + if (this.error != null) { + jsonWriter.writeFieldName("error"); + OpenAIJsonHelper.toBinaryData(this.error).writeTo(jsonWriter); + } return jsonWriter.writeEndObject(); } @@ -266,8 +260,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * @throws IllegalStateException If the deserialized JSON object was missing any required properties. * @throws IOException If an error occurs while reading the RealtimeMcpToolCall. */ - @Generated public static RealtimeMcpToolCall fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup return jsonReader.readObject(reader -> { String id = null; String serverLabel = null; @@ -276,7 +270,7 @@ public static RealtimeMcpToolCall fromJson(JsonReader jsonReader) throws IOExcep RealtimeConversationItemType type = RealtimeConversationItemType.MCP_CALL; String approvalRequestId = null; String output = null; - RealtimeMcpError error = null; + Error error = null; Long createdAt = null; String responseId = null; while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -297,7 +291,9 @@ public static RealtimeMcpToolCall fromJson(JsonReader jsonReader) throws IOExcep } else if ("output".equals(fieldName)) { output = reader.getString(); } else if ("error".equals(fieldName)) { - error = RealtimeMcpError.fromJson(reader); + BinaryData errorData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + error = OpenAIJsonHelper.fromBinaryData(errorData, Error.class); } else if ("created_at".equals(fieldName)) { createdAt = reader.getNullable(JsonReader::getLong); } else if ("response_id".equals(fieldName)) { @@ -317,4 +313,16 @@ public static RealtimeMcpToolCall fromJson(JsonReader jsonReader) throws IOExcep return deserializedRealtimeMcpToolCall; }); } + + /** + * Set the error property: The error property. + * + * @param error the error value to set. + * @return the RealtimeMcpToolCall object itself. + */ + @Generated + public RealtimeMcpToolCall setError(Error error) { + this.error = error; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolExecutionError.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolExecutionError.java deleted file mode 100644 index 8b5ed099aaa10..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpToolExecutionError.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Realtime MCP tool execution error. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeMcpToolExecutionError extends RealtimeMcpError { - - /* - * The type property. - */ - @Generated - private RealtimeMcpErrorType type = RealtimeMcpErrorType.TOOL_EXECUTION_ERROR; - - /* - * The message property. - */ - @Generated - private final String message; - - /** - * Creates an instance of RealtimeMcpToolExecutionError class. - * - * @param message the message value to set. - */ - @Generated - public RealtimeMcpToolExecutionError(String message) { - this.message = message; - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeMcpErrorType getType() { - return this.type; - } - - /** - * Get the message property: The message property. - * - * @return the message value. - */ - @Generated - public String getMessage() { - return this.message; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("message", this.message); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeMcpToolExecutionError from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeMcpToolExecutionError if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the RealtimeMcpToolExecutionError. - */ - @Generated - public static RealtimeMcpToolExecutionError fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String message = null; - RealtimeMcpErrorType type = RealtimeMcpErrorType.TOOL_EXECUTION_ERROR; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("message".equals(fieldName)) { - message = reader.getString(); - } else if ("type".equals(fieldName)) { - type = RealtimeMcpErrorType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - RealtimeMcpToolExecutionError deserializedRealtimeMcpToolExecutionError - = new RealtimeMcpToolExecutionError(message); - deserializedRealtimeMcpToolExecutionError.type = type; - return deserializedRealtimeMcpToolExecutionError; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmAudioFormat.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmAudioFormat.java deleted file mode 100644 index a960b0ed347df..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmAudioFormat.java +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.RealtimeAudioFormats.AudioPcm.Rate; -import java.io.IOException; - -/** - * The RealtimePcmAudioFormat model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimePcmAudioFormat extends RealtimeAudioFormat { - - /* - * The type property. - */ - @Generated - private RealtimeAudioFormatType type = RealtimeAudioFormatType.AUDIO_PCM; - - // AI Tooling: openai-java de-dup - private Rate rate; - - /** - * Creates an instance of RealtimePcmAudioFormat class. - */ - @Generated - public RealtimePcmAudioFormat() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeAudioFormatType getType() { - return this.type; - } - - /** - * Get the rate property: The rate property. - * - * @return the rate value. - */ - public Rate getRate() { - // AI Tooling: openai-java de-dup - return this.rate; - } - - /** - * Set the rate property: The rate property. - * - * @param rate the rate value to set. - * @return the RealtimePcmAudioFormat object itself. - */ - public RealtimePcmAudioFormat setRate(Rate rate) { - // AI Tooling: openai-java de-dup - this.rate = rate; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - // AI Tooling: openai-java de-dup - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeNumberField("rate", this.rate == null ? null : this.rate.asLong()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimePcmAudioFormat from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimePcmAudioFormat if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimePcmAudioFormat. - */ - public static RealtimePcmAudioFormat fromJson(JsonReader jsonReader) throws IOException { - // AI Tooling: openai-java de-dup - return jsonReader.readObject(reader -> { - RealtimePcmAudioFormat deserializedRealtimePcmAudioFormat = new RealtimePcmAudioFormat(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimePcmAudioFormat.type = RealtimeAudioFormatType.fromString(reader.getString()); - } else if ("rate".equals(fieldName)) { - deserializedRealtimePcmAudioFormat.rate = reader.getNullable(r -> Rate.of(r.getLong())); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimePcmAudioFormat; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmaAudioFormat.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmaAudioFormat.java deleted file mode 100644 index c2f5bbfcc0470..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmaAudioFormat.java +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimePcmaAudioFormat model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimePcmaAudioFormat extends RealtimeAudioFormat { - - /* - * The type property. - */ - @Generated - private RealtimeAudioFormatType type = RealtimeAudioFormatType.AUDIO_PCMA; - - /** - * Creates an instance of RealtimePcmaAudioFormat class. - */ - @Generated - public RealtimePcmaAudioFormat() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeAudioFormatType getType() { - return this.type; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimePcmaAudioFormat from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimePcmaAudioFormat if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimePcmaAudioFormat. - */ - @Generated - public static RealtimePcmaAudioFormat fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimePcmaAudioFormat deserializedRealtimePcmaAudioFormat = new RealtimePcmaAudioFormat(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimePcmaAudioFormat.type = RealtimeAudioFormatType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimePcmaAudioFormat; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmuAudioFormat.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmuAudioFormat.java deleted file mode 100644 index 472b1cea076d5..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimePcmuAudioFormat.java +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimePcmuAudioFormat model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimePcmuAudioFormat extends RealtimeAudioFormat { - - /* - * The type property. - */ - @Generated - private RealtimeAudioFormatType type = RealtimeAudioFormatType.AUDIO_PCMU; - - /** - * Creates an instance of RealtimePcmuAudioFormat class. - */ - @Generated - public RealtimePcmuAudioFormat() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeAudioFormatType getType() { - return this.type; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimePcmuAudioFormat from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimePcmuAudioFormat if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimePcmuAudioFormat. - */ - @Generated - public static RealtimePcmuAudioFormat fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimePcmuAudioFormat deserializedRealtimePcmuAudioFormat = new RealtimePcmuAudioFormat(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimePcmuAudioFormat.type = RealtimeAudioFormatType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimePcmuAudioFormat; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java index 2bf69b1073a23..b4233e50ae8b6 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java @@ -3,13 +3,16 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeAudioFormats; import com.openai.models.realtime.ResponseContentPartDoneEvent.Part.Type; import java.io.IOException; @@ -45,7 +48,7 @@ public final class RealtimeResponseContentPart implements JsonSerializable BinaryData.fromObject(nonNullReader.readUntyped())); + deserializedRealtimeResponseContentPart.format + = OpenAIJsonHelper.fromBinaryData(formatData, RealtimeAudioFormats.class); } else { reader.skipChildren(); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSemanticVadTurnDetection.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSemanticVadTurnDetection.java deleted file mode 100644 index 3e3086269d637..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSemanticVadTurnDetection.java +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.RealtimeAudioInputTurnDetection.SemanticVad.Eagerness; -import java.io.IOException; - -/** - * The RealtimeSemanticVadTurnDetection model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSemanticVadTurnDetection extends RealtimeTurnDetection { - - /* - * The type property. - */ - @Generated - private RealtimeTurnDetectionType type = RealtimeTurnDetectionType.SEMANTIC_VAD; - - // AI Tooling: openai-java de-dup - private Eagerness eagerness; - - /* - * The create_response property. - */ - @Generated - private Boolean createResponse; - - /* - * The interrupt_response property. - */ - @Generated - private Boolean interruptResponse; - - /** - * Creates an instance of RealtimeSemanticVadTurnDetection class. - */ - @Generated - public RealtimeSemanticVadTurnDetection() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeTurnDetectionType getType() { - return this.type; - } - - /** - * Get the eagerness property: The eagerness property. - * - * @return the eagerness value. - */ - public Eagerness getEagerness() { - // AI Tooling: openai-java de-dup - return this.eagerness; - } - - /** - * Get the createResponse property: The create_response property. - * - * @return the createResponse value. - */ - @Generated - public Boolean isCreateResponse() { - return this.createResponse; - } - - /** - * Set the createResponse property: The create_response property. - * - * @param createResponse the createResponse value to set. - * @return the RealtimeSemanticVadTurnDetection object itself. - */ - @Generated - public RealtimeSemanticVadTurnDetection setCreateResponse(Boolean createResponse) { - this.createResponse = createResponse; - return this; - } - - /** - * Get the interruptResponse property: The interrupt_response property. - * - * @return the interruptResponse value. - */ - @Generated - public Boolean isInterruptResponse() { - return this.interruptResponse; - } - - /** - * Set the interruptResponse property: The interrupt_response property. - * - * @param interruptResponse the interruptResponse value to set. - * @return the RealtimeSemanticVadTurnDetection object itself. - */ - @Generated - public RealtimeSemanticVadTurnDetection setInterruptResponse(Boolean interruptResponse) { - this.interruptResponse = interruptResponse; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - // AI Tooling: openai-java de-dup - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeStringField("eagerness", this.eagerness == null ? null : this.eagerness.asString()); - jsonWriter.writeBooleanField("create_response", this.createResponse); - jsonWriter.writeBooleanField("interrupt_response", this.interruptResponse); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSemanticVadTurnDetection from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSemanticVadTurnDetection if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSemanticVadTurnDetection. - */ - public static RealtimeSemanticVadTurnDetection fromJson(JsonReader jsonReader) throws IOException { - // AI Tooling: openai-java de-dup - return jsonReader.readObject(reader -> { - RealtimeSemanticVadTurnDetection deserializedRealtimeSemanticVadTurnDetection - = new RealtimeSemanticVadTurnDetection(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeSemanticVadTurnDetection.type - = RealtimeTurnDetectionType.fromString(reader.getString()); - } else if ("eagerness".equals(fieldName)) { - deserializedRealtimeSemanticVadTurnDetection.eagerness - = reader.getNullable(r -> Eagerness.of(r.getString())); - } else if ("create_response".equals(fieldName)) { - deserializedRealtimeSemanticVadTurnDetection.createResponse - = reader.getNullable(JsonReader::getBoolean); - } else if ("interrupt_response".equals(fieldName)) { - deserializedRealtimeSemanticVadTurnDetection.interruptResponse - = reader.getNullable(JsonReader::getBoolean); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSemanticVadTurnDetection; - }); - } - - /** - * Set the eagerness property: The eagerness property. - * - * @param eagerness the eagerness value to set. - * @return the RealtimeSemanticVadTurnDetection object itself. - */ - public RealtimeSemanticVadTurnDetection setEagerness(Eagerness eagerness) { - // AI Tooling: openai-java de-dup - this.eagerness = eagerness; - return this; - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java index 4fe1c8e2eaed1..857264ab35911 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java @@ -171,8 +171,20 @@ public static RealtimeServerEvent fromJson(JsonReader jsonReader) throws IOExcep return RealtimeResponseMcpCallFailedEvent.fromJson(readerToUse.reset()); } else if ("error".equals(discriminatorValue)) { return RealtimeErrorEvent.fromJson(readerToUse.reset()); + } else if ("session.handoff.started".equals(discriminatorValue)) { + return VoiceAgentSessionHandoffStartedEvent.fromJson(readerToUse.reset()); + } else if ("session.handoff.aborted".equals(discriminatorValue)) { + return VoiceAgentSessionHandoffAbortedEvent.fromJson(readerToUse.reset()); + } else if ("response.system_tool_arguments.delta".equals(discriminatorValue)) { + return VoiceAgentSystemToolArgumentsDeltaEvent.fromJson(readerToUse.reset()); + } else if ("response.system_tool_arguments.done".equals(discriminatorValue)) { + return VoiceAgentSystemToolArgumentsDoneEvent.fromJson(readerToUse.reset()); + } else if ("input_collection.status".equals(discriminatorValue)) { + return VoiceAgentInputCollectionStatusEvent.fromJson(readerToUse.reset()); } else if ("session.subagent.started".equals(discriminatorValue)) { return VoiceAgentSessionSubagentStartedEvent.fromJson(readerToUse.reset()); + } else if ("session.subagent.completed".equals(discriminatorValue)) { + return VoiceAgentSessionSubagentCompletedEvent.fromJson(readerToUse.reset()); } else if ("session.subagent.aborted".equals(discriminatorValue)) { return VoiceAgentSessionSubagentAbortedEvent.fromJson(readerToUse.reset()); } else if ("warning".equals(discriminatorValue)) { @@ -201,8 +213,8 @@ public static RealtimeServerEvent fromJson(JsonReader jsonReader) throws IOExcep return VoiceAgentResponseAnimationVisemeDoneEvent.fromJson(readerToUse.reset()); } else if ("response.video.delta".equals(discriminatorValue)) { return VoiceAgentResponseVideoDeltaEvent.fromJson(readerToUse.reset()); - } else if ("session.subagent.completed".equals(discriminatorValue)) { - return VoiceAgentSessionSubagentCompletedEvent.fromJson(readerToUse.reset()); + } else if ("session.handoff.completed".equals(discriminatorValue)) { + return VoiceAgentSessionHandoffCompletedEvent.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java index 01c8dabe50f33..603851e627a1b 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java @@ -440,4 +440,42 @@ public static RealtimeServerEventType fromString(String name) { public static Collection values() { return values(RealtimeServerEventType.class); } + + /** + * An incremental fragment of model-generated system-tool arguments. + */ + @Generated + public static final RealtimeServerEventType RESPONSE_SYSTEM_TOOL_ARGUMENTS_DELTA + = fromString("response.system_tool_arguments.delta"); + + /** + * The complete model-generated system-tool arguments, not a provider outcome. + */ + @Generated + public static final RealtimeServerEventType RESPONSE_SYSTEM_TOOL_ARGUMENTS_DONE + = fromString("response.system_tool_arguments.done"); + + /** + * An asynchronous collection or telephony-operation outcome. + */ + @Generated + public static final RealtimeServerEventType INPUT_COLLECTION_STATUS = fromString("input_collection.status"); + + /** + * Static value session.handoff.started for RealtimeServerEventType. + */ + @Generated + public static final RealtimeServerEventType SESSION_HANDOFF_STARTED = fromString("session.handoff.started"); + + /** + * Static value session.handoff.completed for RealtimeServerEventType. + */ + @Generated + public static final RealtimeServerEventType SESSION_HANDOFF_COMPLETED = fromString("session.handoff.completed"); + + /** + * Static value session.handoff.aborted for RealtimeServerEventType. + */ + @Generated + public static final RealtimeServerEventType SESSION_HANDOFF_ABORTED = fromString("session.handoff.aborted"); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerVadTurnDetection.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerVadTurnDetection.java deleted file mode 100644 index 00096c3a1ad4d..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeServerVadTurnDetection.java +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.time.Duration; - -/** - * The RealtimeServerVadTurnDetection model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeServerVadTurnDetection extends RealtimeTurnDetection { - - /* - * The type property. - */ - @Generated - private RealtimeTurnDetectionType type = RealtimeTurnDetectionType.SERVER_VAD; - - /* - * The threshold property. - */ - @Generated - private Double threshold; - - /* - * The prefix_padding_ms property. - */ - @Generated - private Long prefixPaddingMs; - - /* - * The silence_duration_ms property. - */ - @Generated - private Long silenceDuration; - - /* - * The create_response property. - */ - @Generated - private Boolean createResponse; - - /* - * The interrupt_response property. - */ - @Generated - private Boolean interruptResponse; - - /* - * The idle_timeout_ms property. - */ - @Generated - private Long idleTimeout; - - /** - * Creates an instance of RealtimeServerVadTurnDetection class. - */ - @Generated - public RealtimeServerVadTurnDetection() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeTurnDetectionType getType() { - return this.type; - } - - /** - * Get the threshold property: The threshold property. - * - * @return the threshold value. - */ - @Generated - public Double getThreshold() { - return this.threshold; - } - - /** - * Set the threshold property: The threshold property. - * - * @param threshold the threshold value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setThreshold(Double threshold) { - this.threshold = threshold; - return this; - } - - /** - * Get the prefixPaddingMs property: The prefix_padding_ms property. - * - * @return the prefixPaddingMs value. - */ - @Generated - public Long getPrefixPaddingMs() { - return this.prefixPaddingMs; - } - - /** - * Set the prefixPaddingMs property: The prefix_padding_ms property. - * - * @param prefixPaddingMs the prefixPaddingMs value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setPrefixPaddingMs(Long prefixPaddingMs) { - this.prefixPaddingMs = prefixPaddingMs; - return this; - } - - /** - * Get the silenceDuration property: The silence_duration_ms property. - * - * @return the silenceDuration value. - */ - @Generated - public Duration getSilenceDuration() { - if (this.silenceDuration == null) { - return null; - } - return Duration.ofMillis(this.silenceDuration); - } - - /** - * Set the silenceDuration property: The silence_duration_ms property. - * - * @param silenceDuration the silenceDuration value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setSilenceDuration(Duration silenceDuration) { - if (silenceDuration == null) { - this.silenceDuration = null; - } else { - this.silenceDuration = silenceDuration.toMillis(); - } - return this; - } - - /** - * Get the createResponse property: The create_response property. - * - * @return the createResponse value. - */ - @Generated - public Boolean isCreateResponse() { - return this.createResponse; - } - - /** - * Set the createResponse property: The create_response property. - * - * @param createResponse the createResponse value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setCreateResponse(Boolean createResponse) { - this.createResponse = createResponse; - return this; - } - - /** - * Get the interruptResponse property: The interrupt_response property. - * - * @return the interruptResponse value. - */ - @Generated - public Boolean isInterruptResponse() { - return this.interruptResponse; - } - - /** - * Set the interruptResponse property: The interrupt_response property. - * - * @param interruptResponse the interruptResponse value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setInterruptResponse(Boolean interruptResponse) { - this.interruptResponse = interruptResponse; - return this; - } - - /** - * Get the idleTimeout property: The idle_timeout_ms property. - * - * @return the idleTimeout value. - */ - @Generated - public Duration getIdleTimeout() { - if (this.idleTimeout == null) { - return null; - } - return Duration.ofMillis(this.idleTimeout); - } - - /** - * Set the idleTimeout property: The idle_timeout_ms property. - * - * @param idleTimeout the idleTimeout value to set. - * @return the RealtimeServerVadTurnDetection object itself. - */ - @Generated - public RealtimeServerVadTurnDetection setIdleTimeout(Duration idleTimeout) { - if (idleTimeout == null) { - this.idleTimeout = null; - } else { - this.idleTimeout = idleTimeout.toMillis(); - } - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeNumberField("threshold", this.threshold); - jsonWriter.writeNumberField("prefix_padding_ms", this.prefixPaddingMs); - jsonWriter.writeNumberField("silence_duration_ms", this.silenceDuration); - jsonWriter.writeBooleanField("create_response", this.createResponse); - jsonWriter.writeBooleanField("interrupt_response", this.interruptResponse); - jsonWriter.writeNumberField("idle_timeout_ms", this.idleTimeout); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeServerVadTurnDetection from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeServerVadTurnDetection if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeServerVadTurnDetection. - */ - @Generated - public static RealtimeServerVadTurnDetection fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeServerVadTurnDetection deserializedRealtimeServerVadTurnDetection - = new RealtimeServerVadTurnDetection(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.type - = RealtimeTurnDetectionType.fromString(reader.getString()); - } else if ("threshold".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.threshold = reader.getNullable(JsonReader::getDouble); - } else if ("prefix_padding_ms".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.prefixPaddingMs - = reader.getNullable(JsonReader::getLong); - } else if ("silence_duration_ms".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.silenceDuration - = reader.getNullable(JsonReader::getLong); - } else if ("create_response".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.createResponse - = reader.getNullable(JsonReader::getBoolean); - } else if ("interrupt_response".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.interruptResponse - = reader.getNullable(JsonReader::getBoolean); - } else if ("idle_timeout_ms".equals(fieldName)) { - deserializedRealtimeServerVadTurnDetection.idleTimeout = reader.getNullable(JsonReader::getLong); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeServerVadTurnDetection; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioConfiguration.java deleted file mode 100644 index 501df0569cb28..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioConfiguration.java +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimeSessionAudioConfiguration model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionAudioConfiguration implements JsonSerializable { - - /* - * The input property. - */ - @Generated - private RealtimeSessionAudioInput input; - - /* - * The output property. - */ - @Generated - private RealtimeSessionAudioOutput output; - - /** - * Creates an instance of RealtimeSessionAudioConfiguration class. - */ - @Generated - public RealtimeSessionAudioConfiguration() { - } - - /** - * Get the input property: The input property. - * - * @return the input value. - */ - @Generated - public RealtimeSessionAudioInput getInput() { - return this.input; - } - - /** - * Set the input property: The input property. - * - * @param input the input value to set. - * @return the RealtimeSessionAudioConfiguration object itself. - */ - @Generated - public RealtimeSessionAudioConfiguration setInput(RealtimeSessionAudioInput input) { - this.input = input; - return this; - } - - /** - * Get the output property: The output property. - * - * @return the output value. - */ - @Generated - public RealtimeSessionAudioOutput getOutput() { - return this.output; - } - - /** - * Set the output property: The output property. - * - * @param output the output value to set. - * @return the RealtimeSessionAudioConfiguration object itself. - */ - @Generated - public RealtimeSessionAudioConfiguration setOutput(RealtimeSessionAudioOutput output) { - this.output = output; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("input", this.input); - jsonWriter.writeJsonField("output", this.output); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionAudioConfiguration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionAudioConfiguration if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionAudioConfiguration. - */ - @Generated - public static RealtimeSessionAudioConfiguration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeSessionAudioConfiguration deserializedRealtimeSessionAudioConfiguration - = new RealtimeSessionAudioConfiguration(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("input".equals(fieldName)) { - deserializedRealtimeSessionAudioConfiguration.input = RealtimeSessionAudioInput.fromJson(reader); - } else if ("output".equals(fieldName)) { - deserializedRealtimeSessionAudioConfiguration.output = RealtimeSessionAudioOutput.fromJson(reader); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSessionAudioConfiguration; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioInput.java deleted file mode 100644 index bb8f8e9d6887c..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioInput.java +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.OpenAIJsonHelper; -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.BinaryData; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.RealtimeAudioConfigInput.NoiseReduction; -import java.io.IOException; - -/** - * The RealtimeSessionAudioInput model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionAudioInput implements JsonSerializable { - - /* - * The format property. - */ - @Generated - private RealtimeAudioFormat format; - - /* - * The transcription property. - */ - @Generated - private AudioTranscription transcription; - - // AI Tooling: openai-java de-dup - private NoiseReduction noiseReduction; - - /* - * The turn_detection property. - */ - @Generated - private RealtimeTurnDetection turnDetection; - - /** - * Creates an instance of RealtimeSessionAudioInput class. - */ - @Generated - public RealtimeSessionAudioInput() { - } - - /** - * Get the format property: The format property. - * - * @return the format value. - */ - @Generated - public RealtimeAudioFormat getFormat() { - return this.format; - } - - /** - * Set the format property: The format property. - * - * @param format the format value to set. - * @return the RealtimeSessionAudioInput object itself. - */ - @Generated - public RealtimeSessionAudioInput setFormat(RealtimeAudioFormat format) { - this.format = format; - return this; - } - - /** - * Get the transcription property: The transcription property. - * - * @return the transcription value. - */ - @Generated - public AudioTranscription getTranscription() { - return this.transcription; - } - - /** - * Set the transcription property: The transcription property. - * - * @param transcription the transcription value to set. - * @return the RealtimeSessionAudioInput object itself. - */ - @Generated - public RealtimeSessionAudioInput setTranscription(AudioTranscription transcription) { - this.transcription = transcription; - return this; - } - - /** - * Get the noiseReduction property: The noise_reduction property. - * - * @return the noiseReduction value. - */ - public NoiseReduction getNoiseReduction() { - // AI Tooling: openai-java de-dup - return this.noiseReduction; - } - - /** - * Get the turnDetection property: The turn_detection property. - * - * @return the turnDetection value. - */ - @Generated - public RealtimeTurnDetection getTurnDetection() { - return this.turnDetection; - } - - /** - * Set the turnDetection property: The turn_detection property. - * - * @param turnDetection the turnDetection value to set. - * @return the RealtimeSessionAudioInput object itself. - */ - @Generated - public RealtimeSessionAudioInput setTurnDetection(RealtimeTurnDetection turnDetection) { - this.turnDetection = turnDetection; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - // AI Tooling: openai-java de-dup - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("format", this.format); - jsonWriter.writeJsonField("transcription", this.transcription); - if (this.noiseReduction != null) { - jsonWriter.writeFieldName("noise_reduction"); - OpenAIJsonHelper.toBinaryData(this.noiseReduction).writeTo(jsonWriter); - } - jsonWriter.writeJsonField("turn_detection", this.turnDetection); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionAudioInput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionAudioInput if the JsonReader was pointing to an instance of - * it, or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionAudioInput. - */ - public static RealtimeSessionAudioInput fromJson(JsonReader jsonReader) throws IOException { - // AI Tooling: openai-java de-dup - return jsonReader.readObject(reader -> { - RealtimeSessionAudioInput deserializedRealtimeSessionAudioInput = new RealtimeSessionAudioInput(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("format".equals(fieldName)) { - deserializedRealtimeSessionAudioInput.format = RealtimeAudioFormat.fromJson(reader); - } else if ("transcription".equals(fieldName)) { - deserializedRealtimeSessionAudioInput.transcription = AudioTranscription.fromJson(reader); - } else if ("noise_reduction".equals(fieldName)) { - BinaryData noiseReductionData = reader.getNullable(r -> BinaryData.fromObject(r.readUntyped())); - deserializedRealtimeSessionAudioInput.noiseReduction - = OpenAIJsonHelper.fromBinaryData(noiseReductionData, NoiseReduction.class); - } else if ("turn_detection".equals(fieldName)) { - deserializedRealtimeSessionAudioInput.turnDetection = RealtimeTurnDetection.fromJson(reader); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSessionAudioInput; - }); - } - - /** - * Set the noiseReduction property: The noise_reduction property. - * - * @param noiseReduction the noiseReduction value to set. - * @return the RealtimeSessionAudioInput object itself. - */ - public RealtimeSessionAudioInput setNoiseReduction(NoiseReduction noiseReduction) { - // AI Tooling: openai-java de-dup - this.noiseReduction = noiseReduction; - return this; - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioOutput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioOutput.java deleted file mode 100644 index ddd0272ae256f..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioOutput.java +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.BinaryData; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimeSessionAudioOutput model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionAudioOutput implements JsonSerializable { - - /* - * The format property. - */ - @Generated - private RealtimeAudioFormat format; - - /* - * The voice property. - */ - @Generated - private BinaryData voice; - - /* - * The speed property. - */ - @Generated - private Double speed; - - /** - * Creates an instance of RealtimeSessionAudioOutput class. - */ - @Generated - public RealtimeSessionAudioOutput() { - } - - /** - * Get the format property: The format property. - * - * @return the format value. - */ - @Generated - public RealtimeAudioFormat getFormat() { - return this.format; - } - - /** - * Set the format property: The format property. - * - * @param format the format value to set. - * @return the RealtimeSessionAudioOutput object itself. - */ - @Generated - public RealtimeSessionAudioOutput setFormat(RealtimeAudioFormat format) { - this.format = format; - return this; - } - - /** - * Get the voice property: The voice property. - * - * @return the voice value. - */ - BinaryData getVoice() { - // AI Tooling: union type - return this.voice; - } - - /** - * Set the voice property: The voice property. - * - * @param voice the voice value to set. - * @return the RealtimeSessionAudioOutput object itself. - */ - RealtimeSessionAudioOutput setVoice(BinaryData voice) { - // AI Tooling: union type - this.voice = voice; - return this; - } - - /** - * Get the speed property: The speed property. - * - * @return the speed value. - */ - @Generated - public Double getSpeed() { - return this.speed; - } - - /** - * Set the speed property: The speed property. - * - * @param speed the speed value to set. - * @return the RealtimeSessionAudioOutput object itself. - */ - @Generated - public RealtimeSessionAudioOutput setSpeed(Double speed) { - this.speed = speed; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("format", this.format); - if (this.voice != null) { - jsonWriter.writeFieldName("voice"); - this.voice.writeTo(jsonWriter); - } - jsonWriter.writeNumberField("speed", this.speed); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionAudioOutput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionAudioOutput if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionAudioOutput. - */ - @Generated - public static RealtimeSessionAudioOutput fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeSessionAudioOutput deserializedRealtimeSessionAudioOutput = new RealtimeSessionAudioOutput(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("format".equals(fieldName)) { - deserializedRealtimeSessionAudioOutput.format = RealtimeAudioFormat.fromJson(reader); - } else if ("voice".equals(fieldName)) { - deserializedRealtimeSessionAudioOutput.voice - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - } else if ("speed".equals(fieldName)) { - deserializedRealtimeSessionAudioOutput.speed = reader.getNullable(JsonReader::getDouble); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSessionAudioOutput; - }); - } - - /** - * Set the voice property: The built-in or custom voice used for audio output. - * - * @param voice the {@link VoiceIds} built-in voice to set. - * @return the RealtimeSessionAudioOutput object itself. - */ - public RealtimeSessionAudioOutput setVoice(VoiceIds voice) { - // AI Tooling: union type - this.voice = voice == null ? null : BinaryData.fromObject(voice.toString()); - return this; - } - - /** - * Get the voice property: The built-in or custom voice used for audio output. - * - * @return the voice value as a {@link VoiceIds}, or {@code null} when it is not set or holds another variant. - */ - public VoiceIds getVoiceAsVoiceIds() { - // AI Tooling: union type - if (this.voice == null) { - return null; - } - String json = this.voice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return VoiceIds.fromString(this.voice.toObject(String.class)); - } - - /** - * Set the voice property: The built-in or custom voice used for audio output. - * - * @param voice the {@link RealtimeSessionCreateRequestGAAudioOutputVoice} custom voice to set. - * @return the RealtimeSessionAudioOutput object itself. - */ - public RealtimeSessionAudioOutput setVoice(RealtimeSessionCreateRequestGAAudioOutputVoice voice) { - // AI Tooling: union type - this.voice = voice == null ? null : BinaryData.fromObject(voice); - return this; - } - - /** - * Get the voice property: The built-in or custom voice used for audio output. - * - * @return the voice value as a {@link RealtimeSessionCreateRequestGAAudioOutputVoice}, or {@code null} when it is - * not set or holds another variant. - */ - public RealtimeSessionCreateRequestGAAudioOutputVoice getVoiceAsRealtimeSessionCreateRequestGAAudioOutputVoice() { - // AI Tooling: union type - if (this.voice == null) { - return null; - } - String json = this.voice.toString().trim(); - if (!(json.startsWith("{"))) { - return null; - } - return this.voice.toObject(RealtimeSessionCreateRequestGAAudioOutputVoice.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfiguration.java deleted file mode 100644 index 36b101c877412..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfiguration.java +++ /dev/null @@ -1,907 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.OpenAIJsonHelper; -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.BinaryData; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.RealtimeReasoning; -import com.openai.models.realtime.RealtimeSessionCreateRequest.Model; -import com.openai.models.realtime.RealtimeSessionCreateRequest.OutputModality; -import com.openai.models.realtime.RealtimeToolsConfigUnion; -import com.openai.models.realtime.RealtimeTruncationRetentionRatio; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ResponsePrompt; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; -import java.io.IOException; -import java.util.List; - -/** - * Realtime session configuration - * - * Realtime session object configuration. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionConfiguration extends RealtimeSessionConfigurationBase { - - /* - * The type property. - */ - @Generated - private RealtimeSessionType type = RealtimeSessionType.REALTIME; - - /* - * The set of modalities the model can respond with. It defaults to `["audio"]`, indicating - * that the model will respond with audio plus a transcript. `["text"]` can be used to make - * the model respond with text only. It is not possible to request both `text` and `audio` at the same time. - */ - @Generated - private List outputModalities; - - /* - * The Realtime model used for this session. - */ - @Generated - private Model model; - - /* - * 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. - */ - @Generated - private String instructions; - - /* - * Configuration for input and output audio. - */ - @Generated - private RealtimeSessionAudioConfiguration audio; - - /* - * Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - */ - @Generated - private List include; - - /* - * Tracing Configuration - * - * Realtime API can write session traces to the [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set - * to null to disable tracing. Once - * tracing is enabled for a session, the configuration cannot be modified. - * `auto` will create a trace for the session with default values for the - * workflow name, group id, and metadata. - */ - @Generated - private BinaryData tracing; - - /* - * Tools available to the model. - */ - @Generated - private List tools; - - /* - * How the model chooses tools. Provide one of the string modes or force a specific - * function/MCP tool. - */ - @Generated - private BinaryData toolChoice; - - /* - * Whether the model may call multiple tools in parallel. Only supported by - * reasoning Realtime models such as `gpt-realtime-2`. - */ - @Generated - private Boolean parallelToolCalls; - - /* - * The reasoning property. - */ - @Generated - private RealtimeReasoning reasoning; - - /* - * 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`. - */ - @Generated - private BinaryData maxOutputTokens; - - /* - * The truncation property. - */ - @Generated - private BinaryData truncation; - - /* - * The prompt property. - */ - @Generated - private ResponsePrompt prompt; - - /** - * Creates an instance of RealtimeSessionConfiguration class. - */ - @Generated - public RealtimeSessionConfiguration() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeSessionType getType() { - return this.type; - } - - /** - * Get the outputModalities property: The set of modalities the model can respond with. It defaults to `["audio"]`, - * indicating - * that the model will respond with audio plus a transcript. `["text"]` can be used to make - * the model respond with text only. It is not possible to request both `text` and `audio` at the same time. - * - * @return the outputModalities value. - */ - @Generated - public List getOutputModalities() { - return this.outputModalities; - } - - /** - * Set the outputModalities property: The set of modalities the model can respond with. It defaults to `["audio"]`, - * indicating - * that the model will respond with audio plus a transcript. `["text"]` can be used to make - * the model respond with text only. It is not possible to request both `text` and `audio` at the same time. - * - * @param outputModalities the outputModalities value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setOutputModalities(List outputModalities) { - this.outputModalities = outputModalities; - return this; - } - - /** - * Get the model property: The Realtime model used for this session. - * - * @return the model value. - */ - @Generated - public Model getModel() { - return this.model; - } - - /** - * Get the instructions property: 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. - * - * @return the instructions value. - */ - @Generated - public String getInstructions() { - return this.instructions; - } - - /** - * Set the instructions property: 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. - * - * @param instructions the instructions value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setInstructions(String instructions) { - this.instructions = instructions; - return this; - } - - /** - * Get the audio property: Configuration for input and output audio. - * - * @return the audio value. - */ - @Generated - public RealtimeSessionAudioConfiguration getAudio() { - return this.audio; - } - - /** - * Set the audio property: Configuration for input and output audio. - * - * @param audio the audio value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setAudio(RealtimeSessionAudioConfiguration audio) { - this.audio = audio; - return this; - } - - /** - * Get the include property: Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - * - * @return the include value. - */ - @Generated - public List getInclude() { - return this.include; - } - - /** - * Set the include property: Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - * - * @param include the include value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setInclude(List include) { - this.include = include; - return this; - } - - /** - * Get the tracing property: Tracing Configuration - * - * Realtime API can write session traces to the [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set - * to null to disable tracing. Once - * tracing is enabled for a session, the configuration cannot be modified. - * `auto` will create a trace for the session with default values for the - * workflow name, group id, and metadata. - * - * @return the tracing value. - */ - BinaryData getTracing() { - // AI Tooling: union type - return this.tracing; - } - - /** - * Set the tracing property: Tracing Configuration - * - * Realtime API can write session traces to the [Traces Dashboard](https://platform.openai.com/logs?api=traces). Set - * to null to disable tracing. Once - * tracing is enabled for a session, the configuration cannot be modified. - * `auto` will create a trace for the session with default values for the - * workflow name, group id, and metadata. - * - * @param tracing the tracing value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - RealtimeSessionConfiguration setTracing(BinaryData tracing) { - // AI Tooling: union type - this.tracing = tracing; - return this; - } - - /** - * Get the tools property: Tools available to the model. - * - * @return the tools value. - */ - List getTools() { - // AI Tooling: union type - return this.tools; - } - - /** - * Set the tools property: Tools available to the model. - * - * @param tools the tools value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - RealtimeSessionConfiguration setTools(List tools) { - // AI Tooling: union type - this.tools = tools; - return this; - } - - /** - * Get the tools property as a list of openai-java {@link RealtimeToolsConfigUnion} values: Tools available to the - * model. - * - * @return the tools value as a list of openai-java union values. - */ - public List getToolsAsOpenAITools() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - return OpenAIJsonHelper.fromBinaryDataList(this.tools, RealtimeToolsConfigUnion.class); - } - - /** - * Set the tools property using a list of openai-java {@link RealtimeToolsConfigUnion} values: Tools available to - * the model. - * - * @param tools the list of openai-java union values to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setToolsAsOpenAITools(List tools) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.tools = OpenAIJsonHelper.toBinaryDataList(tools); - return this; - } - - /** - * Get the toolChoice property: How the model chooses tools. Provide one of the string modes or force a specific - * function/MCP tool. - * - * @return the toolChoice value. - */ - BinaryData getToolChoice() { - // AI Tooling: union type - return this.toolChoice; - } - - /** - * Set the toolChoice property: How the model chooses tools. Provide one of the string modes or force a specific - * function/MCP tool. - * - * @param toolChoice the toolChoice value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - RealtimeSessionConfiguration setToolChoice(BinaryData toolChoice) { - // AI Tooling: union type - this.toolChoice = toolChoice; - return this; - } - - /** - * Get the parallelToolCalls property: Whether the model may call multiple tools in parallel. Only supported by - * reasoning Realtime models such as `gpt-realtime-2`. - * - * @return the parallelToolCalls value. - */ - @Generated - public Boolean isParallelToolCalls() { - return this.parallelToolCalls; - } - - /** - * Set the parallelToolCalls property: Whether the model may call multiple tools in parallel. Only supported by - * reasoning Realtime models such as `gpt-realtime-2`. - * - * @param parallelToolCalls the parallelToolCalls value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setParallelToolCalls(Boolean parallelToolCalls) { - this.parallelToolCalls = parallelToolCalls; - return this; - } - - /** - * Get the reasoning property: The reasoning property. - * - * @return the reasoning value. - */ - @Generated - public RealtimeReasoning getReasoning() { - return this.reasoning; - } - - /** - * Set the reasoning property: The reasoning property. - * - * @param reasoning the reasoning value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setReasoning(RealtimeReasoning reasoning) { - this.reasoning = reasoning; - return this; - } - - /** - * Get the maxOutputTokens property: 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`. - * - * @return the maxOutputTokens value. - */ - BinaryData getMaxOutputTokens() { - // AI Tooling: union type - return this.maxOutputTokens; - } - - /** - * Set the maxOutputTokens property: 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`. - * - * @param maxOutputTokens the maxOutputTokens value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - RealtimeSessionConfiguration setMaxOutputTokens(BinaryData maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens; - return this; - } - - /** - * Get the truncation property: The truncation property. - * - * @return the truncation value. - */ - BinaryData getTruncation() { - // AI Tooling: union type - return this.truncation; - } - - /** - * Set the truncation property: The truncation property. - * - * @param truncation the truncation value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - RealtimeSessionConfiguration setTruncation(BinaryData truncation) { - // AI Tooling: union type - this.truncation = truncation; - return this; - } - - /** - * Get the prompt property: The prompt property. - * - * @return the prompt value. - */ - @Generated - public ResponsePrompt getPrompt() { - return this.prompt; - } - - /** - * Set the prompt property: The prompt property. - * - * @param prompt the prompt value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setPrompt(ResponsePrompt prompt) { - this.prompt = prompt; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeArrayField("output_modalities", this.outputModalities, - (writer, element) -> writer.writeString(element == null ? null : element.asString())); - jsonWriter.writeStringField("model", this.model == null ? null : this.model.asString()); - jsonWriter.writeStringField("instructions", this.instructions); - jsonWriter.writeJsonField("audio", this.audio); - jsonWriter.writeArrayField("include", this.include, (writer, element) -> writer.writeString(element)); - if (this.tracing != null) { - jsonWriter.writeFieldName("tracing"); - this.tracing.writeTo(jsonWriter); - } - jsonWriter.writeArrayField("tools", this.tools, (writer, element) -> { - if (element == null) { - writer.writeNull(); - } else { - element.writeTo(writer); - } - }); - if (this.toolChoice != null) { - jsonWriter.writeFieldName("tool_choice"); - this.toolChoice.writeTo(jsonWriter); - } - jsonWriter.writeBooleanField("parallel_tool_calls", this.parallelToolCalls); - // AI Tooling: openai-java de-dup - if (this.reasoning != null) { - jsonWriter.writeFieldName("reasoning"); - OpenAIJsonHelper.toBinaryData(this.reasoning).writeTo(jsonWriter); - } - if (this.maxOutputTokens != null) { - jsonWriter.writeFieldName("max_output_tokens"); - this.maxOutputTokens.writeTo(jsonWriter); - } - if (this.truncation != null) { - jsonWriter.writeFieldName("truncation"); - this.truncation.writeTo(jsonWriter); - } - if (this.prompt != null) { - jsonWriter.writeFieldName("prompt"); - OpenAIJsonHelper.toBinaryData(this.prompt).writeTo(jsonWriter); - } - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionConfiguration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionConfiguration if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionConfiguration. - */ - public static RealtimeSessionConfiguration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeSessionConfiguration deserializedRealtimeSessionConfiguration = new RealtimeSessionConfiguration(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.type = RealtimeSessionType.fromString(reader.getString()); - } else if ("output_modalities".equals(fieldName)) { - List outputModalities - = reader.readArray(reader1 -> reader1.getNullable(r -> OutputModality.of(r.getString()))); - deserializedRealtimeSessionConfiguration.outputModalities = outputModalities; - } else if ("model".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.model = reader.getNullable(r -> Model.of(r.getString())); - } else if ("instructions".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.instructions = reader.getString(); - } else if ("audio".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.audio = RealtimeSessionAudioConfiguration.fromJson(reader); - } else if ("include".equals(fieldName)) { - List include = reader.readArray(reader1 -> reader1.getString()); - deserializedRealtimeSessionConfiguration.include = include; - } else if ("tracing".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.tracing - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - } else if ("tools".equals(fieldName)) { - List tools = reader.readArray(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); - deserializedRealtimeSessionConfiguration.tools = tools; - } else if ("tool_choice".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.toolChoice - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - } else if ("parallel_tool_calls".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.parallelToolCalls - = reader.getNullable(JsonReader::getBoolean); - } else if ("reasoning".equals(fieldName)) { - // AI Tooling: openai-java de-dup - BinaryData reasoningData - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - deserializedRealtimeSessionConfiguration.reasoning - = OpenAIJsonHelper.fromBinaryData(reasoningData, RealtimeReasoning.class); - } else if ("max_output_tokens".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.maxOutputTokens - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - } else if ("truncation".equals(fieldName)) { - deserializedRealtimeSessionConfiguration.truncation - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - } else if ("prompt".equals(fieldName)) { - BinaryData promptData - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); - deserializedRealtimeSessionConfiguration.prompt - = OpenAIJsonHelper.fromBinaryData(promptData, ResponsePrompt.class); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSessionConfiguration; - }); - } - - /** - * Set the tracing property: Tracing configuration. - * - * @param tracing the tracing mode string to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setTracing(String tracing) { - // AI Tooling: union type - this.tracing = tracing == null ? null : BinaryData.fromObject(tracing); - return this; - } - - /** - * Get the tracing property: Tracing configuration. - * - * @return the tracing value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getTracingAsString() { - // AI Tooling: union type - if (this.tracing == null) { - return null; - } - String json = this.tracing.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.tracing.toObject(String.class); - } - - /** - * Set the tracing property: Tracing configuration. - * - * @param tracing the {@link RealtimeSessionTracingConfiguration} configuration to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setTracing(RealtimeSessionTracingConfiguration tracing) { - // AI Tooling: union type - this.tracing = tracing == null ? null : BinaryData.fromObject(tracing); - return this; - } - - /** - * Set the toolChoice property: How the model chooses tools. - * - * @param toolChoice the {@link ToolChoiceOptions} mode to set ({@code NONE}, {@code AUTO} or {@code REQUIRED}). - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setToolChoice(ToolChoiceOptions toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Set the toolChoice property to a specific function tool: How the model chooses tools. - * - * @param toolChoice the openai-java {@link ToolChoiceFunction} to set, or null to clear. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setToolChoice(ToolChoiceFunction toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceFunction}: How the model chooses tools. - * - * @return the toolChoice value as a ToolChoiceFunction, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceFunction getToolChoiceAsToolChoiceFunction() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isFunction()) { - return null; - } - return choice.asFunction(); - } - - /** - * Set the toolChoice property to a specific MCP tool: How the model chooses tools. - * - * @param toolChoice the openai-java {@link ToolChoiceMcp} to set, or null to clear. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setToolChoice(ToolChoiceMcp toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceMcp}: How the model chooses tools. - * - * @return the toolChoice value as a ToolChoiceMcp, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceMcp getToolChoiceAsToolChoiceMcp() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isMcp()) { - return null; - } - return choice.asMcp(); - } - - private ResponseCreateParams.ToolChoice getOpenAIToolChoice() { - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!json.startsWith("{")) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ResponseCreateParams.ToolChoice.class); - } - - /** - * Set the maxOutputTokens property: Maximum number of output tokens for a single assistant response. - * - * @param maxOutputTokens the maximum number of output tokens to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setMaxOutputTokens(long maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Set the maxOutputTokens property: Maximum number of output tokens for a single assistant response. - * - * @param maxOutputTokens the token-limit string to set, for example {@code "inf"} for an unlimited count. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setMaxOutputTokens(String maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens == null ? null : BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } - - /** - * Set the truncation property: The truncation policy for the session. - * - * @param truncation the truncation mode string to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setTruncation(String truncation) { - // AI Tooling: union type - this.truncation = truncation == null ? null : BinaryData.fromObject(truncation); - return this; - } - - /** - * Get the truncation property: The truncation policy for the session. - * - * @return the truncation value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getTruncationAsString() { - // AI Tooling: union type - if (this.truncation == null) { - return null; - } - String json = this.truncation.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.truncation.toObject(String.class); - } - - /** - * Set the truncation property: The truncation policy for the session. - * - * @param truncation the openai-java {@link RealtimeTruncationRetentionRatio} configuration to set. - * @return the RealtimeSessionConfiguration object itself. - */ - public RealtimeSessionConfiguration setTruncation(RealtimeTruncationRetentionRatio truncation) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.truncation = OpenAIJsonHelper.toBinaryData(truncation); - return this; - } - - /** - * Get the toolChoice property: How the model chooses tools. - * - * @return the toolChoice value as a {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another - * variant. - */ - public ToolChoiceOptions getToolChoiceAsToolChoiceOptions() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return OpenAIJsonHelper.fromBinaryData(this.toolChoice, ToolChoiceOptions.class); - } - - /** - * Set the model property: The Realtime model used for this session. - * - * @param model the model value to set. - * @return the RealtimeSessionConfiguration object itself. - */ - @Generated - public RealtimeSessionConfiguration setModel(Model model) { - this.model = model; - return this; - } - - /** - * Get the truncation property: The truncation policy for the session. - * - * @return the truncation value as an openai-java {@link RealtimeTruncationRetentionRatio}, or {@code null} when it - * is not set or holds another variant. - */ - public RealtimeTruncationRetentionRatio getTruncationAsRealtimeTruncationRetentionRatio() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.truncation == null) { - return null; - } - String json = this.truncation.toString().trim(); - if (!(json.startsWith("{"))) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.truncation, - RealtimeTruncationRetentionRatio.class); - } - - /** - * Get the tracing property: Tracing configuration. - * - * @return the tracing value as a {@link RealtimeSessionTracingConfiguration}, or {@code null} when it is not set - * or holds another variant. - */ - public RealtimeSessionTracingConfiguration getTracingAsRealtimeSessionTracingConfiguration() { - // AI Tooling: union type - if (this.tracing == null) { - return null; - } - String json = this.tracing.toString().trim(); - if (!(json.startsWith("{"))) { - return null; - } - return this.tracing.toObject(RealtimeSessionTracingConfiguration.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreateRequestGAAudioOutputVoice.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreateRequestGAAudioOutputVoice.java deleted file mode 100644 index 8d8692dec5a6a..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreateRequestGAAudioOutputVoice.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimeSessionCreateRequestGAAudioOutputVoice model. - */ -@Immutable -@Beta(warningText = "Preview API.") -public final class RealtimeSessionCreateRequestGAAudioOutputVoice - implements JsonSerializable { - - /* - * The id property. - */ - @Generated - private final String id; - - /** - * Creates an instance of RealtimeSessionCreateRequestGAAudioOutputVoice class. - * - * @param id the id value to set. - */ - @Generated - public RealtimeSessionCreateRequestGAAudioOutputVoice(String id) { - this.id = id; - } - - /** - * Get the id property: The id property. - * - * @return the id value. - */ - @Generated - public String getId() { - return this.id; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("id", this.id); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionCreateRequestGAAudioOutputVoice from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionCreateRequestGAAudioOutputVoice if the JsonReader was pointing to an - * instance of it, or null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the RealtimeSessionCreateRequestGAAudioOutputVoice. - */ - @Generated - public static RealtimeSessionCreateRequestGAAudioOutputVoice fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String id = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("id".equals(fieldName)) { - id = reader.getString(); - } else { - reader.skipChildren(); - } - } - return new RealtimeSessionCreateRequestGAAudioOutputVoice(id); - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java index c8305e58ae94b..e911776ab669b 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java @@ -6,7 +6,6 @@ import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; -import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; @@ -37,7 +36,7 @@ public final class RealtimeSessionCreatedEvent extends RealtimeServerEvent { * The session configuration. */ @Generated - private final BinaryData session; + private final VoiceAgentSessionResponseConfiguration session; /* * The session-scoped conversation id. When present, responses attached to the session conversation use the same @@ -46,18 +45,6 @@ public final class RealtimeSessionCreatedEvent extends RealtimeServerEvent { @Generated private String conversationId; - /** - * Creates an instance of RealtimeSessionCreatedEvent class. - * - * @param eventId the eventId value to set. - * @param session the session value to set. - */ - RealtimeSessionCreatedEvent(String eventId, BinaryData session) { - // AI Tooling: union type - this.eventId = eventId; - this.session = session; - } - /** * Get the type property: The type property. * @@ -79,16 +66,6 @@ public String getEventId() { return this.eventId; } - /** - * Get the session property: The session configuration. - * - * @return the session value. - */ - BinaryData getSession() { - // AI Tooling: union type - return this.session; - } - /** * Get the conversationId property: The session-scoped conversation id. When present, responses attached to the * session conversation use the same value in `response.created` and `response.done`. @@ -108,8 +85,7 @@ public String getConversationId() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("event_id", this.eventId); - jsonWriter.writeFieldName("session"); - this.session.writeTo(jsonWriter); + jsonWriter.writeJsonField("session", this.session); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("conversation_id", this.conversationId); return jsonWriter.writeEndObject(); @@ -128,7 +104,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static RealtimeSessionCreatedEvent fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String eventId = null; - BinaryData session = null; + VoiceAgentSessionResponseConfiguration session = null; RealtimeServerEventType type = RealtimeServerEventType.SESSION_CREATED; String conversationId = null; while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -137,7 +113,7 @@ public static RealtimeSessionCreatedEvent fromJson(JsonReader jsonReader) throws if ("event_id".equals(fieldName)) { eventId = reader.getString(); } else if ("session".equals(fieldName)) { - session = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + session = VoiceAgentSessionResponseConfiguration.fromJson(reader); } else if ("type".equals(fieldName)) { type = RealtimeServerEventType.fromString(reader.getString()); } else if ("conversation_id".equals(fieldName)) { @@ -155,32 +131,24 @@ public static RealtimeSessionCreatedEvent fromJson(JsonReader jsonReader) throws } /** - * Get the session property: The session configuration. + * Creates an instance of RealtimeSessionCreatedEvent class. * - * @return the session value as a {@link VoiceAgentSessionResponseConfiguration}, or {@code null} when it is not set - * or holds another variant. + * @param eventId the eventId value to set. + * @param session the session value to set. */ - public VoiceAgentSessionResponseConfiguration getSessionAsVoiceAgentSessionResponseConfiguration() { - // AI Tooling: union type - if (this.session == null) { - return null; - } - String json = this.session.toString().trim(); - if (!(json.startsWith("{"))) { - return null; - } - return this.session.toObject(VoiceAgentSessionResponseConfiguration.class); + public RealtimeSessionCreatedEvent(String eventId, VoiceAgentSessionResponseConfiguration session) { + // AI Tooling: typed session + this.eventId = eventId; + this.session = session; } /** - * Creates an instance of RealtimeSessionCreatedEvent class. + * Get the session property: The session configuration. * - * @param eventId the eventId value to set. - * @param session the {@link VoiceAgentSessionResponseConfiguration} session to set. + * @return the session value. */ - public RealtimeSessionCreatedEvent(String eventId, VoiceAgentSessionResponseConfiguration session) { - // AI Tooling: union type - this.eventId = eventId; - this.session = session == null ? null : BinaryData.fromObject(session); + @Generated + public VoiceAgentSessionResponseConfiguration getSession() { + return this.session; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionTracingConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionTracingConfiguration.java deleted file mode 100644 index 7ad3246ebd1b0..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionTracingConfiguration.java +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.BinaryData; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.util.Map; - -/** - * The RealtimeSessionTracingConfiguration model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionTracingConfiguration - implements JsonSerializable { - - /* - * The workflow_name property. - */ - @Generated - private String workflowName; - - /* - * The group_id property. - */ - @Generated - private String groupId; - - /* - * The metadata property. - */ - @Generated - private Map metadata; - - /** - * Creates an instance of RealtimeSessionTracingConfiguration class. - */ - @Generated - public RealtimeSessionTracingConfiguration() { - } - - /** - * Get the workflowName property: The workflow_name property. - * - * @return the workflowName value. - */ - @Generated - public String getWorkflowName() { - return this.workflowName; - } - - /** - * Set the workflowName property: The workflow_name property. - * - * @param workflowName the workflowName value to set. - * @return the RealtimeSessionTracingConfiguration object itself. - */ - @Generated - public RealtimeSessionTracingConfiguration setWorkflowName(String workflowName) { - this.workflowName = workflowName; - return this; - } - - /** - * Get the groupId property: The group_id property. - * - * @return the groupId value. - */ - @Generated - public String getGroupId() { - return this.groupId; - } - - /** - * Set the groupId property: The group_id property. - * - * @param groupId the groupId value to set. - * @return the RealtimeSessionTracingConfiguration object itself. - */ - @Generated - public RealtimeSessionTracingConfiguration setGroupId(String groupId) { - this.groupId = groupId; - return this; - } - - /** - * Get the metadata property: The metadata property. - * - * @return the metadata value. - */ - @Generated - public Map getMetadata() { - return this.metadata; - } - - /** - * Set the metadata property: The metadata property. - * - * @param metadata the metadata value to set. - * @return the RealtimeSessionTracingConfiguration object itself. - */ - @Generated - public RealtimeSessionTracingConfiguration setMetadata(Map metadata) { - this.metadata = metadata; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("workflow_name", this.workflowName); - jsonWriter.writeStringField("group_id", this.groupId); - jsonWriter.writeMapField("metadata", this.metadata, (writer, element) -> { - if (element == null) { - writer.writeNull(); - } else { - element.writeTo(writer); - } - }); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeSessionTracingConfiguration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionTracingConfiguration if the JsonReader was pointing to an instance of it, - * or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionTracingConfiguration. - */ - @Generated - public static RealtimeSessionTracingConfiguration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeSessionTracingConfiguration deserializedRealtimeSessionTracingConfiguration - = new RealtimeSessionTracingConfiguration(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("workflow_name".equals(fieldName)) { - deserializedRealtimeSessionTracingConfiguration.workflowName = reader.getString(); - } else if ("group_id".equals(fieldName)) { - deserializedRealtimeSessionTracingConfiguration.groupId = reader.getString(); - } else if ("metadata".equals(fieldName)) { - Map metadata = reader.readMap(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); - deserializedRealtimeSessionTracingConfiguration.metadata = metadata; - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeSessionTracingConfiguration; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionType.java deleted file mode 100644 index d2fa53e26eb88..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionType.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for RealtimeSessionType. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeSessionType extends ExpandableStringEnum { - - /** - * Static value realtime for RealtimeSessionType. - */ - @Generated - public static final RealtimeSessionType REALTIME = fromString("realtime"); - - /** - * Static value transcription for RealtimeSessionType. - */ - @Generated - public static final RealtimeSessionType TRANSCRIPTION = fromString("transcription"); - - /** - * Creates a new instance of RealtimeSessionType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public RealtimeSessionType() { - } - - /** - * Creates or finds a RealtimeSessionType from its string representation. - * - * @param name a name to look for. - * @return the corresponding RealtimeSessionType. - */ - @Generated - public static RealtimeSessionType fromString(String name) { - return fromString(name, RealtimeSessionType.class); - } - - /** - * Gets known RealtimeSessionType values. - * - * @return known RealtimeSessionType values. - */ - @Generated - public static Collection values() { - return values(RealtimeSessionType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java index 50d12a860d9bf..abe19ce580e3d 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java @@ -3,12 +3,15 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.SessionUpdateEvent.Session; import java.io.IOException; /** @@ -50,17 +53,7 @@ public final class RealtimeSessionUpdateEvent extends RealtimeClientEvent { * session or a transcription session. */ @Generated - private final RealtimeSessionConfigurationBase session; - - /** - * Creates an instance of RealtimeSessionUpdateEvent class. - * - * @param session the session value to set. - */ - @Generated - public RealtimeSessionUpdateEvent(RealtimeSessionConfigurationBase session) { - this.session = session; - } + private final Session session; /** * Get the type property: The type property. @@ -106,18 +99,21 @@ public RealtimeSessionUpdateEvent setEventId(String eventId) { * @return the session value. */ @Generated - public RealtimeSessionConfigurationBase getSession() { + public Session getSession() { return this.session; } /** * {@inheritDoc} */ - @Generated @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("session", this.session); + if (this.session != null) { + jsonWriter.writeFieldName("session"); + OpenAIJsonHelper.toBinaryData(this.session).writeTo(jsonWriter); + } jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("event_id", this.eventId); return jsonWriter.writeEndObject(); @@ -132,17 +128,19 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * @throws IllegalStateException If the deserialized JSON object was missing any required properties. * @throws IOException If an error occurs while reading the RealtimeSessionUpdateEvent. */ - @Generated public static RealtimeSessionUpdateEvent fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup return jsonReader.readObject(reader -> { - RealtimeSessionConfigurationBase session = null; + Session session = null; RealtimeClientEventType type = RealtimeClientEventType.SESSION_UPDATE; String eventId = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("session".equals(fieldName)) { - session = RealtimeSessionConfigurationBase.fromJson(reader); + BinaryData sessionData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + session = OpenAIJsonHelper.fromBinaryData(sessionData, Session.class); } else if ("type".equals(fieldName)) { type = RealtimeClientEventType.fromString(reader.getString()); } else if ("event_id".equals(fieldName)) { @@ -157,4 +155,14 @@ public static RealtimeSessionUpdateEvent fromJson(JsonReader jsonReader) throws return deserializedRealtimeSessionUpdateEvent; }); } + + /** + * Creates an instance of RealtimeSessionUpdateEvent class. + * + * @param session the session value to set. + */ + @Generated + public RealtimeSessionUpdateEvent(Session session) { + this.session = session; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java index a00c2b890e3fe..cc15a38a1f29c 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java @@ -6,7 +6,6 @@ import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; -import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; @@ -36,19 +35,7 @@ public final class RealtimeSessionUpdatedEvent extends RealtimeServerEvent { * The session configuration. */ @Generated - private final BinaryData session; - - /** - * Creates an instance of RealtimeSessionUpdatedEvent class. - * - * @param eventId the eventId value to set. - * @param session the session value to set. - */ - RealtimeSessionUpdatedEvent(String eventId, BinaryData session) { - // AI Tooling: union type - this.eventId = eventId; - this.session = session; - } + private final VoiceAgentSessionResponseConfiguration session; /** * Get the type property: The type property. @@ -71,16 +58,6 @@ public String getEventId() { return this.eventId; } - /** - * Get the session property: The session configuration. - * - * @return the session value. - */ - BinaryData getSession() { - // AI Tooling: union type - return this.session; - } - /** * {@inheritDoc} */ @@ -89,8 +66,7 @@ BinaryData getSession() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("event_id", this.eventId); - jsonWriter.writeFieldName("session"); - this.session.writeTo(jsonWriter); + jsonWriter.writeJsonField("session", this.session); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } @@ -108,7 +84,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static RealtimeSessionUpdatedEvent fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String eventId = null; - BinaryData session = null; + VoiceAgentSessionResponseConfiguration session = null; RealtimeServerEventType type = RealtimeServerEventType.SESSION_UPDATED; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); @@ -116,7 +92,7 @@ public static RealtimeSessionUpdatedEvent fromJson(JsonReader jsonReader) throws if ("event_id".equals(fieldName)) { eventId = reader.getString(); } else if ("session".equals(fieldName)) { - session = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + session = VoiceAgentSessionResponseConfiguration.fromJson(reader); } else if ("type".equals(fieldName)) { type = RealtimeServerEventType.fromString(reader.getString()); } else { @@ -131,32 +107,24 @@ public static RealtimeSessionUpdatedEvent fromJson(JsonReader jsonReader) throws } /** - * Get the session property: The session configuration. + * Creates an instance of RealtimeSessionUpdatedEvent class. * - * @return the session value as a {@link VoiceAgentSessionResponseConfiguration}, or {@code null} when it is not set - * or holds another variant. + * @param eventId the eventId value to set. + * @param session the session value to set. */ - public VoiceAgentSessionResponseConfiguration getSessionAsVoiceAgentSessionResponseConfiguration() { - // AI Tooling: union type - if (this.session == null) { - return null; - } - String json = this.session.toString().trim(); - if (!(json.startsWith("{"))) { - return null; - } - return this.session.toObject(VoiceAgentSessionResponseConfiguration.class); + public RealtimeSessionUpdatedEvent(String eventId, VoiceAgentSessionResponseConfiguration session) { + // AI Tooling: typed session + this.eventId = eventId; + this.session = session; } /** - * Creates an instance of RealtimeSessionUpdatedEvent class. + * Get the session property: The session configuration. * - * @param eventId the eventId value to set. - * @param session the {@link VoiceAgentSessionResponseConfiguration} session to set. + * @return the session value. */ - public RealtimeSessionUpdatedEvent(String eventId, VoiceAgentSessionResponseConfiguration session) { - // AI Tooling: union type - this.eventId = eventId; - this.session = session == null ? null : BinaryData.fromObject(session); + @Generated + public VoiceAgentSessionResponseConfiguration getSession() { + return this.session; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioConfiguration.java deleted file mode 100644 index 978f0c1cca1d2..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioConfiguration.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The RealtimeTranscriptionSessionAudioConfiguration model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeTranscriptionSessionAudioConfiguration - implements JsonSerializable { - - /* - * The input property. - */ - @Generated - private RealtimeTranscriptionSessionAudioInput input; - - /** - * Creates an instance of RealtimeTranscriptionSessionAudioConfiguration class. - */ - @Generated - public RealtimeTranscriptionSessionAudioConfiguration() { - } - - /** - * Get the input property: The input property. - * - * @return the input value. - */ - @Generated - public RealtimeTranscriptionSessionAudioInput getInput() { - return this.input; - } - - /** - * Set the input property: The input property. - * - * @param input the input value to set. - * @return the RealtimeTranscriptionSessionAudioConfiguration object itself. - */ - @Generated - public RealtimeTranscriptionSessionAudioConfiguration setInput(RealtimeTranscriptionSessionAudioInput input) { - this.input = input; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("input", this.input); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeTranscriptionSessionAudioConfiguration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeTranscriptionSessionAudioConfiguration if the JsonReader was pointing to an - * instance of it, or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeTranscriptionSessionAudioConfiguration. - */ - @Generated - public static RealtimeTranscriptionSessionAudioConfiguration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeTranscriptionSessionAudioConfiguration deserializedRealtimeTranscriptionSessionAudioConfiguration - = new RealtimeTranscriptionSessionAudioConfiguration(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("input".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionAudioConfiguration.input - = RealtimeTranscriptionSessionAudioInput.fromJson(reader); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeTranscriptionSessionAudioConfiguration; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioInput.java deleted file mode 100644 index be75d4752b60e..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioInput.java +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.OpenAIJsonHelper; -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.BinaryData; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import com.openai.models.realtime.RealtimeTranscriptionSessionAudioInput.NoiseReduction; -import java.io.IOException; - -/** - * The RealtimeTranscriptionSessionAudioInput model. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeTranscriptionSessionAudioInput - implements JsonSerializable { - - /* - * The format property. - */ - @Generated - private RealtimeAudioFormat format; - - /* - * The transcription property. - */ - @Generated - private AudioTranscription transcription; - - // AI Tooling: openai-java de-dup - private NoiseReduction noiseReduction; - - /* - * The turn_detection property. - */ - @Generated - private RealtimeTurnDetection turnDetection; - - /** - * Creates an instance of RealtimeTranscriptionSessionAudioInput class. - */ - @Generated - public RealtimeTranscriptionSessionAudioInput() { - } - - /** - * Get the format property: The format property. - * - * @return the format value. - */ - @Generated - public RealtimeAudioFormat getFormat() { - return this.format; - } - - /** - * Set the format property: The format property. - * - * @param format the format value to set. - * @return the RealtimeTranscriptionSessionAudioInput object itself. - */ - @Generated - public RealtimeTranscriptionSessionAudioInput setFormat(RealtimeAudioFormat format) { - this.format = format; - return this; - } - - /** - * Get the transcription property: The transcription property. - * - * @return the transcription value. - */ - @Generated - public AudioTranscription getTranscription() { - return this.transcription; - } - - /** - * Set the transcription property: The transcription property. - * - * @param transcription the transcription value to set. - * @return the RealtimeTranscriptionSessionAudioInput object itself. - */ - @Generated - public RealtimeTranscriptionSessionAudioInput setTranscription(AudioTranscription transcription) { - this.transcription = transcription; - return this; - } - - /** - * Get the noiseReduction property: The noise_reduction property. - * - * @return the noiseReduction value. - */ - public NoiseReduction getNoiseReduction() { - // AI Tooling: openai-java de-dup - return this.noiseReduction; - } - - /** - * Get the turnDetection property: The turn_detection property. - * - * @return the turnDetection value. - */ - @Generated - public RealtimeTurnDetection getTurnDetection() { - return this.turnDetection; - } - - /** - * Set the turnDetection property: The turn_detection property. - * - * @param turnDetection the turnDetection value to set. - * @return the RealtimeTranscriptionSessionAudioInput object itself. - */ - @Generated - public RealtimeTranscriptionSessionAudioInput setTurnDetection(RealtimeTurnDetection turnDetection) { - this.turnDetection = turnDetection; - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - // AI Tooling: openai-java de-dup - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("format", this.format); - jsonWriter.writeJsonField("transcription", this.transcription); - if (this.noiseReduction != null) { - jsonWriter.writeFieldName("noise_reduction"); - OpenAIJsonHelper.toBinaryData(this.noiseReduction).writeTo(jsonWriter); - } - jsonWriter.writeJsonField("turn_detection", this.turnDetection); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeTranscriptionSessionAudioInput from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeTranscriptionSessionAudioInput if the JsonReader was pointing to an - * instance of it, or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeTranscriptionSessionAudioInput. - */ - public static RealtimeTranscriptionSessionAudioInput fromJson(JsonReader jsonReader) throws IOException { - // AI Tooling: openai-java de-dup - return jsonReader.readObject(reader -> { - RealtimeTranscriptionSessionAudioInput deserializedRealtimeTranscriptionSessionAudioInput - = new RealtimeTranscriptionSessionAudioInput(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("format".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionAudioInput.format = RealtimeAudioFormat.fromJson(reader); - } else if ("transcription".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionAudioInput.transcription - = AudioTranscription.fromJson(reader); - } else if ("noise_reduction".equals(fieldName)) { - BinaryData noiseReductionData = reader.getNullable(r -> BinaryData.fromObject(r.readUntyped())); - deserializedRealtimeTranscriptionSessionAudioInput.noiseReduction - = OpenAIJsonHelper.fromBinaryData(noiseReductionData, NoiseReduction.class); - } else if ("turn_detection".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionAudioInput.turnDetection - = RealtimeTurnDetection.fromJson(reader); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeTranscriptionSessionAudioInput; - }); - } - - /** - * Set the noiseReduction property: The noise_reduction property. - * - * @param noiseReduction the noiseReduction value to set. - * @return the RealtimeTranscriptionSessionAudioInput object itself. - */ - public RealtimeTranscriptionSessionAudioInput setNoiseReduction(NoiseReduction noiseReduction) { - // AI Tooling: openai-java de-dup - this.noiseReduction = noiseReduction; - return this; - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionConfiguration.java deleted file mode 100644 index 6ec19a9d19af9..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionConfiguration.java +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.util.List; - -/** - * Realtime transcription session configuration - * - * Realtime transcription session object configuration. - */ -@Fluent -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeTranscriptionSessionConfiguration extends RealtimeSessionConfigurationBase { - - /* - * The type property. - */ - @Generated - private RealtimeSessionType type = RealtimeSessionType.TRANSCRIPTION; - - /* - * Configuration for input and output audio. - */ - @Generated - private RealtimeTranscriptionSessionAudioConfiguration audio; - - /* - * Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - */ - @Generated - private List include; - - /** - * Creates an instance of RealtimeTranscriptionSessionConfiguration class. - */ - @Generated - public RealtimeTranscriptionSessionConfiguration() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public RealtimeSessionType getType() { - return this.type; - } - - /** - * Get the audio property: Configuration for input and output audio. - * - * @return the audio value. - */ - @Generated - public RealtimeTranscriptionSessionAudioConfiguration getAudio() { - return this.audio; - } - - /** - * Set the audio property: Configuration for input and output audio. - * - * @param audio the audio value to set. - * @return the RealtimeTranscriptionSessionConfiguration object itself. - */ - @Generated - public RealtimeTranscriptionSessionConfiguration setAudio(RealtimeTranscriptionSessionAudioConfiguration audio) { - this.audio = audio; - return this; - } - - /** - * Get the include property: Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - * - * @return the include value. - */ - @Generated - public List getInclude() { - return this.include; - } - - /** - * Set the include property: Additional fields to include in server outputs. - * `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription. - * - * @param include the include value to set. - * @return the RealtimeTranscriptionSessionConfiguration object itself. - */ - @Generated - public RealtimeTranscriptionSessionConfiguration setInclude(List include) { - this.include = include; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeJsonField("audio", this.audio); - jsonWriter.writeArrayField("include", this.include, (writer, element) -> writer.writeString(element)); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeTranscriptionSessionConfiguration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeTranscriptionSessionConfiguration if the JsonReader was pointing to an instance of - * it, or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeTranscriptionSessionConfiguration. - */ - @Generated - public static RealtimeTranscriptionSessionConfiguration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeTranscriptionSessionConfiguration deserializedRealtimeTranscriptionSessionConfiguration - = new RealtimeTranscriptionSessionConfiguration(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionConfiguration.type - = RealtimeSessionType.fromString(reader.getString()); - } else if ("audio".equals(fieldName)) { - deserializedRealtimeTranscriptionSessionConfiguration.audio - = RealtimeTranscriptionSessionAudioConfiguration.fromJson(reader); - } else if ("include".equals(fieldName)) { - List include = reader.readArray(reader1 -> reader1.getString()); - deserializedRealtimeTranscriptionSessionConfiguration.include = include; - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeTranscriptionSessionConfiguration; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetection.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetection.java deleted file mode 100644 index b10c5bcc4e9b4..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetection.java +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Realtime Turn Detection - * - * Configuration for turn detection, ether Server VAD or Semantic VAD. This can be set to `null` to turn off, in which - * case the client must manually trigger model response. - * Server VAD means that the model will detect the start and end of speech based on audio volume and respond at the end - * of user speech. - * Semantic VAD is more advanced and uses a turn detection model (in conjunction with VAD) to semantically estimate - * whether the user has finished speaking, then dynamically sets a timeout based on this probability. For example, if - * user audio trails off with "uhhm", the model will score a low probability of turn end and wait longer for the user to - * continue speaking. This can be useful for more natural conversations, but may have a higher latency. - * For `gpt-realtime-whisper` transcription sessions, turn detection must be - * set to `null`; VAD is not supported. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class RealtimeTurnDetection implements JsonSerializable { - - /* - * The type property. - */ - @Generated - private RealtimeTurnDetectionType type = RealtimeTurnDetectionType.fromString("RealtimeTurnDetection"); - - /** - * Creates an instance of RealtimeTurnDetection class. - */ - @Generated - protected RealtimeTurnDetection() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - public RealtimeTurnDetectionType getType() { - return this.type; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RealtimeTurnDetection from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeTurnDetection if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeTurnDetection. - */ - @Generated - public static RealtimeTurnDetection fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String discriminatorValue = null; - try (JsonReader readerToUse = reader.bufferObject()) { - // Prepare for reading - readerToUse.nextToken(); - while (readerToUse.nextToken() != JsonToken.END_OBJECT) { - String fieldName = readerToUse.getFieldName(); - readerToUse.nextToken(); - if ("type".equals(fieldName)) { - discriminatorValue = readerToUse.getString(); - break; - } else { - readerToUse.skipChildren(); - } - } - // Use the discriminator value to determine which subtype should be deserialized. - if ("server_vad".equals(discriminatorValue)) { - return RealtimeServerVadTurnDetection.fromJson(readerToUse.reset()); - } else if ("semantic_vad".equals(discriminatorValue)) { - return RealtimeSemanticVadTurnDetection.fromJson(readerToUse.reset()); - } else { - return fromJsonKnownDiscriminator(readerToUse.reset()); - } - } - }); - } - - @Generated - static RealtimeTurnDetection fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - RealtimeTurnDetection deserializedRealtimeTurnDetection = new RealtimeTurnDetection(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedRealtimeTurnDetection.type = RealtimeTurnDetectionType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedRealtimeTurnDetection; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetectionType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetectionType.java deleted file mode 100644 index ab71e4a01c410..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeTurnDetectionType.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for RealtimeTurnDetectionType. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class RealtimeTurnDetectionType extends ExpandableStringEnum { - - /** - * Static value server_vad for RealtimeTurnDetectionType. - */ - @Generated - public static final RealtimeTurnDetectionType SERVER_VAD = fromString("server_vad"); - - /** - * Static value semantic_vad for RealtimeTurnDetectionType. - */ - @Generated - public static final RealtimeTurnDetectionType SEMANTIC_VAD = fromString("semantic_vad"); - - /** - * Creates a new instance of RealtimeTurnDetectionType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public RealtimeTurnDetectionType() { - } - - /** - * Creates or finds a RealtimeTurnDetectionType from its string representation. - * - * @param name a name to look for. - * @return the corresponding RealtimeTurnDetectionType. - */ - @Generated - public static RealtimeTurnDetectionType fromString(String name) { - return fromString(name, RealtimeTurnDetectionType.class); - } - - /** - * Gets known RealtimeTurnDetectionType values. - * - * @return known RealtimeTurnDetectionType values. - */ - @Generated - public static Collection values() { - return values(RealtimeTurnDetectionType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBinding.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBinding.java new file mode 100644 index 0000000000000..d52075949e7e9 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBinding.java @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Inbound binding using a same-project SipInbound connection for authentication/network restrictions. Creation does not + * prove regional runtime readiness. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class SipTelephonyBinding extends TelephonyBinding { + + /* + * The telephony provider. + */ + @Generated + private TelephonyProvider provider = TelephonyProvider.SIP; + + /* + * Optional display metadata, not a routing key or E.164-constrained destination. + */ + @Generated + private String phoneNumber; + + /* + * Exact E.164 caller numbers or restricted anchored patterns, validated by the service. Omit or use [] for no + * restriction. + */ + @Generated + private List allowedCallingNumbers; + + /** + * Get the provider property: The telephony provider. + * + * @return the provider value. + */ + @Generated + @Override + public TelephonyProvider getProvider() { + return this.provider; + } + + /** + * Get the phoneNumber property: Optional display metadata, not a routing key or E.164-constrained destination. + * + * @return the phoneNumber value. + */ + @Generated + public String getPhoneNumber() { + return this.phoneNumber; + } + + /** + * Get the allowedCallingNumbers property: Exact E.164 caller numbers or restricted anchored patterns, validated by + * the service. Omit or use [] for no restriction. + * + * @return the allowedCallingNumbers value. + */ + @Generated + public List getAllowedCallingNumbers() { + return this.allowedCallingNumbers; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("connection_name", getConnectionName()); + jsonWriter.writeStringField("label", getLabel()); + jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); + jsonWriter.writeStringField("phone_number", this.phoneNumber); + jsonWriter.writeArrayField("allowed_calling_numbers", this.allowedCallingNumbers, + (writer, element) -> writer.writeString(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of SipTelephonyBinding from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of SipTelephonyBinding if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the SipTelephonyBinding. + */ + @Generated + public static SipTelephonyBinding fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String connectionName = null; + String incomingCallUrl = null; + String label = null; + TelephonyProvider provider = TelephonyProvider.SIP; + String phoneNumber = null; + List allowedCallingNumbers = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("connection_name".equals(fieldName)) { + connectionName = reader.getString(); + } else if ("incoming_call_url".equals(fieldName)) { + incomingCallUrl = reader.getString(); + } else if ("label".equals(fieldName)) { + label = reader.getString(); + } else if ("provider".equals(fieldName)) { + provider = TelephonyProvider.fromString(reader.getString()); + } else if ("phone_number".equals(fieldName)) { + phoneNumber = reader.getString(); + } else if ("allowed_calling_numbers".equals(fieldName)) { + allowedCallingNumbers = reader.readArray(reader1 -> reader1.getString()); + } else { + reader.skipChildren(); + } + } + SipTelephonyBinding deserializedSipTelephonyBinding = new SipTelephonyBinding(connectionName); + deserializedSipTelephonyBinding.setId(id); + deserializedSipTelephonyBinding.setIncomingCallUrl(incomingCallUrl); + deserializedSipTelephonyBinding.setLabel(label); + deserializedSipTelephonyBinding.provider = provider; + deserializedSipTelephonyBinding.phoneNumber = phoneNumber; + deserializedSipTelephonyBinding.allowedCallingNumbers = allowedCallingNumbers; + return deserializedSipTelephonyBinding; + }); + } + + /** + * Creates an instance of SipTelephonyBinding class. + * + * @param connectionName the connectionName value to set. + */ + @Generated + public SipTelephonyBinding(String connectionName) { + super(connectionName); + } + + /** + * Set the phoneNumber property: Optional display metadata, not a routing key or E.164-constrained destination. + * + * @param phoneNumber the phoneNumber value to set. + * @return the SipTelephonyBinding object itself. + */ + @Generated + public SipTelephonyBinding setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + return this; + } + + /** + * Set the allowedCallingNumbers property: Exact E.164 caller numbers or restricted anchored patterns, validated by + * the service. Omit or use [] for no restriction. + * + * @param allowedCallingNumbers the allowedCallingNumbers value to set. + * @return the SipTelephonyBinding object itself. + */ + @Generated + public SipTelephonyBinding setAllowedCallingNumbers(List allowedCallingNumbers) { + this.allowedCallingNumbers = allowedCallingNumbers; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public SipTelephonyBinding setLabel(String label) { + super.setLabel(label); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBindingListItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBindingListItem.java new file mode 100644 index 0000000000000..7b2220024ecd1 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyBindingListItem.java @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * An inbound SIP binding returned in a list, including its current entity tag. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class SipTelephonyBindingListItem extends TelephonyBindingListItem { + + /* + * The telephony provider. + */ + @Generated + private TelephonyProvider provider = TelephonyProvider.SIP; + + /* + * Optional display phone metadata, not a routing key. + */ + @Generated + private String phoneNumber; + + /* + * Current exact E.164 caller numbers or restricted fully anchored patterns. + */ + @Generated + private List allowedCallingNumbers; + + /** + * Get the provider property: The telephony provider. + * + * @return the provider value. + */ + @Generated + @Override + public TelephonyProvider getProvider() { + return this.provider; + } + + /** + * Get the phoneNumber property: Optional display phone metadata, not a routing key. + * + * @return the phoneNumber value. + */ + @Generated + public String getPhoneNumber() { + return this.phoneNumber; + } + + /** + * Get the allowedCallingNumbers property: Current exact E.164 caller numbers or restricted fully anchored patterns. + * + * @return the allowedCallingNumbers value. + */ + @Generated + public List getAllowedCallingNumbers() { + return this.allowedCallingNumbers; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeStringField("connection_name", getConnectionName()); + jsonWriter.writeStringField("incoming_call_url", getIncomingCallUrl()); + jsonWriter.writeStringField("label", getLabel()); + jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); + jsonWriter.writeStringField("phone_number", this.phoneNumber); + jsonWriter.writeArrayField("allowed_calling_numbers", this.allowedCallingNumbers, + (writer, element) -> writer.writeString(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of SipTelephonyBindingListItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of SipTelephonyBindingListItem if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the SipTelephonyBindingListItem. + */ + @Generated + public static SipTelephonyBindingListItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String connectionName = null; + String incomingCallUrl = null; + String eTag = null; + String label = null; + TelephonyProvider provider = TelephonyProvider.SIP; + String phoneNumber = null; + List allowedCallingNumbers = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("connection_name".equals(fieldName)) { + connectionName = reader.getString(); + } else if ("incoming_call_url".equals(fieldName)) { + incomingCallUrl = reader.getString(); + } else if ("etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("label".equals(fieldName)) { + label = reader.getString(); + } else if ("provider".equals(fieldName)) { + provider = TelephonyProvider.fromString(reader.getString()); + } else if ("phone_number".equals(fieldName)) { + phoneNumber = reader.getString(); + } else if ("allowed_calling_numbers".equals(fieldName)) { + allowedCallingNumbers = reader.readArray(reader1 -> reader1.getString()); + } else { + reader.skipChildren(); + } + } + SipTelephonyBindingListItem deserializedSipTelephonyBindingListItem + = new SipTelephonyBindingListItem(id, connectionName, incomingCallUrl); + deserializedSipTelephonyBindingListItem.setETag(eTag); + deserializedSipTelephonyBindingListItem.setLabel(label); + deserializedSipTelephonyBindingListItem.provider = provider; + deserializedSipTelephonyBindingListItem.phoneNumber = phoneNumber; + deserializedSipTelephonyBindingListItem.allowedCallingNumbers = allowedCallingNumbers; + return deserializedSipTelephonyBindingListItem; + }); + } + + /** + * Creates an instance of SipTelephonyBindingListItem class. + * + * @param id the id value to set. + * @param connectionName the connectionName value to set. + * @param incomingCallUrl the incomingCallUrl value to set. + */ + @Generated + private SipTelephonyBindingListItem(String id, String connectionName, String incomingCallUrl) { + super(id, connectionName, incomingCallUrl); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java index 60d5c0cf49ec7..d5609c92ba973 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java @@ -3,6 +3,7 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.StructuredInputJsonHelper; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; import com.azure.core.util.BinaryData; @@ -160,8 +161,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * it was pointing to JSON null. * @throws IOException If an error occurs while reading the StructuredInputDefinition. */ - @Generated public static StructuredInputDefinition fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: Preserve structured input JSON without numeric coercion. return jsonReader.readObject(reader -> { StructuredInputDefinition deserializedStructuredInputDefinition = new StructuredInputDefinition(); while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -171,10 +172,10 @@ public static StructuredInputDefinition fromJson(JsonReader jsonReader) throws I deserializedStructuredInputDefinition.description = reader.getString(); } else if ("default_value".equals(fieldName)) { deserializedStructuredInputDefinition.defaultValue - = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + = reader.getNullable(StructuredInputJsonHelper::readJsonValue); } else if ("schema".equals(fieldName)) { - Map schema = reader.readMap(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); + Map schema + = reader.readMap(reader1 -> reader1.getNullable(StructuredInputJsonHelper::readJsonValue)); deserializedStructuredInputDefinition.schema = schema; } else if ("required".equals(fieldName)) { deserializedStructuredInputDefinition.required = reader.getNullable(JsonReader::getBoolean); diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java index fca3c6ba5df5e..87cb8d9e84613 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java @@ -4,8 +4,8 @@ package com.azure.ai.agents.models; import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; @@ -14,7 +14,7 @@ /** * A Microsoft Teams Phone extensibility binding owned by a voice agent. */ -@Immutable +@Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") public final class TeamsPhoneExtensibilityTelephonyBinding extends TelephonyBinding { @@ -36,22 +36,6 @@ public final class TeamsPhoneExtensibilityTelephonyBinding extends TelephonyBind @Generated private final String resourceAccountObjectId; - /** - * Creates an instance of TeamsPhoneExtensibilityTelephonyBinding class. - * - * @param id the id value to set. - * @param connectionName the connectionName value to set. - * @param status the status value to set. - * @param incomingCallUrl the incomingCallUrl value to set. - * @param resourceAccountObjectId the resourceAccountObjectId value to set. - */ - @Generated - private TeamsPhoneExtensibilityTelephonyBinding(String id, String connectionName, TelephonyBindingStatus status, - String incomingCallUrl, String resourceAccountObjectId) { - super(id, connectionName, status, incomingCallUrl); - this.resourceAccountObjectId = resourceAccountObjectId; - } - /** * Get the provider property: The telephony provider. * @@ -90,10 +74,7 @@ public String getResourceAccountObjectId() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("id", getId()); jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("status", getStatus() == null ? null : getStatus().toString()); - jsonWriter.writeStringField("incoming_call_url", getIncomingCallUrl()); jsonWriter.writeStringField("label", getLabel()); jsonWriter.writeStringField("resource_account_object_id", this.resourceAccountObjectId); jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); @@ -115,7 +96,6 @@ public static TeamsPhoneExtensibilityTelephonyBinding fromJson(JsonReader jsonRe return jsonReader.readObject(reader -> { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; String label = null; String resourceAccountObjectId = null; @@ -128,8 +108,6 @@ public static TeamsPhoneExtensibilityTelephonyBinding fromJson(JsonReader jsonRe id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("label".equals(fieldName)) { @@ -145,12 +123,47 @@ public static TeamsPhoneExtensibilityTelephonyBinding fromJson(JsonReader jsonRe } } TeamsPhoneExtensibilityTelephonyBinding deserializedTeamsPhoneExtensibilityTelephonyBinding - = new TeamsPhoneExtensibilityTelephonyBinding(id, connectionName, status, incomingCallUrl, - resourceAccountObjectId); + = new TeamsPhoneExtensibilityTelephonyBinding(connectionName, resourceAccountObjectId); + deserializedTeamsPhoneExtensibilityTelephonyBinding.setId(id); + deserializedTeamsPhoneExtensibilityTelephonyBinding.setIncomingCallUrl(incomingCallUrl); deserializedTeamsPhoneExtensibilityTelephonyBinding.setLabel(label); deserializedTeamsPhoneExtensibilityTelephonyBinding.provider = provider; deserializedTeamsPhoneExtensibilityTelephonyBinding.phoneNumber = phoneNumber; return deserializedTeamsPhoneExtensibilityTelephonyBinding; }); } + + /** + * Creates an instance of TeamsPhoneExtensibilityTelephonyBinding class. + * + * @param connectionName the connectionName value to set. + * @param resourceAccountObjectId the resourceAccountObjectId value to set. + */ + @Generated + public TeamsPhoneExtensibilityTelephonyBinding(String connectionName, String resourceAccountObjectId) { + super(connectionName); + this.resourceAccountObjectId = resourceAccountObjectId; + } + + /** + * Set the phoneNumber property: The optional display phone number for the Teams resource account. + * + * @param phoneNumber the phoneNumber value to set. + * @return the TeamsPhoneExtensibilityTelephonyBinding object itself. + */ + @Generated + public TeamsPhoneExtensibilityTelephonyBinding setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public TeamsPhoneExtensibilityTelephonyBinding setLabel(String label) { + super.setLabel(label); + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java index 66ba70ef8b667..99d4cadb73619 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java @@ -36,22 +36,6 @@ public final class TeamsPhoneExtensibilityTelephonyBindingListItem extends Telep @Generated private final String resourceAccountObjectId; - /** - * Creates an instance of TeamsPhoneExtensibilityTelephonyBindingListItem class. - * - * @param id the id value to set. - * @param connectionName the connectionName value to set. - * @param status the status value to set. - * @param incomingCallUrl the incomingCallUrl value to set. - * @param resourceAccountObjectId the resourceAccountObjectId value to set. - */ - @Generated - private TeamsPhoneExtensibilityTelephonyBindingListItem(String id, String connectionName, - TelephonyBindingStatus status, String incomingCallUrl, String resourceAccountObjectId) { - super(id, connectionName, status, incomingCallUrl); - this.resourceAccountObjectId = resourceAccountObjectId; - } - /** * Get the provider property: The telephony provider. * @@ -92,7 +76,6 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("id", getId()); jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("status", getStatus() == null ? null : getStatus().toString()); jsonWriter.writeStringField("incoming_call_url", getIncomingCallUrl()); jsonWriter.writeStringField("label", getLabel()); jsonWriter.writeStringField("resource_account_object_id", this.resourceAccountObjectId); @@ -115,7 +98,6 @@ public static TeamsPhoneExtensibilityTelephonyBindingListItem fromJson(JsonReade return jsonReader.readObject(reader -> { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; String eTag = null; String label = null; @@ -129,8 +111,6 @@ public static TeamsPhoneExtensibilityTelephonyBindingListItem fromJson(JsonReade id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("etag".equals(fieldName)) { @@ -148,7 +128,7 @@ public static TeamsPhoneExtensibilityTelephonyBindingListItem fromJson(JsonReade } } TeamsPhoneExtensibilityTelephonyBindingListItem deserializedTeamsPhoneExtensibilityTelephonyBindingListItem - = new TeamsPhoneExtensibilityTelephonyBindingListItem(id, connectionName, status, incomingCallUrl, + = new TeamsPhoneExtensibilityTelephonyBindingListItem(id, connectionName, incomingCallUrl, resourceAccountObjectId); deserializedTeamsPhoneExtensibilityTelephonyBindingListItem.setETag(eTag); deserializedTeamsPhoneExtensibilityTelephonyBindingListItem.setLabel(label); @@ -157,4 +137,19 @@ public static TeamsPhoneExtensibilityTelephonyBindingListItem fromJson(JsonReade return deserializedTeamsPhoneExtensibilityTelephonyBindingListItem; }); } + + /** + * Creates an instance of TeamsPhoneExtensibilityTelephonyBindingListItem class. + * + * @param id the id value to set. + * @param connectionName the connectionName value to set. + * @param incomingCallUrl the incomingCallUrl value to set. + * @param resourceAccountObjectId the resourceAccountObjectId value to set. + */ + @Generated + private TeamsPhoneExtensibilityTelephonyBindingListItem(String id, String connectionName, String incomingCallUrl, + String resourceAccountObjectId) { + super(id, connectionName, incomingCallUrl); + this.resourceAccountObjectId = resourceAccountObjectId; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddress.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddress.java new file mode 100644 index 0000000000000..6050b6b566f07 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddress.java @@ -0,0 +1,140 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Shared source, recipient and transfer address. Connections validate each role before dialing; unsupported types fail. + * New types may be added. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class TelephonyAddress implements JsonSerializable { + + /* + * Endpoint address type. + */ + @Generated + private TelephonyAddressType type = TelephonyAddressType.fromString("TelephonyAddress"); + + /* + * Concrete address value. Known variants apply their format constraints; unknown variants are rejected before + * dialing. + */ + @Generated + private final String value; + + /** + * Creates an instance of TelephonyAddress class. + * + * @param value the value value to set. + */ + @Generated + protected TelephonyAddress(String value) { + this.value = value; + } + + /** + * Get the type property: Endpoint address type. + * + * @return the type value. + */ + @Generated + public TelephonyAddressType getType() { + return this.type; + } + + /** + * Get the value property: Concrete address value. Known variants apply their format constraints; unknown variants + * are rejected before dialing. + * + * @return the value value. + */ + @Generated + public String getValue() { + return this.value; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("value", this.value); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyAddress from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyAddress if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyAddress. + */ + @Generated + public static TelephonyAddress fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("type".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("phone_number".equals(discriminatorValue)) { + return TelephonyPhoneNumber.fromJson(readerToUse.reset()); + } else if ("teams".equals(discriminatorValue)) { + return TelephonyTeamsAddress.fromJson(readerToUse.reset()); + } else if ("sip".equals(discriminatorValue)) { + return TelephonySipAddress.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static TelephonyAddress fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String value = null; + TelephonyAddressType type = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("value".equals(fieldName)) { + value = reader.getString(); + } else if ("type".equals(fieldName)) { + type = TelephonyAddressType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + TelephonyAddress deserializedTelephonyAddress = new TelephonyAddress(value); + deserializedTelephonyAddress.type = type; + return deserializedTelephonyAddress; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddressType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddressType.java new file mode 100644 index 0000000000000..36b76cda90c84 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyAddressType.java @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Extensible endpoint address kinds. Address type describes the endpoint independently of the provider. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyAddressType extends ExpandableStringEnum { + + /** + * An E.164 phone number. + */ + @Generated + public static final TelephonyAddressType PHONE_NUMBER = fromString("phone_number"); + + /** + * A Microsoft Teams identity. Source addresses require a nonempty resource-account object GUID; transfer + * destinations also support 28:orgid:{guid}. + */ + @Generated + public static final TelephonyAddressType TEAMS = fromString("teams"); + + /** + * A SIP or SIPS destination for transfer. + */ + @Generated + public static final TelephonyAddressType SIP = fromString("sip"); + + /** + * Creates a new instance of TelephonyAddressType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public TelephonyAddressType() { + } + + /** + * Creates or finds a TelephonyAddressType from its string representation. + * + * @param name a name to look for. + * @return the corresponding TelephonyAddressType. + */ + @Generated + public static TelephonyAddressType fromString(String name) { + return fromString(name, TelephonyAddressType.class); + } + + /** + * Gets known TelephonyAddressType values. + * + * @return known TelephonyAddressType values. + */ + @Generated + public static Collection values() { + return values(TelephonyAddressType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBinding.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBinding.java index 35518decb6848..5ffa712c98253 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBinding.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBinding.java @@ -4,8 +4,8 @@ package com.azure.ai.agents.models; import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; @@ -15,7 +15,7 @@ /** * A telephony binding owned by a voice agent. */ -@Immutable +@Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") public class TelephonyBinding implements JsonSerializable { @@ -29,7 +29,7 @@ public class TelephonyBinding implements JsonSerializable { * The service-generated binding identifier. */ @Generated - private final String id; + private String id; /* * The optional display label for the binding. @@ -38,33 +38,11 @@ public class TelephonyBinding implements JsonSerializable { private String label; /* - * The lifecycle status. + * The service-generated incoming address: an HTTPS webhook for webhook-based providers or a SIP/SIPS ingress URI + * for SIP. */ @Generated - private final TelephonyBindingStatus status; - - /* - * The service-generated webhook URL to configure with the telephony provider. - */ - @Generated - private final String incomingCallUrl; - - /** - * Creates an instance of TelephonyBinding class. - * - * @param id the id value to set. - * @param connectionName the connectionName value to set. - * @param status the status value to set. - * @param incomingCallUrl the incomingCallUrl value to set. - */ - @Generated - protected TelephonyBinding(String id, String connectionName, TelephonyBindingStatus status, - String incomingCallUrl) { - this.id = id; - this.connectionName = connectionName; - this.status = status; - this.incomingCallUrl = incomingCallUrl; - } + private String incomingCallUrl; /** * Get the provider property: The telephony provider. @@ -103,23 +81,14 @@ public String getLabel() { * @return the TelephonyBinding object itself. */ @Generated - TelephonyBinding setLabel(String label) { + public TelephonyBinding setLabel(String label) { this.label = label; return this; } /** - * Get the status property: The lifecycle status. - * - * @return the status value. - */ - @Generated - public TelephonyBindingStatus getStatus() { - return this.status; - } - - /** - * Get the incomingCallUrl property: The service-generated webhook URL to configure with the telephony provider. + * Get the incomingCallUrl property: The service-generated incoming address: an HTTPS webhook for webhook-based + * providers or a SIP/SIPS ingress URI for SIP. * * @return the incomingCallUrl value. */ @@ -135,10 +104,7 @@ public String getIncomingCallUrl() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("id", this.id); jsonWriter.writeStringField("connection_name", this.connectionName); - jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); - jsonWriter.writeStringField("incoming_call_url", this.incomingCallUrl); jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); jsonWriter.writeStringField("label", this.label); return jsonWriter.writeEndObject(); @@ -175,6 +141,8 @@ public static TelephonyBinding fromJson(JsonReader jsonReader) throws IOExceptio return TeamsPhoneExtensibilityTelephonyBinding.fromJson(readerToUse.reset()); } else if ("twilio".equals(discriminatorValue)) { return TwilioTelephonyBinding.fromJson(readerToUse.reset()); + } else if ("sip".equals(discriminatorValue)) { + return SipTelephonyBinding.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } @@ -187,7 +155,6 @@ static TelephonyBinding fromJsonKnownDiscriminator(JsonReader jsonReader) throws return jsonReader.readObject(reader -> { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; TelephonyProvider provider = null; String label = null; @@ -198,8 +165,6 @@ static TelephonyBinding fromJsonKnownDiscriminator(JsonReader jsonReader) throws id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("provider".equals(fieldName)) { @@ -210,8 +175,9 @@ static TelephonyBinding fromJsonKnownDiscriminator(JsonReader jsonReader) throws reader.skipChildren(); } } - TelephonyBinding deserializedTelephonyBinding - = new TelephonyBinding(id, connectionName, status, incomingCallUrl); + TelephonyBinding deserializedTelephonyBinding = new TelephonyBinding(connectionName); + deserializedTelephonyBinding.id = id; + deserializedTelephonyBinding.incomingCallUrl = incomingCallUrl; deserializedTelephonyBinding.provider = provider; deserializedTelephonyBinding.label = label; return deserializedTelephonyBinding; @@ -233,4 +199,39 @@ static TelephonyBinding fromJsonKnownDiscriminator(JsonReader jsonReader) throws public String getConnectionName() { return this.connectionName; } + + /** + * Creates an instance of TelephonyBinding class. + * + * @param connectionName the connectionName value to set. + */ + @Generated + protected TelephonyBinding(String connectionName) { + this.connectionName = connectionName; + } + + /** + * Set the id property: The service-generated binding identifier. + * + * @param id the id value to set. + * @return the TelephonyBinding object itself. + */ + @Generated + TelephonyBinding setId(String id) { + this.id = id; + return this; + } + + /** + * Set the incomingCallUrl property: The service-generated incoming address: an HTTPS webhook for webhook-based + * providers or a SIP/SIPS ingress URI for SIP. + * + * @param incomingCallUrl the incomingCallUrl value to set. + * @return the TelephonyBinding object itself. + */ + @Generated + TelephonyBinding setIncomingCallUrl(String incomingCallUrl) { + this.incomingCallUrl = incomingCallUrl; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java index 66fced7f239bd..a7c548953d4e9 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java @@ -38,34 +38,11 @@ public class TelephonyBindingListItem implements JsonSerializable { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; String eTag = null; TelephonyProvider provider = null; @@ -199,8 +167,6 @@ static TelephonyBindingListItem fromJsonKnownDiscriminator(JsonReader jsonReader id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("etag".equals(fieldName)) { @@ -214,7 +180,7 @@ static TelephonyBindingListItem fromJsonKnownDiscriminator(JsonReader jsonReader } } TelephonyBindingListItem deserializedTelephonyBindingListItem - = new TelephonyBindingListItem(id, connectionName, status, incomingCallUrl); + = new TelephonyBindingListItem(id, connectionName, incomingCallUrl); deserializedTelephonyBindingListItem.eTag = eTag; deserializedTelephonyBindingListItem.provider = provider; deserializedTelephonyBindingListItem.label = label; @@ -265,4 +231,18 @@ TelephonyBindingListItem setETag(String eTag) { this.eTag = eTag; return this; } + + /** + * Creates an instance of TelephonyBindingListItem class. + * + * @param id the id value to set. + * @param connectionName the connectionName value to set. + * @param incomingCallUrl the incomingCallUrl value to set. + */ + @Generated + protected TelephonyBindingListItem(String id, String connectionName, String incomingCallUrl) { + this.id = id; + this.connectionName = connectionName; + this.incomingCallUrl = incomingCallUrl; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingStatus.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingStatus.java deleted file mode 100644 index 9b6f9587957c2..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyBindingStatus.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * The lifecycle status of a telephony binding. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TelephonyBindingStatus extends ExpandableStringEnum { - - /** - * The binding accepts new inbound calls. - */ - @Generated - public static final TelephonyBindingStatus ACTIVE = fromString("active"); - - /** - * The binding remains configured but rejects new inbound calls. - */ - @Generated - public static final TelephonyBindingStatus SUSPENDED = fromString("suspended"); - - /** - * Creates a new instance of TelephonyBindingStatus value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public TelephonyBindingStatus() { - } - - /** - * Creates or finds a TelephonyBindingStatus from its string representation. - * - * @param name a name to look for. - * @return the corresponding TelephonyBindingStatus. - */ - @Generated - public static TelephonyBindingStatus fromString(String name) { - return fromString(name, TelephonyBindingStatus.class); - } - - /** - * Gets known TelephonyBindingStatus values. - * - * @return known TelephonyBindingStatus values. - */ - @Generated - public static Collection values() { - return values(TelephonyBindingStatus.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java index c45eaf6b1e47f..8f688690d0f4d 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java @@ -3,6 +3,7 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.StructuredInputJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; @@ -28,7 +29,7 @@ public final class TelephonyCallJob implements JsonSerializable structuredInputs; @@ -54,19 +53,19 @@ public final class TelephonyCallJob implements JsonSerializable { if (element == null) { @@ -304,10 +295,6 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } }); jsonWriter.writeJsonField("schedule", this.schedule); - jsonWriter.writeJsonField("cancellation", this.cancellation); - jsonWriter.writeNumberField("next_attempt_at", this.nextAttemptAt); - jsonWriter.writeStringField("terminal_reason", - this.terminalReason == null ? null : this.terminalReason.toString()); return jsonWriter.writeEndObject(); } @@ -320,35 +307,34 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * @throws IllegalStateException If the deserialized JSON object was missing any required properties. * @throws IOException If an error occurs while reading the TelephonyCallJob. */ - @Generated public static TelephonyCallJob fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: Preserve structured input JSON without numeric coercion. return jsonReader.readObject(reader -> { - TelephonyOutboundDestination destination = null; + TelephonyAddress destination = null; String connectionName = null; - String source = null; String id = null; String agentName = null; TelephonyCallJobStatus status = null; TelephonyOutboundRetryPolicy retryPolicy = null; int attemptCount = 0; long revision = 0L; - OffsetDateTime createdAt = null; - OffsetDateTime updatedAt = null; + long createdAt = 0L; + long updatedAt = 0L; + TelephonyAddress source = null; String purpose = null; Map structuredInputs = null; TelephonyCallJobSchedule schedule = null; TelephonyCallJobCancellation cancellation = null; Long nextAttemptAt = null; TelephonyCallJobTerminalReason terminalReason = null; + String campaignName = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("destination".equals(fieldName)) { - destination = TelephonyOutboundDestination.fromJson(reader); + destination = TelephonyAddress.fromJson(reader); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("source".equals(fieldName)) { - source = reader.getString(); } else if ("id".equals(fieldName)) { id = reader.getString(); } else if ("agent_name".equals(fieldName)) { @@ -362,14 +348,16 @@ public static TelephonyCallJob fromJson(JsonReader jsonReader) throws IOExceptio } else if ("revision".equals(fieldName)) { revision = reader.getLong(); } else if ("created_at".equals(fieldName)) { - createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + createdAt = reader.getLong(); } else if ("updated_at".equals(fieldName)) { - updatedAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + updatedAt = reader.getLong(); + } else if ("source".equals(fieldName)) { + source = TelephonyAddress.fromJson(reader); } else if ("purpose".equals(fieldName)) { purpose = reader.getString(); } else if ("structured_inputs".equals(fieldName)) { - structuredInputs = reader.readMap(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); + structuredInputs + = reader.readMap(reader1 -> reader1.getNullable(StructuredInputJsonHelper::readJsonValue)); } else if ("schedule".equals(fieldName)) { schedule = TelephonyCallJobSchedule.fromJson(reader); } else if ("cancellation".equals(fieldName)) { @@ -378,42 +366,50 @@ public static TelephonyCallJob fromJson(JsonReader jsonReader) throws IOExceptio nextAttemptAt = reader.getNullable(JsonReader::getLong); } else if ("terminal_reason".equals(fieldName)) { terminalReason = TelephonyCallJobTerminalReason.fromString(reader.getString()); + } else if ("campaign_name".equals(fieldName)) { + campaignName = reader.getString(); } else { reader.skipChildren(); } } - TelephonyCallJob deserializedTelephonyCallJob = new TelephonyCallJob(destination, connectionName, source, - id, agentName, status, retryPolicy, attemptCount, revision, createdAt, updatedAt); + TelephonyCallJob deserializedTelephonyCallJob + = new TelephonyCallJob(destination, connectionName, retryPolicy, source); + deserializedTelephonyCallJob.id = id; + deserializedTelephonyCallJob.agentName = agentName; + deserializedTelephonyCallJob.status = status; + deserializedTelephonyCallJob.attemptCount = attemptCount; + deserializedTelephonyCallJob.revision = revision; + deserializedTelephonyCallJob.createdAt = createdAt; + deserializedTelephonyCallJob.updatedAt = updatedAt; deserializedTelephonyCallJob.purpose = purpose; deserializedTelephonyCallJob.structuredInputs = structuredInputs; deserializedTelephonyCallJob.schedule = schedule; deserializedTelephonyCallJob.cancellation = cancellation; deserializedTelephonyCallJob.nextAttemptAt = nextAttemptAt; deserializedTelephonyCallJob.terminalReason = terminalReason; + deserializedTelephonyCallJob.campaignName = campaignName; return deserializedTelephonyCallJob; }); } /* - * The Foundry connection name in the current project used to originate the call. Its category selects Twilio or - * Azure Communication Services / Teams Phone extensibility. No inbound telephony binding is required. + * Same-project Twilio, ACS/Teams Phone extensibility or SipOutbound connection; no inbound binding needed. SIP + * requires CustomKeys and a DNS target, revalidated before dialing, not a connectivity guarantee. */ @Generated private final String connectionName; /* - * The caller identity used to originate the call. For a Twilio connection, provide an authorized E.164 phone - * number. For an Azure Communication Services / Teams Phone extensibility connection, provide the Teams Resource - * Account object ID. The identity type is inferred from the connection category; originating does not change - * inbound routing. + * Caller identity: phone_number for Twilio/SIP, or a teams resource-account GUID for ACS/Teams Phone extensibility. + * No sip source URI. */ @Generated - private final String source; + private final TelephonyAddress source; /** - * Get the connectionName property: The Foundry connection name in the current project used to originate the call. - * Its category selects Twilio or Azure Communication Services / Teams Phone extensibility. No inbound telephony - * binding is required. + * Get the connectionName property: Same-project Twilio, ACS/Teams Phone extensibility or SipOutbound connection; no + * inbound binding needed. SIP requires CustomKeys and a DNS target, revalidated before dialing, not a connectivity + * guarantee. * * @return the connectionName value. */ @@ -423,71 +419,48 @@ public String getConnectionName() { } /** - * Get the source property: The caller identity used to originate the call. For a Twilio connection, provide an - * authorized E.164 phone number. For an Azure Communication Services / Teams Phone extensibility connection, - * provide the Teams Resource Account object ID. The identity type is inferred from the connection category; - * originating does not change inbound routing. + * Get the source property: Caller identity: phone_number for Twilio/SIP, or a teams resource-account GUID for + * ACS/Teams Phone extensibility. No sip source URI. * * @return the source value. */ @Generated - public String getSource() { + public TelephonyAddress getSource() { return this.source; } + /* + * Owning Campaign, absent for direct calls. Instance-bound despite name reuse; Campaign deletion hides then removes + * its jobs. + */ + @Generated + private String campaignName; + /** * Creates an instance of TelephonyCallJob class. * * @param destination the destination value to set. * @param connectionName the connectionName value to set. - * @param source the source value to set. - * @param id the id value to set. - * @param agentName the agentName value to set. - * @param status the status value to set. * @param retryPolicy the retryPolicy value to set. - * @param attemptCount the attemptCount value to set. - * @param revision the revision value to set. - * @param createdAt the createdAt value to set. - * @param updatedAt the updatedAt value to set. + * @param source the source value to set. */ @Generated - private TelephonyCallJob(TelephonyOutboundDestination destination, String connectionName, String source, String id, - String agentName, TelephonyCallJobStatus status, TelephonyOutboundRetryPolicy retryPolicy, int attemptCount, - long revision, OffsetDateTime createdAt, OffsetDateTime updatedAt) { + private TelephonyCallJob(TelephonyAddress destination, String connectionName, + TelephonyOutboundRetryPolicy retryPolicy, TelephonyAddress source) { this.destination = destination; this.connectionName = connectionName; - this.source = source; - this.id = id; - this.agentName = agentName; - this.status = status; this.retryPolicy = retryPolicy; - this.attemptCount = attemptCount; - this.revision = revision; - if (createdAt == null) { - this.createdAt = 0L; - } else { - this.createdAt = createdAt.toEpochSecond(); - } - if (updatedAt == null) { - this.updatedAt = 0L; - } else { - this.updatedAt = updatedAt.toEpochSecond(); - } + this.source = source; } - /* - * The object type. Always `telephony.call_job`. - */ - @Generated - private final String objectType = "telephony.call_job"; - /** - * Get the objectType property: The object type. Always `telephony.call_job`. + * Get the campaignName property: Owning Campaign, absent for direct calls. Instance-bound despite name reuse; + * Campaign deletion hides then removes its jobs. * - * @return the objectType value. + * @return the campaignName value. */ @Generated - public String getObjectType() { - return this.objectType; + public String getCampaignName() { + return this.campaignName; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyCallJobInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJobCreate.java similarity index 53% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyCallJobInput.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJobCreate.java index 7b0c58be7f0e5..5e50ef6d9608a 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/CreateTelephonyCallJobInput.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCallJobCreate.java @@ -3,6 +3,7 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.StructuredInputJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; @@ -15,34 +16,25 @@ import java.util.Map; /** - * A request to create one durable direct outbound call job. + * The direct outbound call to create. */ @Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class CreateTelephonyCallJobInput implements JsonSerializable { +public final class TelephonyCallJobCreate implements JsonSerializable { /* * The phone destination to call. */ @Generated - private final TelephonyOutboundDestination destination; + private final TelephonyAddress destination; /* - * The Foundry connection name in the current project used to originate the call. Its category selects Twilio or - * Azure Communication Services / Teams Phone extensibility. No inbound telephony binding is required. + * Same-project Twilio, ACS/Teams Phone extensibility or SipOutbound connection; no inbound binding needed. SIP + * requires CustomKeys and a DNS target, revalidated before dialing, not a connectivity guarantee. */ @Generated private final String connectionName; - /* - * The caller identity used to originate the call. For a Twilio connection, provide an authorized E.164 phone - * number. For an Azure Communication Services / Teams Phone extensibility connection, provide the Teams Resource - * Account object ID. The identity type is inferred from the connection category; originating does not change - * inbound routing. - */ - @Generated - private final String source; - /* * An optional customer-declared purpose for placing the call. */ @@ -50,9 +42,7 @@ public final class CreateTelephonyCallJobInput implements JsonSerializable structuredInputs; @@ -64,20 +54,28 @@ public final class CreateTelephonyCallJobInput implements JsonSerializable getStructuredInputs() { } /** - * Set the structuredInputs property: 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. + * Set the structuredInputs property: Agent/greeting inputs, including nested JSON and null. Agent schemas, required + * fields and defaults apply. * * @param structuredInputs the structuredInputs value to set. - * @return the CreateTelephonyCallJobInput object itself. + * @return the TelephonyCallJobCreate object itself. */ @Generated - public CreateTelephonyCallJobInput setStructuredInputs(Map structuredInputs) { + public TelephonyCallJobCreate setStructuredInputs(Map structuredInputs) { this.structuredInputs = structuredInputs; return this; } @@ -182,16 +163,17 @@ public TelephonyCallJobSchedule getSchedule() { * Set the schedule property: The optional execution window. * * @param schedule the schedule value to set. - * @return the CreateTelephonyCallJobInput object itself. + * @return the TelephonyCallJobCreate object itself. */ @Generated - public CreateTelephonyCallJobInput setSchedule(TelephonyCallJobSchedule schedule) { + public TelephonyCallJobCreate setSchedule(TelephonyCallJobSchedule schedule) { this.schedule = schedule; return this; } /** - * Get the retryPolicy property: The provider-attempt retry policy. Omit it for one attempt with no retry delay. + * Get the retryPolicy property: Frozen retry policy. Omission at creation returns fixed_interval with + * max_attempts=1 and interval=0 seconds: one initial attempt, no retry. * * @return the retryPolicy value. */ @@ -201,17 +183,29 @@ public TelephonyOutboundRetryPolicy getRetryPolicy() { } /** - * Set the retryPolicy property: The provider-attempt retry policy. Omit it for one attempt with no retry delay. + * Set the retryPolicy property: Frozen retry policy. Omission at creation returns fixed_interval with + * max_attempts=1 and interval=0 seconds: one initial attempt, no retry. * * @param retryPolicy the retryPolicy value to set. - * @return the CreateTelephonyCallJobInput object itself. + * @return the TelephonyCallJobCreate object itself. */ @Generated - public CreateTelephonyCallJobInput setRetryPolicy(TelephonyOutboundRetryPolicy retryPolicy) { + public TelephonyCallJobCreate setRetryPolicy(TelephonyOutboundRetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; return this; } + /** + * Get the source property: Caller identity: phone_number for Twilio/SIP, or a teams resource-account GUID for + * ACS/Teams Phone extensibility. No sip source URI. + * + * @return the source value. + */ + @Generated + public TelephonyAddress getSource() { + return this.source; + } + /** * {@inheritDoc} */ @@ -221,7 +215,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeJsonField("destination", this.destination); jsonWriter.writeStringField("connection_name", this.connectionName); - jsonWriter.writeStringField("source", this.source); + jsonWriter.writeJsonField("source", this.source); jsonWriter.writeStringField("purpose", this.purpose); jsonWriter.writeMapField("structured_inputs", this.structuredInputs, (writer, element) -> { if (element == null) { @@ -236,20 +230,20 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } /** - * Reads an instance of CreateTelephonyCallJobInput from the JsonReader. + * Reads an instance of TelephonyCallJobCreate from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of CreateTelephonyCallJobInput if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. + * @return An instance of TelephonyCallJobCreate if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the CreateTelephonyCallJobInput. + * @throws IOException If an error occurs while reading the TelephonyCallJobCreate. */ - @Generated - public static CreateTelephonyCallJobInput fromJson(JsonReader jsonReader) throws IOException { + public static TelephonyCallJobCreate fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: Preserve structured input JSON without numeric coercion. return jsonReader.readObject(reader -> { - TelephonyOutboundDestination destination = null; + TelephonyAddress destination = null; String connectionName = null; - String source = null; + TelephonyAddress source = null; String purpose = null; Map structuredInputs = null; TelephonyCallJobSchedule schedule = null; @@ -258,16 +252,16 @@ public static CreateTelephonyCallJobInput fromJson(JsonReader jsonReader) throws String fieldName = reader.getFieldName(); reader.nextToken(); if ("destination".equals(fieldName)) { - destination = TelephonyOutboundDestination.fromJson(reader); + destination = TelephonyAddress.fromJson(reader); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); } else if ("source".equals(fieldName)) { - source = reader.getString(); + source = TelephonyAddress.fromJson(reader); } else if ("purpose".equals(fieldName)) { purpose = reader.getString(); } else if ("structured_inputs".equals(fieldName)) { - structuredInputs = reader.readMap(reader1 -> reader1 - .getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped()))); + structuredInputs + = reader.readMap(reader1 -> reader1.getNullable(StructuredInputJsonHelper::readJsonValue)); } else if ("schedule".equals(fieldName)) { schedule = TelephonyCallJobSchedule.fromJson(reader); } else if ("retry_policy".equals(fieldName)) { @@ -276,13 +270,13 @@ public static CreateTelephonyCallJobInput fromJson(JsonReader jsonReader) throws reader.skipChildren(); } } - CreateTelephonyCallJobInput deserializedCreateTelephonyCallJobInput - = new CreateTelephonyCallJobInput(destination, connectionName, source); - deserializedCreateTelephonyCallJobInput.purpose = purpose; - deserializedCreateTelephonyCallJobInput.structuredInputs = structuredInputs; - deserializedCreateTelephonyCallJobInput.schedule = schedule; - deserializedCreateTelephonyCallJobInput.retryPolicy = retryPolicy; - return deserializedCreateTelephonyCallJobInput; + TelephonyCallJobCreate deserializedTelephonyCallJobCreate + = new TelephonyCallJobCreate(destination, connectionName, source); + deserializedTelephonyCallJobCreate.purpose = purpose; + deserializedTelephonyCallJobCreate.structuredInputs = structuredInputs; + deserializedTelephonyCallJobCreate.schedule = schedule; + deserializedTelephonyCallJobCreate.retryPolicy = retryPolicy; + return deserializedTelephonyCallJobCreate; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaign.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaign.java new file mode 100644 index 0000000000000..6a4cff930d34d --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaign.java @@ -0,0 +1,469 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.List; + +/** + * Agent-owned outbound call Campaign. Creation/replacement authorizes execution after successful preparation. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaign implements JsonSerializable { + + /* + * Human-readable name of the provider connection in the current project. + */ + @Generated + private final String connectionName; + + /* + * Typed caller address shared with generated CallJobs. The connection validates source support separately from + * recipient support. + */ + @Generated + private final TelephonyAddress source; + + /* + * 1-100 recipients, exclusive with recipient_dataset. The whole UTF-8 request is limited to 1 MiB. Omitted from + * reads; retain the submission for row correlation. + */ + @Generated + private List recipients; + + /* + * Same-project CSV/JSON/JSONL uri_file, exclusive with recipients. Omitted version pins latest per preparation. + * Limits: 1-1,000,000 rows, 256 MiB decoded/file, 1 MiB/row. + */ + @Generated + private DatasetReference recipientDataset; + + /* + * Dispatch schedule; omission equals ImmediateSchedule. Every mode waits for successful preparation, then follows + * its schedule and available capacity. + */ + @Generated + private TelephonyCampaignSchedule schedule; + + /* + * Per-recipient retries. Omit for one attempt; generated CallJobs return fixed_interval with max_attempts=1 and + * interval=0 seconds. + */ + @Generated + private TelephonyOutboundRetryPolicy retryPolicy; + + /* + * Business execution state. Each asynchronous action has its own retained operation monitor. + */ + @Generated + private TelephonyCampaignStatus status; + + /* + * Preparation/control failure, cleared on retry. Never includes secrets or raw recipient values. + */ + @Generated + private ApiError error; + + /* + * Immutable name supplied as campaign_name in the PUT path, not the request body; echoed in responses. Unique + * within the project and Agent. + */ + @Generated + private String name; + + /* + * Creation time. + */ + @Generated + private long createdAt; + + /* + * Last observable progress update. + */ + @Generated + private long updatedAt; + + /* + * Latest accepted action, for discovery only. Poll the initiating response's Operation-Id/Operation-Location + * instead. + */ + @Generated + private String operationId; + + /* + * Time of terminal completion for the current round; cleared when failed preparation is replaced. + */ + @Generated + private Long finishedAt; + + /* + * Latest Agent version pinned once per preparation and shared by retries/calls. Omitted until resolved; replacement + * clears it. Unavailable pins fail without fallback. + */ + @Generated + private String lockedAgentVersion; + + /* + * Available partial accounting even when the job fails or is cancelled. + */ + @Generated + private TelephonyCampaignProgress progress; + + /** + * Creates an instance of TelephonyCampaign class. + * + * @param connectionName the connectionName value to set. + * @param source the source value to set. + */ + @Generated + public TelephonyCampaign(String connectionName, TelephonyAddress source) { + this.connectionName = connectionName; + this.source = source; + } + + /** + * Get the connectionName property: Human-readable name of the provider connection in the current project. + * + * @return the connectionName value. + */ + @Generated + public String getConnectionName() { + return this.connectionName; + } + + /** + * Get the source property: Typed caller address shared with generated CallJobs. The connection validates source + * support separately from recipient support. + * + * @return the source value. + */ + @Generated + public TelephonyAddress getSource() { + return this.source; + } + + /** + * Get the recipients property: 1-100 recipients, exclusive with recipient_dataset. The whole UTF-8 request is + * limited to 1 MiB. Omitted from reads; retain the submission for row correlation. + * + * @return the recipients value. + */ + @Generated + public List getRecipients() { + return this.recipients; + } + + /** + * Set the recipients property: 1-100 recipients, exclusive with recipient_dataset. The whole UTF-8 request is + * limited to 1 MiB. Omitted from reads; retain the submission for row correlation. + * + * @param recipients the recipients value to set. + * @return the TelephonyCampaign object itself. + */ + @Generated + public TelephonyCampaign setRecipients(List recipients) { + this.recipients = recipients; + return this; + } + + /** + * Get the recipientDataset property: Same-project CSV/JSON/JSONL uri_file, exclusive with recipients. Omitted + * version pins latest per preparation. Limits: 1-1,000,000 rows, 256 MiB decoded/file, 1 MiB/row. + * + * @return the recipientDataset value. + */ + @Generated + public DatasetReference getRecipientDataset() { + return this.recipientDataset; + } + + /** + * Set the recipientDataset property: Same-project CSV/JSON/JSONL uri_file, exclusive with recipients. Omitted + * version pins latest per preparation. Limits: 1-1,000,000 rows, 256 MiB decoded/file, 1 MiB/row. + * + * @param recipientDataset the recipientDataset value to set. + * @return the TelephonyCampaign object itself. + */ + @Generated + public TelephonyCampaign setRecipientDataset(DatasetReference recipientDataset) { + this.recipientDataset = recipientDataset; + return this; + } + + /** + * Get the schedule property: Dispatch schedule; omission equals ImmediateSchedule. Every mode waits for successful + * preparation, then follows its schedule and available capacity. + * + * @return the schedule value. + */ + @Generated + public TelephonyCampaignSchedule getSchedule() { + return this.schedule; + } + + /** + * Set the schedule property: Dispatch schedule; omission equals ImmediateSchedule. Every mode waits for successful + * preparation, then follows its schedule and available capacity. + * + * @param schedule the schedule value to set. + * @return the TelephonyCampaign object itself. + */ + @Generated + public TelephonyCampaign setSchedule(TelephonyCampaignSchedule schedule) { + this.schedule = schedule; + return this; + } + + /** + * Get the retryPolicy property: Per-recipient retries. Omit for one attempt; generated CallJobs return + * fixed_interval with max_attempts=1 and interval=0 seconds. + * + * @return the retryPolicy value. + */ + @Generated + public TelephonyOutboundRetryPolicy getRetryPolicy() { + return this.retryPolicy; + } + + /** + * Set the retryPolicy property: Per-recipient retries. Omit for one attempt; generated CallJobs return + * fixed_interval with max_attempts=1 and interval=0 seconds. + * + * @param retryPolicy the retryPolicy value to set. + * @return the TelephonyCampaign object itself. + */ + @Generated + public TelephonyCampaign setRetryPolicy(TelephonyOutboundRetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + return this; + } + + /** + * Get the status property: Business execution state. Each asynchronous action has its own retained operation + * monitor. + * + * @return the status value. + */ + @Generated + public TelephonyCampaignStatus getStatus() { + return this.status; + } + + /** + * Get the error property: Preparation/control failure, cleared on retry. Never includes secrets or raw recipient + * values. + * + * @return the error value. + */ + @Generated + public ApiError getError() { + return this.error; + } + + /** + * Get the name property: Immutable name supplied as campaign_name in the PUT path, not the request body; echoed in + * responses. Unique within the project and Agent. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + + /** + * Get the createdAt property: Creation time. + * + * @return the createdAt value. + */ + @Generated + public OffsetDateTime getCreatedAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.createdAt), ZoneOffset.UTC); + } + + /** + * Get the updatedAt property: Last observable progress update. + * + * @return the updatedAt value. + */ + @Generated + public OffsetDateTime getUpdatedAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.updatedAt), ZoneOffset.UTC); + } + + /** + * Get the operationId property: Latest accepted action, for discovery only. Poll the initiating response's + * Operation-Id/Operation-Location instead. + * + * @return the operationId value. + */ + @Generated + public String getOperationId() { + return this.operationId; + } + + /** + * Get the finishedAt property: Time of terminal completion for the current round; cleared when failed preparation + * is replaced. + * + * @return the finishedAt value. + */ + @Generated + public OffsetDateTime getFinishedAt() { + if (this.finishedAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.finishedAt), ZoneOffset.UTC); + } + + /** + * Get the lockedAgentVersion property: Latest Agent version pinned once per preparation and shared by + * retries/calls. Omitted until resolved; replacement clears it. Unavailable pins fail without fallback. + * + * @return the lockedAgentVersion value. + */ + @Generated + public String getLockedAgentVersion() { + return this.lockedAgentVersion; + } + + /** + * Get the progress property: Available partial accounting even when the job fails or is cancelled. + * + * @return the progress value. + */ + @Generated + public TelephonyCampaignProgress getProgress() { + return this.progress; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("connection_name", this.connectionName); + jsonWriter.writeJsonField("source", this.source); + jsonWriter.writeArrayField("recipients", this.recipients, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeJsonField("recipient_dataset", this.recipientDataset); + jsonWriter.writeJsonField("schedule", this.schedule); + jsonWriter.writeJsonField("retry_policy", this.retryPolicy); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaign from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaign if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyCampaign. + */ + @Generated + public static TelephonyCampaign fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String connectionName = null; + TelephonyAddress source = null; + TelephonyCampaignStatus status = null; + String name = null; + long createdAt = 0L; + long updatedAt = 0L; + String eTag = null; + String operationId = null; + TelephonyCampaignProgress progress = null; + List recipients = null; + DatasetReference recipientDataset = null; + TelephonyCampaignSchedule schedule = null; + TelephonyOutboundRetryPolicy retryPolicy = null; + ApiError error = null; + Long finishedAt = null; + String lockedAgentVersion = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("connection_name".equals(fieldName)) { + connectionName = reader.getString(); + } else if ("source".equals(fieldName)) { + source = TelephonyAddress.fromJson(reader); + } else if ("status".equals(fieldName)) { + status = TelephonyCampaignStatus.fromString(reader.getString()); + } else if ("name".equals(fieldName)) { + name = reader.getString(); + } else if ("created_at".equals(fieldName)) { + createdAt = reader.getLong(); + } else if ("updated_at".equals(fieldName)) { + updatedAt = reader.getLong(); + } else if ("etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("operation_id".equals(fieldName)) { + operationId = reader.getString(); + } else if ("progress".equals(fieldName)) { + progress = TelephonyCampaignProgress.fromJson(reader); + } else if ("recipients".equals(fieldName)) { + recipients = reader.readArray(reader1 -> TelephonyRecipient.fromJson(reader1)); + } else if ("recipient_dataset".equals(fieldName)) { + recipientDataset = DatasetReference.fromJson(reader); + } else if ("schedule".equals(fieldName)) { + schedule = TelephonyCampaignSchedule.fromJson(reader); + } else if ("retry_policy".equals(fieldName)) { + retryPolicy = TelephonyOutboundRetryPolicy.fromJson(reader); + } else if ("error".equals(fieldName)) { + error = ApiError.fromJson(reader); + } else if ("finished_at".equals(fieldName)) { + finishedAt = reader.getNullable(JsonReader::getLong); + } else if ("locked_agent_version".equals(fieldName)) { + lockedAgentVersion = reader.getString(); + } else { + reader.skipChildren(); + } + } + TelephonyCampaign deserializedTelephonyCampaign = new TelephonyCampaign(connectionName, source); + deserializedTelephonyCampaign.status = status; + deserializedTelephonyCampaign.name = name; + deserializedTelephonyCampaign.createdAt = createdAt; + deserializedTelephonyCampaign.updatedAt = updatedAt; + deserializedTelephonyCampaign.eTag = eTag; + deserializedTelephonyCampaign.operationId = operationId; + deserializedTelephonyCampaign.progress = progress; + deserializedTelephonyCampaign.recipients = recipients; + deserializedTelephonyCampaign.recipientDataset = recipientDataset; + deserializedTelephonyCampaign.schedule = schedule; + deserializedTelephonyCampaign.retryPolicy = retryPolicy; + deserializedTelephonyCampaign.error = error; + deserializedTelephonyCampaign.finishedAt = finishedAt; + deserializedTelephonyCampaign.lockedAgentVersion = lockedAgentVersion; + return deserializedTelephonyCampaign; + }); + } + + /* + * Conditional-action token, not a cache validator. Changes with control state, not progress. + */ + @Generated + private String eTag; + + /** + * Get the eTag property: Conditional-action token, not a cache validator. Changes with control state, not progress. + * + * @return the eTag value. + */ + @Generated + public String getETag() { + return this.eTag; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignAtTimeSchedule.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignAtTimeSchedule.java new file mode 100644 index 0000000000000..f733c3424bf6d --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignAtTimeSchedule.java @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Uses one earliest dispatch time for all recipients. Past times are allowed; preparation must still succeed. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignAtTimeSchedule extends TelephonyCampaignSchedule { + + /* + * How each recipient's earliest dispatch time is determined. + */ + @Generated + private TelephonyCampaignScheduleType type = TelephonyCampaignScheduleType.SCHEDULED; + + /* + * Common earliest dispatch time; successful preparation is required. + */ + @Generated + private final long scheduledAt; + + /** + * Creates an instance of TelephonyCampaignAtTimeSchedule class. + * + * @param scheduledAt the scheduledAt value to set. + */ + @Generated + public TelephonyCampaignAtTimeSchedule(OffsetDateTime scheduledAt) { + if (scheduledAt == null) { + this.scheduledAt = 0L; + } else { + this.scheduledAt = scheduledAt.toEpochSecond(); + } + } + + /** + * Get the type property: How each recipient's earliest dispatch time is determined. + * + * @return the type value. + */ + @Generated + @Override + public TelephonyCampaignScheduleType getType() { + return this.type; + } + + /** + * Get the scheduledAt property: Common earliest dispatch time; successful preparation is required. + * + * @return the scheduledAt value. + */ + @Generated + public OffsetDateTime getScheduledAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.scheduledAt), ZoneOffset.UTC); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public TelephonyCampaignAtTimeSchedule setExpiresAt(OffsetDateTime expiresAt) { + super.setExpiresAt(expiresAt); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + if (getExpiresAt() != null) { + jsonWriter.writeNumberField("expires_at", getExpiresAt().toEpochSecond()); + } + jsonWriter.writeLongField("scheduled_at", this.scheduledAt); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignAtTimeSchedule from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignAtTimeSchedule if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyCampaignAtTimeSchedule. + */ + @Generated + public static TelephonyCampaignAtTimeSchedule fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + OffsetDateTime expiresAt = null; + OffsetDateTime scheduledAt = null; + TelephonyCampaignScheduleType type = TelephonyCampaignScheduleType.SCHEDULED; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("expires_at".equals(fieldName)) { + Long expiresAtHolder = reader.getNullable(JsonReader::getLong); + if (expiresAtHolder != null) { + expiresAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(expiresAtHolder), ZoneOffset.UTC); + } + } else if ("scheduled_at".equals(fieldName)) { + scheduledAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("type".equals(fieldName)) { + type = TelephonyCampaignScheduleType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + TelephonyCampaignAtTimeSchedule deserializedTelephonyCampaignAtTimeSchedule + = new TelephonyCampaignAtTimeSchedule(scheduledAt); + deserializedTelephonyCampaignAtTimeSchedule.setExpiresAt(expiresAt); + deserializedTelephonyCampaignAtTimeSchedule.type = type; + return deserializedTelephonyCampaignAtTimeSchedule; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignImmediateSchedule.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignImmediateSchedule.java new file mode 100644 index 0000000000000..3363fd7497a09 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignImmediateSchedule.java @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Dispatch automatically as soon as preparation succeeds and capacity permits. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignImmediateSchedule extends TelephonyCampaignSchedule { + + /* + * How each recipient's earliest dispatch time is determined. + */ + @Generated + private TelephonyCampaignScheduleType type = TelephonyCampaignScheduleType.IMMEDIATE; + + /** + * Creates an instance of TelephonyCampaignImmediateSchedule class. + */ + @Generated + public TelephonyCampaignImmediateSchedule() { + } + + /** + * Get the type property: How each recipient's earliest dispatch time is determined. + * + * @return the type value. + */ + @Generated + @Override + public TelephonyCampaignScheduleType getType() { + return this.type; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public TelephonyCampaignImmediateSchedule setExpiresAt(OffsetDateTime expiresAt) { + super.setExpiresAt(expiresAt); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + if (getExpiresAt() != null) { + jsonWriter.writeNumberField("expires_at", getExpiresAt().toEpochSecond()); + } + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignImmediateSchedule from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignImmediateSchedule if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the TelephonyCampaignImmediateSchedule. + */ + @Generated + public static TelephonyCampaignImmediateSchedule fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + TelephonyCampaignImmediateSchedule deserializedTelephonyCampaignImmediateSchedule + = new TelephonyCampaignImmediateSchedule(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("expires_at".equals(fieldName)) { + Long expiresAtHolder = reader.getNullable(JsonReader::getLong); + if (expiresAtHolder != null) { + deserializedTelephonyCampaignImmediateSchedule.setExpiresAt( + OffsetDateTime.ofInstant(Instant.ofEpochSecond(expiresAtHolder), ZoneOffset.UTC)); + } + } else if ("type".equals(fieldName)) { + deserializedTelephonyCampaignImmediateSchedule.type + = TelephonyCampaignScheduleType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedTelephonyCampaignImmediateSchedule; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperation.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperation.java new file mode 100644 index 0000000000000..a0b8114fa7bf9 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperation.java @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Preparation/cancel/delete monitor bound to its original Campaign instance/round, independent of later actions. Omits + * result. Retained for the Campaign lifetime and at least 24 hours after both completion and deletion. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignOperation implements JsonSerializable { + + /* + * Server-assigned unique identifier. + */ + @Generated + private String id; + + /* + * Current lifecycle status. + */ + @Generated + private JobStatus status; + + /* + * Error details — populated only on failure. + */ + @Generated + private ApiError error; + + /* + * Work tracked by this monitor. + */ + @Generated + private TelephonyCampaignOperationKind kind; + + /* + * Creation time of this operation. + */ + @Generated + private long createdAt; + + /* + * When preparation, cancellation or deletion finished. + */ + @Generated + private Long finishedAt; + + /** + * Creates an instance of TelephonyCampaignOperation class. + */ + @Generated + private TelephonyCampaignOperation() { + } + + /** + * Get the id property: Server-assigned unique identifier. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the status property: Current lifecycle status. + * + * @return the status value. + */ + @Generated + public JobStatus getStatus() { + return this.status; + } + + /** + * Get the error property: Error details — populated only on failure. + * + * @return the error value. + */ + @Generated + public ApiError getError() { + return this.error; + } + + /** + * Get the kind property: Work tracked by this monitor. + * + * @return the kind value. + */ + @Generated + public TelephonyCampaignOperationKind getKind() { + return this.kind; + } + + /** + * Get the createdAt property: Creation time of this operation. + * + * @return the createdAt value. + */ + @Generated + public OffsetDateTime getCreatedAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.createdAt), ZoneOffset.UTC); + } + + /** + * Get the finishedAt property: When preparation, cancellation or deletion finished. + * + * @return the finishedAt value. + */ + @Generated + public OffsetDateTime getFinishedAt() { + if (this.finishedAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.finishedAt), ZoneOffset.UTC); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignOperation from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignOperation if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyCampaignOperation. + */ + @Generated + public static TelephonyCampaignOperation fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + TelephonyCampaignOperation deserializedTelephonyCampaignOperation = new TelephonyCampaignOperation(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + deserializedTelephonyCampaignOperation.id = reader.getString(); + } else if ("status".equals(fieldName)) { + deserializedTelephonyCampaignOperation.status = JobStatus.fromString(reader.getString()); + } else if ("kind".equals(fieldName)) { + deserializedTelephonyCampaignOperation.kind + = TelephonyCampaignOperationKind.fromString(reader.getString()); + } else if ("created_at".equals(fieldName)) { + deserializedTelephonyCampaignOperation.createdAt = reader.getLong(); + } else if ("error".equals(fieldName)) { + deserializedTelephonyCampaignOperation.error = ApiError.fromJson(reader); + } else if ("finished_at".equals(fieldName)) { + deserializedTelephonyCampaignOperation.finishedAt = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + return deserializedTelephonyCampaignOperation; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperationKind.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperationKind.java new file mode 100644 index 0000000000000..f1ddc349c9b4c --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperationKind.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Kind of asynchronous work associated with a Campaign. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignOperationKind extends ExpandableStringEnum { + + /** + * Input validation and complete CallJob generation for a PUT. + */ + @Generated + public static final TelephonyCampaignOperationKind VALIDATION = fromString("validation"); + + /** + * Stop future dispatch and drain admitted work. + */ + @Generated + public static final TelephonyCampaignOperationKind CANCEL = fromString("cancel"); + + /** + * Cascade cleanup of Campaign task resources. + */ + @Generated + public static final TelephonyCampaignOperationKind DELETE = fromString("delete"); + + /** + * Creates a new instance of TelephonyCampaignOperationKind value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public TelephonyCampaignOperationKind() { + } + + /** + * Creates or finds a TelephonyCampaignOperationKind from its string representation. + * + * @param name a name to look for. + * @return the corresponding TelephonyCampaignOperationKind. + */ + @Generated + public static TelephonyCampaignOperationKind fromString(String name) { + return fromString(name, TelephonyCampaignOperationKind.class); + } + + /** + * Gets known TelephonyCampaignOperationKind values. + * + * @return known TelephonyCampaignOperationKind values. + */ + @Generated + public static Collection values() { + return values(TelephonyCampaignOperationKind.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignPerRecipientSchedule.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignPerRecipientSchedule.java new file mode 100644 index 0000000000000..98d7bb45b28e2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignPerRecipientSchedule.java @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Uses each recipient's scheduled_at: RFC 3339 with timezone in Datasets, Unix seconds for inline recipients. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignPerRecipientSchedule extends TelephonyCampaignSchedule { + + /* + * How each recipient's earliest dispatch time is determined. + */ + @Generated + private TelephonyCampaignScheduleType type = TelephonyCampaignScheduleType.RECIPIENT; + + /** + * Creates an instance of TelephonyCampaignPerRecipientSchedule class. + */ + @Generated + public TelephonyCampaignPerRecipientSchedule() { + } + + /** + * Get the type property: How each recipient's earliest dispatch time is determined. + * + * @return the type value. + */ + @Generated + @Override + public TelephonyCampaignScheduleType getType() { + return this.type; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public TelephonyCampaignPerRecipientSchedule setExpiresAt(OffsetDateTime expiresAt) { + super.setExpiresAt(expiresAt); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + if (getExpiresAt() != null) { + jsonWriter.writeNumberField("expires_at", getExpiresAt().toEpochSecond()); + } + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignPerRecipientSchedule from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignPerRecipientSchedule if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the TelephonyCampaignPerRecipientSchedule. + */ + @Generated + public static TelephonyCampaignPerRecipientSchedule fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + TelephonyCampaignPerRecipientSchedule deserializedTelephonyCampaignPerRecipientSchedule + = new TelephonyCampaignPerRecipientSchedule(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("expires_at".equals(fieldName)) { + Long expiresAtHolder = reader.getNullable(JsonReader::getLong); + if (expiresAtHolder != null) { + deserializedTelephonyCampaignPerRecipientSchedule.setExpiresAt( + OffsetDateTime.ofInstant(Instant.ofEpochSecond(expiresAtHolder), ZoneOffset.UTC)); + } + } else if ("type".equals(fieldName)) { + deserializedTelephonyCampaignPerRecipientSchedule.type + = TelephonyCampaignScheduleType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedTelephonyCampaignPerRecipientSchedule; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignProgress.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignProgress.java new file mode 100644 index 0000000000000..37edcb4169d86 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignProgress.java @@ -0,0 +1,222 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Recipient execution counts, zero until preparation succeeds; then mutually exclusive and summing to total_recipients. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignProgress implements JsonSerializable { + + /* + * Total input rows, including invalid rows. Omitted until known; never an estimate. + */ + @Generated + private Long totalRecipients; + + /* + * Recipients waiting for their schedule, capacity or retry after preparation has completed. + */ + @Generated + private final long pending; + + /* + * Recipients with a durable origination reservation or unresolved provider attempt, including dispatching before a + * call ID is received. + */ + @Generated + private final long active; + + /* + * Recipients whose CallJob completed; not proof of business success. + */ + @Generated + private final long completed; + + /* + * Recipients whose CallJob exhausted retries or failed. + */ + @Generated + private final long failed; + + /* + * Recipients cancelled before completion. Does not include dispatch-window expiry. + */ + @Generated + private final long cancelled; + + /* + * Recipients whose dispatch deadline elapsed before a new attempt could start. + */ + @Generated + private final long expired; + + /** + * Creates an instance of TelephonyCampaignProgress class. + * + * @param pending the pending value to set. + * @param active the active value to set. + * @param completed the completed value to set. + * @param failed the failed value to set. + * @param cancelled the cancelled value to set. + * @param expired the expired value to set. + */ + @Generated + private TelephonyCampaignProgress(long pending, long active, long completed, long failed, long cancelled, + long expired) { + this.pending = pending; + this.active = active; + this.completed = completed; + this.failed = failed; + this.cancelled = cancelled; + this.expired = expired; + } + + /** + * Get the totalRecipients property: Total input rows, including invalid rows. Omitted until known; never an + * estimate. + * + * @return the totalRecipients value. + */ + @Generated + public Long getTotalRecipients() { + return this.totalRecipients; + } + + /** + * Get the pending property: Recipients waiting for their schedule, capacity or retry after preparation has + * completed. + * + * @return the pending value. + */ + @Generated + public long getPending() { + return this.pending; + } + + /** + * Get the active property: Recipients with a durable origination reservation or unresolved provider attempt, + * including dispatching before a call ID is received. + * + * @return the active value. + */ + @Generated + public long getActive() { + return this.active; + } + + /** + * Get the completed property: Recipients whose CallJob completed; not proof of business success. + * + * @return the completed value. + */ + @Generated + public long getCompleted() { + return this.completed; + } + + /** + * Get the failed property: Recipients whose CallJob exhausted retries or failed. + * + * @return the failed value. + */ + @Generated + public long getFailed() { + return this.failed; + } + + /** + * Get the cancelled property: Recipients cancelled before completion. Does not include dispatch-window expiry. + * + * @return the cancelled value. + */ + @Generated + public long getCancelled() { + return this.cancelled; + } + + /** + * Get the expired property: Recipients whose dispatch deadline elapsed before a new attempt could start. + * + * @return the expired value. + */ + @Generated + public long getExpired() { + return this.expired; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeLongField("pending", this.pending); + jsonWriter.writeLongField("active", this.active); + jsonWriter.writeLongField("completed", this.completed); + jsonWriter.writeLongField("failed", this.failed); + jsonWriter.writeLongField("cancelled", this.cancelled); + jsonWriter.writeLongField("expired", this.expired); + jsonWriter.writeNumberField("total_recipients", this.totalRecipients); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignProgress from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignProgress if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyCampaignProgress. + */ + @Generated + public static TelephonyCampaignProgress fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + long pending = 0L; + long active = 0L; + long completed = 0L; + long failed = 0L; + long cancelled = 0L; + long expired = 0L; + Long totalRecipients = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("pending".equals(fieldName)) { + pending = reader.getLong(); + } else if ("active".equals(fieldName)) { + active = reader.getLong(); + } else if ("completed".equals(fieldName)) { + completed = reader.getLong(); + } else if ("failed".equals(fieldName)) { + failed = reader.getLong(); + } else if ("cancelled".equals(fieldName)) { + cancelled = reader.getLong(); + } else if ("expired".equals(fieldName)) { + expired = reader.getLong(); + } else if ("total_recipients".equals(fieldName)) { + totalRecipients = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + TelephonyCampaignProgress deserializedTelephonyCampaignProgress + = new TelephonyCampaignProgress(pending, active, completed, failed, cancelled, expired); + deserializedTelephonyCampaignProgress.totalRecipients = totalRecipients; + return deserializedTelephonyCampaignProgress; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignSchedule.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignSchedule.java new file mode 100644 index 0000000000000..306464bad7a5a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignSchedule.java @@ -0,0 +1,156 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Creation authorizes dialing; every scheduling mode waits for successful preparation. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class TelephonyCampaignSchedule implements JsonSerializable { + + /* + * How each recipient's earliest dispatch time is determined. + */ + @Generated + private TelephonyCampaignScheduleType type = TelephonyCampaignScheduleType.fromString("TelephonyCampaignSchedule"); + + /* + * Exclusive deadline for new attempts, including retries; active calls may finish. Must be later than every + * scheduled_at. + */ + @Generated + private Long expiresAt; + + /** + * Creates an instance of TelephonyCampaignSchedule class. + */ + @Generated + protected TelephonyCampaignSchedule() { + } + + /** + * Get the type property: How each recipient's earliest dispatch time is determined. + * + * @return the type value. + */ + @Generated + public TelephonyCampaignScheduleType getType() { + return this.type; + } + + /** + * Get the expiresAt property: Exclusive deadline for new attempts, including retries; active calls may finish. Must + * be later than every scheduled_at. + * + * @return the expiresAt value. + */ + @Generated + public OffsetDateTime getExpiresAt() { + if (this.expiresAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.expiresAt), ZoneOffset.UTC); + } + + /** + * Set the expiresAt property: Exclusive deadline for new attempts, including retries; active calls may finish. Must + * be later than every scheduled_at. + * + * @param expiresAt the expiresAt value to set. + * @return the TelephonyCampaignSchedule object itself. + */ + @Generated + public TelephonyCampaignSchedule setExpiresAt(OffsetDateTime expiresAt) { + if (expiresAt == null) { + this.expiresAt = null; + } else { + this.expiresAt = expiresAt.toEpochSecond(); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeNumberField("expires_at", this.expiresAt); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignSchedule from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignSchedule if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IOException If an error occurs while reading the TelephonyCampaignSchedule. + */ + @Generated + public static TelephonyCampaignSchedule fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("type".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("immediate".equals(discriminatorValue)) { + return TelephonyCampaignImmediateSchedule.fromJson(readerToUse.reset()); + } else if ("scheduled".equals(discriminatorValue)) { + return TelephonyCampaignAtTimeSchedule.fromJson(readerToUse.reset()); + } else if ("recipient".equals(discriminatorValue)) { + return TelephonyCampaignPerRecipientSchedule.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static TelephonyCampaignSchedule fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + TelephonyCampaignSchedule deserializedTelephonyCampaignSchedule = new TelephonyCampaignSchedule(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("type".equals(fieldName)) { + deserializedTelephonyCampaignSchedule.type + = TelephonyCampaignScheduleType.fromString(reader.getString()); + } else if ("expires_at".equals(fieldName)) { + deserializedTelephonyCampaignSchedule.expiresAt = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + return deserializedTelephonyCampaignSchedule; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignScheduleType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignScheduleType.java new file mode 100644 index 0000000000000..c4b381e4f5492 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignScheduleType.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Mutually exclusive ways to determine each recipient's earliest dispatch time. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignScheduleType extends ExpandableStringEnum { + + /** + * Eligible automatically after successful preparation. + */ + @Generated + public static final TelephonyCampaignScheduleType IMMEDIATE = fromString("immediate"); + + /** + * One common earliest dispatch time. + */ + @Generated + public static final TelephonyCampaignScheduleType SCHEDULED = fromString("scheduled"); + + /** + * A separate earliest dispatch time for each recipient. + */ + @Generated + public static final TelephonyCampaignScheduleType RECIPIENT = fromString("recipient"); + + /** + * Creates a new instance of TelephonyCampaignScheduleType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public TelephonyCampaignScheduleType() { + } + + /** + * Creates or finds a TelephonyCampaignScheduleType from its string representation. + * + * @param name a name to look for. + * @return the corresponding TelephonyCampaignScheduleType. + */ + @Generated + public static TelephonyCampaignScheduleType fromString(String name) { + return fromString(name, TelephonyCampaignScheduleType.class); + } + + /** + * Gets known TelephonyCampaignScheduleType values. + * + * @return known TelephonyCampaignScheduleType values. + */ + @Generated + public static Collection values() { + return values(TelephonyCampaignScheduleType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignStatus.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignStatus.java new file mode 100644 index 0000000000000..2486e7d0c2f4a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignStatus.java @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Campaign execution state, separate from preparation/cancel/delete LROs. All recipients terminal means completed, not + * necessarily successful. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignStatus extends ExpandableStringEnum { + + /** + * Validating recipients and generating CallJobs; no dialing until preparation succeeds. + */ + @Generated + public static final TelephonyCampaignStatus VALIDATING = fromString("validating"); + + /** + * Preparation complete; jobs execute subject to schedule, capacity and retries. + */ + @Generated + public static final TelephonyCampaignStatus RUNNING = fromString("running"); + + /** + * New dispatch stopped while admitted work drains; connected calls finish naturally. Cancellation failure leaves + * dispatch stopped. + */ + @Generated + public static final TelephonyCampaignStatus CANCELLING = fromString("cancelling"); + + /** + * All recipients terminal, including failed/expired jobs. Deletion waits for admitted work to stop. + */ + @Generated + public static final TelephonyCampaignStatus COMPLETED = fromString("completed"); + + /** + * Preparation failed without dialing and workers have stopped. Allows deletion or full replacement. + */ + @Generated + public static final TelephonyCampaignStatus FAILED = fromString("failed"); + + /** + * Cancellation complete. Can be deleted; unfinished work cannot restart. + */ + @Generated + public static final TelephonyCampaignStatus CANCELLED = fromString("cancelled"); + + /** + * Cleanup in progress; dialing and name reuse stay blocked until success, including after cleanup failure. + */ + @Generated + public static final TelephonyCampaignStatus DELETING = fromString("deleting"); + + /** + * Creates a new instance of TelephonyCampaignStatus value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public TelephonyCampaignStatus() { + } + + /** + * Creates or finds a TelephonyCampaignStatus from its string representation. + * + * @param name a name to look for. + * @return the corresponding TelephonyCampaignStatus. + */ + @Generated + public static TelephonyCampaignStatus fromString(String name) { + return fromString(name, TelephonyCampaignStatus.class); + } + + /** + * Gets known TelephonyCampaignStatus values. + * + * @return known TelephonyCampaignStatus values. + */ + @Generated + public static Collection values() { + return values(TelephonyCampaignStatus.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignValidationError.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignValidationError.java new file mode 100644 index 0000000000000..4863569468e1a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyCampaignValidationError.java @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Invalid-row diagnostic for current preparation; execution errors are in CallJobs. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyCampaignValidationError implements JsonSerializable { + + /* + * One-based source row or inline item position. + */ + @Generated + private final long rowNumber; + + /* + * Row validation error; param identifies the field. Never includes raw values or secrets. + */ + @Generated + private final ApiError error; + + /** + * Creates an instance of TelephonyCampaignValidationError class. + * + * @param rowNumber the rowNumber value to set. + * @param error the error value to set. + */ + @Generated + private TelephonyCampaignValidationError(long rowNumber, ApiError error) { + this.rowNumber = rowNumber; + this.error = error; + } + + /** + * Get the rowNumber property: One-based source row or inline item position. + * + * @return the rowNumber value. + */ + @Generated + public long getRowNumber() { + return this.rowNumber; + } + + /** + * Get the error property: Row validation error; param identifies the field. Never includes raw values or secrets. + * + * @return the error value. + */ + @Generated + public ApiError getError() { + return this.error; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeLongField("row_number", this.rowNumber); + jsonWriter.writeJsonField("error", this.error); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyCampaignValidationError from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyCampaignValidationError if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyCampaignValidationError. + */ + @Generated + public static TelephonyCampaignValidationError fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + long rowNumber = 0L; + ApiError error = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("row_number".equals(fieldName)) { + rowNumber = reader.getLong(); + } else if ("error".equals(fieldName)) { + error = ApiError.fromJson(reader); + } else { + reader.skipChildren(); + } + } + return new TelephonyCampaignValidationError(rowNumber, error); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundFixedIntervalRetryPolicy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyFixedIntervalRetryPolicy.java similarity index 67% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundFixedIntervalRetryPolicy.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyFixedIntervalRetryPolicy.java index 5b5ff55b8d3ea..78c841193a494 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundFixedIntervalRetryPolicy.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyFixedIntervalRetryPolicy.java @@ -13,11 +13,12 @@ import java.time.Duration; /** - * The frozen fixed-interval retry policy returned for an outbound call or campaign. + * Shared direct-call/Campaign retry policy. Omission means one attempt; CallJobs return max_attempts=1 and interval=0 + * seconds. */ @Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TelephonyOutboundFixedIntervalRetryPolicy extends TelephonyOutboundRetryPolicy { +public final class TelephonyFixedIntervalRetryPolicy extends TelephonyOutboundRetryPolicy { /* * The retry strategy. Only fixed-interval retries are currently supported. @@ -26,11 +27,26 @@ public final class TelephonyOutboundFixedIntervalRetryPolicy extends TelephonyOu private TelephonyOutboundRetryPolicyType type = TelephonyOutboundRetryPolicyType.FIXED_INTERVAL; /* - * The fixed delay in seconds between attempts. + * The nonnegative delay between attempts, from 0 to 2147483647 seconds. Zero permits an immediate retry, subject to + * scheduling and capacity. */ @Generated private final long interval; + /** + * Creates an instance of TelephonyFixedIntervalRetryPolicy class. + * + * @param interval the interval value to set. + */ + @Generated + public TelephonyFixedIntervalRetryPolicy(Duration interval) { + if (interval == null) { + this.interval = 0L; + } else { + this.interval = interval.getSeconds(); + } + } + /** * Get the type property: The retry strategy. Only fixed-interval retries are currently supported. * @@ -43,7 +59,8 @@ public TelephonyOutboundRetryPolicyType getType() { } /** - * Get the interval property: The fixed delay in seconds between attempts. + * Get the interval property: The nonnegative delay between attempts, from 0 to 2147483647 seconds. Zero permits an + * immediate retry, subject to scheduling and capacity. * * @return the interval value. */ @@ -57,7 +74,7 @@ public Duration getInterval() { */ @Generated @Override - public TelephonyOutboundFixedIntervalRetryPolicy setMaxAttempts(Integer maxAttempts) { + public TelephonyFixedIntervalRetryPolicy setMaxAttempts(Integer maxAttempts) { super.setMaxAttempts(maxAttempts); return this; } @@ -76,16 +93,16 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } /** - * Reads an instance of TelephonyOutboundFixedIntervalRetryPolicy from the JsonReader. + * Reads an instance of TelephonyFixedIntervalRetryPolicy from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of TelephonyOutboundFixedIntervalRetryPolicy if the JsonReader was pointing to an instance of - * it, or null if it was pointing to JSON null. + * @return An instance of TelephonyFixedIntervalRetryPolicy if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TelephonyOutboundFixedIntervalRetryPolicy. + * @throws IOException If an error occurs while reading the TelephonyFixedIntervalRetryPolicy. */ @Generated - public static TelephonyOutboundFixedIntervalRetryPolicy fromJson(JsonReader jsonReader) throws IOException { + public static TelephonyFixedIntervalRetryPolicy fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { Integer maxAttempts = null; Duration interval = null; @@ -103,25 +120,11 @@ public static TelephonyOutboundFixedIntervalRetryPolicy fromJson(JsonReader json reader.skipChildren(); } } - TelephonyOutboundFixedIntervalRetryPolicy deserializedTelephonyOutboundFixedIntervalRetryPolicy - = new TelephonyOutboundFixedIntervalRetryPolicy(interval); - deserializedTelephonyOutboundFixedIntervalRetryPolicy.setMaxAttempts(maxAttempts); - deserializedTelephonyOutboundFixedIntervalRetryPolicy.type = type; - return deserializedTelephonyOutboundFixedIntervalRetryPolicy; + TelephonyFixedIntervalRetryPolicy deserializedTelephonyFixedIntervalRetryPolicy + = new TelephonyFixedIntervalRetryPolicy(interval); + deserializedTelephonyFixedIntervalRetryPolicy.setMaxAttempts(maxAttempts); + deserializedTelephonyFixedIntervalRetryPolicy.type = type; + return deserializedTelephonyFixedIntervalRetryPolicy; }); } - - /** - * Creates an instance of TelephonyOutboundFixedIntervalRetryPolicy class. - * - * @param interval the interval value to set. - */ - @Generated - public TelephonyOutboundFixedIntervalRetryPolicy(Duration interval) { - if (interval == null) { - this.interval = 0L; - } else { - this.interval = interval.getSeconds(); - } - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestinationType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestinationType.java deleted file mode 100644 index da9a0c716bac0..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestinationType.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * The type of destination for an outbound call. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TelephonyOutboundDestinationType extends ExpandableStringEnum { - - /** - * An E.164 phone number. - */ - @Generated - public static final TelephonyOutboundDestinationType PHONE_NUMBER = fromString("phone_number"); - - /** - * Creates a new instance of TelephonyOutboundDestinationType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public TelephonyOutboundDestinationType() { - } - - /** - * Creates or finds a TelephonyOutboundDestinationType from its string representation. - * - * @param name a name to look for. - * @return the corresponding TelephonyOutboundDestinationType. - */ - @Generated - public static TelephonyOutboundDestinationType fromString(String name) { - return fromString(name, TelephonyOutboundDestinationType.class); - } - - /** - * Gets known TelephonyOutboundDestinationType values. - * - * @return known TelephonyOutboundDestinationType values. - */ - @Generated - public static Collection values() { - return values(TelephonyOutboundDestinationType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java index fe6c3f8854de4..0a50e5f460332 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java @@ -113,7 +113,7 @@ public static TelephonyOutboundRetryPolicy fromJson(JsonReader jsonReader) throw } // Use the discriminator value to determine which subtype should be deserialized. if ("fixed_interval".equals(discriminatorValue)) { - return TelephonyOutboundFixedIntervalRetryPolicy.fromJson(readerToUse.reset()); + return TelephonyFixedIntervalRetryPolicy.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/PstnTelephonyTransferDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyPhoneNumber.java similarity index 53% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/PstnTelephonyTransferDestination.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyPhoneNumber.java index 6deef6b33e71f..cd6e928b7e6fe 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/PstnTelephonyTransferDestination.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyPhoneNumber.java @@ -12,37 +12,54 @@ import java.io.IOException; /** - * A PSTN destination for a telephony transfer target. + * Phone-number address used by supported source and destination roles. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class PstnTelephonyTransferDestination extends TelephonyTransferDestination { +public final class TelephonyPhoneNumber extends TelephonyAddress { /* - * The telephony transfer destination type. + * Endpoint address type. */ @Generated - private TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.PSTN; + private TelephonyAddressType type = TelephonyAddressType.PHONE_NUMBER; + + /* + * E.164 phone number. + */ + @Generated + private final String value; /** - * Creates an instance of PstnTelephonyTransferDestination class. + * Creates an instance of TelephonyPhoneNumber class. * * @param value the value value to set. */ @Generated - public PstnTelephonyTransferDestination(String value) { + public TelephonyPhoneNumber(String value) { + super(value); this.value = value; } /** - * Get the kind property: The telephony transfer destination type. + * Get the type property: Endpoint address type. * - * @return the kind value. + * @return the type value. */ @Generated @Override - public TelephonyTransferDestinationKind getKind() { - return this.kind; + public TelephonyAddressType getType() { + return this.type; + } + + /** + * Get the value property: E.164 phone number. + * + * @return the value value. + */ + @Generated + public String getValue() { + return this.value; } /** @@ -53,55 +70,38 @@ public TelephonyTransferDestinationKind getKind() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("value", this.value); - jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } /** - * Reads an instance of PstnTelephonyTransferDestination from the JsonReader. + * Reads an instance of TelephonyPhoneNumber from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of PstnTelephonyTransferDestination if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. + * @return An instance of TelephonyPhoneNumber if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the PstnTelephonyTransferDestination. + * @throws IOException If an error occurs while reading the TelephonyPhoneNumber. */ @Generated - public static PstnTelephonyTransferDestination fromJson(JsonReader jsonReader) throws IOException { + public static TelephonyPhoneNumber fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String value = null; - TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.PSTN; + TelephonyAddressType type = TelephonyAddressType.PHONE_NUMBER; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("value".equals(fieldName)) { value = reader.getString(); - } else if ("kind".equals(fieldName)) { - kind = TelephonyTransferDestinationKind.fromString(reader.getString()); + } else if ("type".equals(fieldName)) { + type = TelephonyAddressType.fromString(reader.getString()); } else { reader.skipChildren(); } } - PstnTelephonyTransferDestination deserializedPstnTelephonyTransferDestination - = new PstnTelephonyTransferDestination(value); - deserializedPstnTelephonyTransferDestination.kind = kind; - return deserializedPstnTelephonyTransferDestination; + TelephonyPhoneNumber deserializedTelephonyPhoneNumber = new TelephonyPhoneNumber(value); + deserializedTelephonyPhoneNumber.type = type; + return deserializedTelephonyPhoneNumber; }); } - - /* - * The E.164 phone number to call. - */ - @Generated - private final String value; - - /** - * Get the value property: The E.164 phone number to call. - * - * @return the value value. - */ - @Generated - public String getValue() { - return this.value; - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyProvider.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyProvider.java index 186b65b4613cd..11f991092c76e 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyProvider.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyProvider.java @@ -57,4 +57,10 @@ public static Collection values() { */ @Generated public static final TelephonyProvider TEAMS_PHONE_EXTENSIBILITY = fromString("teams_phone_extensibility"); + + /** + * Session Initiation Protocol. + */ + @Generated + public static final TelephonyProvider SIP = fromString("sip"); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyRecipient.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyRecipient.java new file mode 100644 index 0000000000000..c9a65b26d8225 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyRecipient.java @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.StructuredInputJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.Map; + +/** + * One recipient in an inline campaign input. Each input position is a separate intended call, including repeated + * destinations. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class TelephonyRecipient implements JsonSerializable { + + /* + * Recipient address; currently phone_number only. Unsupported types fail preparation; future variants can reuse + * this field. + */ + @Generated + private final TelephonyAddress destination; + + /* + * Agent inputs with nested JSON/null, unique names and depth at most 16. Agent schemas/defaults apply. Replay + * preserves types, exact numbers, array order and null/omission, but ignores object order; use lossless numeric + * serialization. + */ + @Generated + private Map structuredInputs; + + /* + * Earliest dispatch time for recipient scheduling. Required only when schedule.type is recipient; forbidden for + * other modes. + */ + @Generated + private Long scheduledAt; + + /** + * Creates an instance of TelephonyRecipient class. + * + * @param destination the destination value to set. + */ + @Generated + public TelephonyRecipient(TelephonyAddress destination) { + this.destination = destination; + } + + /** + * Get the destination property: Recipient address; currently phone_number only. Unsupported types fail preparation; + * future variants can reuse this field. + * + * @return the destination value. + */ + @Generated + public TelephonyAddress getDestination() { + return this.destination; + } + + /** + * Get the structuredInputs property: Agent inputs with nested JSON/null, unique names and depth at most 16. Agent + * schemas/defaults apply. Replay preserves types, exact numbers, array order and null/omission, but ignores object + * order; use lossless numeric serialization. + * + * @return the structuredInputs value. + */ + @Generated + public Map getStructuredInputs() { + return this.structuredInputs; + } + + /** + * Set the structuredInputs property: Agent inputs with nested JSON/null, unique names and depth at most 16. Agent + * schemas/defaults apply. Replay preserves types, exact numbers, array order and null/omission, but ignores object + * order; use lossless numeric serialization. + * + * @param structuredInputs the structuredInputs value to set. + * @return the TelephonyRecipient object itself. + */ + @Generated + public TelephonyRecipient setStructuredInputs(Map structuredInputs) { + this.structuredInputs = structuredInputs; + return this; + } + + /** + * Get the scheduledAt property: Earliest dispatch time for recipient scheduling. Required only when schedule.type + * is recipient; forbidden for other modes. + * + * @return the scheduledAt value. + */ + @Generated + public OffsetDateTime getScheduledAt() { + if (this.scheduledAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.scheduledAt), ZoneOffset.UTC); + } + + /** + * Set the scheduledAt property: Earliest dispatch time for recipient scheduling. Required only when schedule.type + * is recipient; forbidden for other modes. + * + * @param scheduledAt the scheduledAt value to set. + * @return the TelephonyRecipient object itself. + */ + @Generated + public TelephonyRecipient setScheduledAt(OffsetDateTime scheduledAt) { + if (scheduledAt == null) { + this.scheduledAt = null; + } else { + this.scheduledAt = scheduledAt.toEpochSecond(); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeJsonField("destination", this.destination); + jsonWriter.writeMapField("structured_inputs", this.structuredInputs, (writer, element) -> { + if (element == null) { + writer.writeNull(); + } else { + element.writeTo(writer); + } + }); + jsonWriter.writeNumberField("scheduled_at", this.scheduledAt); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of TelephonyRecipient from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of TelephonyRecipient if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the TelephonyRecipient. + */ + public static TelephonyRecipient fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: Preserve structured input JSON without numeric coercion. + return jsonReader.readObject(reader -> { + TelephonyAddress destination = null; + Map structuredInputs = null; + Long scheduledAt = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("destination".equals(fieldName)) { + destination = TelephonyAddress.fromJson(reader); + } else if ("structured_inputs".equals(fieldName)) { + structuredInputs + = reader.readMap(reader1 -> reader1.getNullable(StructuredInputJsonHelper::readJsonValue)); + } else if ("scheduled_at".equals(fieldName)) { + scheduledAt = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + TelephonyRecipient deserializedTelephonyRecipient = new TelephonyRecipient(destination); + deserializedTelephonyRecipient.structuredInputs = structuredInputs; + deserializedTelephonyRecipient.scheduledAt = scheduledAt; + return deserializedTelephonyRecipient; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyTransferDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonySipAddress.java similarity index 56% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyTransferDestination.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonySipAddress.java index 4f581bf31af07..9cb2534620219 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/SipTelephonyTransferDestination.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonySipAddress.java @@ -12,17 +12,18 @@ import java.io.IOException; /** - * A SIP destination for a telephony transfer target. + * SIP/SIPS transfer address, subject to provider validation. SIP outbound sources and recipients use phone_number, not + * SIP URIs. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class SipTelephonyTransferDestination extends TelephonyTransferDestination { +public final class TelephonySipAddress extends TelephonyAddress { /* - * The telephony transfer destination type. + * Endpoint address type. */ @Generated - private TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.SIP; + private TelephonyAddressType type = TelephonyAddressType.SIP; /* * The SIP or SIPS URI to call. @@ -31,24 +32,25 @@ public final class SipTelephonyTransferDestination extends TelephonyTransferDest private final String value; /** - * Creates an instance of SipTelephonyTransferDestination class. + * Creates an instance of TelephonySipAddress class. * * @param value the value value to set. */ @Generated - public SipTelephonyTransferDestination(String value) { + public TelephonySipAddress(String value) { + super(value); this.value = value; } /** - * Get the kind property: The telephony transfer destination type. + * Get the type property: Endpoint address type. * - * @return the kind value. + * @return the type value. */ @Generated @Override - public TelephonyTransferDestinationKind getKind() { - return this.kind; + public TelephonyAddressType getType() { + return this.type; } /** @@ -69,39 +71,38 @@ public String getValue() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("value", this.value); - jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } /** - * Reads an instance of SipTelephonyTransferDestination from the JsonReader. + * Reads an instance of TelephonySipAddress from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of SipTelephonyTransferDestination if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. + * @return An instance of TelephonySipAddress if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the SipTelephonyTransferDestination. + * @throws IOException If an error occurs while reading the TelephonySipAddress. */ @Generated - public static SipTelephonyTransferDestination fromJson(JsonReader jsonReader) throws IOException { + public static TelephonySipAddress fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String value = null; - TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.SIP; + TelephonyAddressType type = TelephonyAddressType.SIP; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("value".equals(fieldName)) { value = reader.getString(); - } else if ("kind".equals(fieldName)) { - kind = TelephonyTransferDestinationKind.fromString(reader.getString()); + } else if ("type".equals(fieldName)) { + type = TelephonyAddressType.fromString(reader.getString()); } else { reader.skipChildren(); } } - SipTelephonyTransferDestination deserializedSipTelephonyTransferDestination - = new SipTelephonyTransferDestination(value); - deserializedSipTelephonyTransferDestination.kind = kind; - return deserializedSipTelephonyTransferDestination; + TelephonySipAddress deserializedTelephonySipAddress = new TelephonySipAddress(value); + deserializedTelephonySipAddress.type = type; + return deserializedTelephonySipAddress; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsTelephonyTransferDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTeamsAddress.java similarity index 52% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsTelephonyTransferDestination.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTeamsAddress.java index 8887b88ac530a..40d022b1b1cba 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TeamsTelephonyTransferDestination.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTeamsAddress.java @@ -12,47 +12,49 @@ import java.io.IOException; /** - * A Microsoft Teams destination for a telephony transfer target. + * Teams source/transfer identity, validated by role and provider. Not supported for outbound recipients. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TeamsTelephonyTransferDestination extends TelephonyTransferDestination { +public final class TelephonyTeamsAddress extends TelephonyAddress { /* - * The telephony transfer destination type. + * Endpoint address type. */ @Generated - private TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.TEAMS; + private TelephonyAddressType type = TelephonyAddressType.TEAMS; /* - * The Microsoft Teams user or resource-account identifier. + * Source: nonempty resource-account GUID. Transfer: user/resource-account GUID or 28:orgid:{guid}. */ @Generated private final String value; /** - * Creates an instance of TeamsTelephonyTransferDestination class. + * Creates an instance of TelephonyTeamsAddress class. * * @param value the value value to set. */ @Generated - public TeamsTelephonyTransferDestination(String value) { + public TelephonyTeamsAddress(String value) { + super(value); this.value = value; } /** - * Get the kind property: The telephony transfer destination type. + * Get the type property: Endpoint address type. * - * @return the kind value. + * @return the type value. */ @Generated @Override - public TelephonyTransferDestinationKind getKind() { - return this.kind; + public TelephonyAddressType getType() { + return this.type; } /** - * Get the value property: The Microsoft Teams user or resource-account identifier. + * Get the value property: Source: nonempty resource-account GUID. Transfer: user/resource-account GUID or + * 28:orgid:{guid}. * * @return the value value. */ @@ -69,39 +71,38 @@ public String getValue() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("value", this.value); - jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } /** - * Reads an instance of TeamsTelephonyTransferDestination from the JsonReader. + * Reads an instance of TelephonyTeamsAddress from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of TeamsTelephonyTransferDestination if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. + * @return An instance of TelephonyTeamsAddress if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TeamsTelephonyTransferDestination. + * @throws IOException If an error occurs while reading the TelephonyTeamsAddress. */ @Generated - public static TeamsTelephonyTransferDestination fromJson(JsonReader jsonReader) throws IOException { + public static TelephonyTeamsAddress fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String value = null; - TelephonyTransferDestinationKind kind = TelephonyTransferDestinationKind.TEAMS; + TelephonyAddressType type = TelephonyAddressType.TEAMS; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("value".equals(fieldName)) { value = reader.getString(); - } else if ("kind".equals(fieldName)) { - kind = TelephonyTransferDestinationKind.fromString(reader.getString()); + } else if ("type".equals(fieldName)) { + type = TelephonyAddressType.fromString(reader.getString()); } else { reader.skipChildren(); } } - TeamsTelephonyTransferDestination deserializedTeamsTelephonyTransferDestination - = new TeamsTelephonyTransferDestination(value); - deserializedTeamsTelephonyTransferDestination.kind = kind; - return deserializedTeamsTelephonyTransferDestination; + TelephonyTeamsAddress deserializedTelephonyTeamsAddress = new TelephonyTeamsAddress(value); + deserializedTelephonyTeamsAddress.type = type; + return deserializedTelephonyTeamsAddress; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestination.java deleted file mode 100644 index 07c20dbc8c774..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestination.java +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * A destination for a telephony transfer target. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class TelephonyTransferDestination implements JsonSerializable { - - /* - * The telephony transfer destination type. - */ - @Generated - private TelephonyTransferDestinationKind kind - = TelephonyTransferDestinationKind.fromString("TelephonyTransferDestination"); - - /** - * Creates an instance of TelephonyTransferDestination class. - */ - @Generated - protected TelephonyTransferDestination() { - } - - /** - * Get the kind property: The telephony transfer destination type. - * - * @return the kind value. - */ - @Generated - public TelephonyTransferDestinationKind getKind() { - return this.kind; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of TelephonyTransferDestination from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of TelephonyTransferDestination if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the TelephonyTransferDestination. - */ - @Generated - public static TelephonyTransferDestination fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String discriminatorValue = null; - try (JsonReader readerToUse = reader.bufferObject()) { - // Prepare for reading - readerToUse.nextToken(); - while (readerToUse.nextToken() != JsonToken.END_OBJECT) { - String fieldName = readerToUse.getFieldName(); - readerToUse.nextToken(); - if ("kind".equals(fieldName)) { - discriminatorValue = readerToUse.getString(); - break; - } else { - readerToUse.skipChildren(); - } - } - // Use the discriminator value to determine which subtype should be deserialized. - if ("pstn".equals(discriminatorValue)) { - return PstnTelephonyTransferDestination.fromJson(readerToUse.reset()); - } else if ("teams".equals(discriminatorValue)) { - return TeamsTelephonyTransferDestination.fromJson(readerToUse.reset()); - } else if ("sip".equals(discriminatorValue)) { - return SipTelephonyTransferDestination.fromJson(readerToUse.reset()); - } else { - return fromJsonKnownDiscriminator(readerToUse.reset()); - } - } - }); - } - - @Generated - static TelephonyTransferDestination fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - TelephonyTransferDestination deserializedTelephonyTransferDestination = new TelephonyTransferDestination(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("kind".equals(fieldName)) { - deserializedTelephonyTransferDestination.kind - = TelephonyTransferDestinationKind.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedTelephonyTransferDestination; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestinationKind.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestinationKind.java deleted file mode 100644 index 6409eb918fc4f..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferDestinationKind.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * The kind of telephony transfer destination. Known values are stable; additional values may be added over time. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TelephonyTransferDestinationKind extends ExpandableStringEnum { - - /** - * A public switched telephone network destination. - */ - @Generated - public static final TelephonyTransferDestinationKind PSTN = fromString("pstn"); - - /** - * A Microsoft Teams user or resource-account destination. - */ - @Generated - public static final TelephonyTransferDestinationKind TEAMS = fromString("teams"); - - /** - * A Session Initiation Protocol destination. - */ - @Generated - public static final TelephonyTransferDestinationKind SIP = fromString("sip"); - - /** - * Creates a new instance of TelephonyTransferDestinationKind value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public TelephonyTransferDestinationKind() { - } - - /** - * Creates or finds a TelephonyTransferDestinationKind from its string representation. - * - * @param name a name to look for. - * @return the corresponding TelephonyTransferDestinationKind. - */ - @Generated - public static TelephonyTransferDestinationKind fromString(String name) { - return fromString(name, TelephonyTransferDestinationKind.class); - } - - /** - * Gets known TelephonyTransferDestinationKind values. - * - * @return known TelephonyTransferDestinationKind values. - */ - @Generated - public static Collection values() { - return values(TelephonyTransferDestinationKind.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java index acb8d647143a3..014c890eb80de 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java @@ -32,24 +32,10 @@ public final class TelephonyTransferTarget implements JsonSerializable { String name = null; String description = null; - TelephonyTransferDestination destination = null; + TelephonyAddress destination = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); @@ -117,7 +104,7 @@ public static TelephonyTransferTarget fromJson(JsonReader jsonReader) throws IOE } else if ("description".equals(fieldName)) { description = reader.getString(); } else if ("destination".equals(fieldName)) { - destination = TelephonyTransferDestination.fromJson(reader); + destination = TelephonyAddress.fromJson(reader); } else { reader.skipChildren(); } @@ -125,4 +112,18 @@ public static TelephonyTransferTarget fromJson(JsonReader jsonReader) throws IOE return new TelephonyTransferTarget(name, description, destination); }); } + + /** + * Creates an instance of TelephonyTransferTarget class. + * + * @param name the name value to set. + * @param description the description value to set. + * @param destination the destination value to set. + */ + @Generated + public TelephonyTransferTarget(String name, String description, TelephonyAddress destination) { + this.name = name; + this.description = description; + this.destination = destination; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType1.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType3.java similarity index 62% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType1.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType3.java index b4b9ba20c85e0..70580026dd425 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType1.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/ToolFunctionToolType3.java @@ -4,9 +4,9 @@ package com.azure.ai.agents.models; /** - * Defines values for ToolFunctionToolType1. + * Defines values for ToolFunctionToolType3. */ -enum ToolFunctionToolType1 { +enum ToolFunctionToolType3 { /** * Enum value function. @@ -14,26 +14,26 @@ enum ToolFunctionToolType1 { FUNCTION("function"); /** - * The actual serialized value for a ToolFunctionToolType1 instance. + * The actual serialized value for a ToolFunctionToolType3 instance. */ private final String value; - ToolFunctionToolType1(String value) { + ToolFunctionToolType3(String value) { this.value = value; } /** - * Parses a serialized value to a ToolFunctionToolType1 instance. + * Parses a serialized value to a ToolFunctionToolType3 instance. * * @param value the serialized value to parse. - * @return the parsed ToolFunctionToolType1 object, or null if unable to parse. + * @return the parsed ToolFunctionToolType3 object, or null if unable to parse. */ - public static ToolFunctionToolType1 fromString(String value) { + public static ToolFunctionToolType3 fromString(String value) { if (value == null) { return null; } - ToolFunctionToolType1[] items = ToolFunctionToolType1.values(); - for (ToolFunctionToolType1 item : items) { + ToolFunctionToolType3[] items = ToolFunctionToolType3.values(); + for (ToolFunctionToolType3 item : items) { if (item.toString().equalsIgnoreCase(value)) { return item; } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextInputTokenDetails.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextInputTokenDetails.java deleted file mode 100644 index e053d630314e2..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextInputTokenDetails.java +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The TranscriptTextInputTokenDetails model. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TranscriptTextInputTokenDetails implements JsonSerializable { - - /* - * The text_tokens property. - */ - @Generated - private Long textTokens; - - /* - * The audio_tokens property. - */ - @Generated - private Long audioTokens; - - /** - * Creates an instance of TranscriptTextInputTokenDetails class. - */ - @Generated - private TranscriptTextInputTokenDetails() { - } - - /** - * Get the textTokens property: The text_tokens property. - * - * @return the textTokens value. - */ - @Generated - public Long getTextTokens() { - return this.textTokens; - } - - /** - * Get the audioTokens property: The audio_tokens property. - * - * @return the audioTokens value. - */ - @Generated - public Long getAudioTokens() { - return this.audioTokens; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeNumberField("text_tokens", this.textTokens); - jsonWriter.writeNumberField("audio_tokens", this.audioTokens); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of TranscriptTextInputTokenDetails from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of TranscriptTextInputTokenDetails if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the TranscriptTextInputTokenDetails. - */ - @Generated - public static TranscriptTextInputTokenDetails fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - TranscriptTextInputTokenDetails deserializedTranscriptTextInputTokenDetails - = new TranscriptTextInputTokenDetails(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("text_tokens".equals(fieldName)) { - deserializedTranscriptTextInputTokenDetails.textTokens = reader.getNullable(JsonReader::getLong); - } else if ("audio_tokens".equals(fieldName)) { - deserializedTranscriptTextInputTokenDetails.audioTokens = reader.getNullable(JsonReader::getLong); - } else { - reader.skipChildren(); - } - } - return deserializedTranscriptTextInputTokenDetails; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsage.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsage.java deleted file mode 100644 index a277f86067edf..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsage.java +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Token usage statistics for the request. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class TranscriptTextUsage implements JsonSerializable { - - /* - * The type property. - */ - @Generated - private TranscriptTextUsageType type = TranscriptTextUsageType.fromString("TranscriptTextUsage"); - - /** - * Creates an instance of TranscriptTextUsage class. - */ - @Generated - protected TranscriptTextUsage() { - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - public TranscriptTextUsageType getType() { - return this.type; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of TranscriptTextUsage from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of TranscriptTextUsage if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IOException If an error occurs while reading the TranscriptTextUsage. - */ - @Generated - public static TranscriptTextUsage fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String discriminatorValue = null; - try (JsonReader readerToUse = reader.bufferObject()) { - // Prepare for reading - readerToUse.nextToken(); - while (readerToUse.nextToken() != JsonToken.END_OBJECT) { - String fieldName = readerToUse.getFieldName(); - readerToUse.nextToken(); - if ("type".equals(fieldName)) { - discriminatorValue = readerToUse.getString(); - break; - } else { - readerToUse.skipChildren(); - } - } - // Use the discriminator value to determine which subtype should be deserialized. - if ("duration".equals(discriminatorValue)) { - return TranscriptTextUsageDuration.fromJson(readerToUse.reset()); - } else if ("tokens".equals(discriminatorValue)) { - return TranscriptTextUsageTokens.fromJson(readerToUse.reset()); - } else { - return fromJsonKnownDiscriminator(readerToUse.reset()); - } - } - }); - } - - @Generated - static TranscriptTextUsage fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - TranscriptTextUsage deserializedTranscriptTextUsage = new TranscriptTextUsage(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - deserializedTranscriptTextUsage.type = TranscriptTextUsageType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - return deserializedTranscriptTextUsage; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageDuration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageDuration.java deleted file mode 100644 index b3071c9d1c6b9..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageDuration.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.time.Duration; - -/** - * Duration Usage - * - * Usage statistics for models billed by audio input duration. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TranscriptTextUsageDuration extends TranscriptTextUsage { - - /* - * The type property. - */ - @Generated - private TranscriptTextUsageType type = TranscriptTextUsageType.DURATION; - - /* - * Duration of the input audio in seconds. - */ - @Generated - private final long duration; - - /** - * Creates an instance of TranscriptTextUsageDuration class. - * - * @param duration the duration value to set. - */ - @Generated - private TranscriptTextUsageDuration(Duration duration) { - if (duration == null) { - this.duration = 0L; - } else { - this.duration = duration.getSeconds(); - } - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public TranscriptTextUsageType getType() { - return this.type; - } - - /** - * Get the duration property: Duration of the input audio in seconds. - * - * @return the duration value. - */ - @Generated - public Duration getDuration() { - return Duration.ofSeconds(this.duration); - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeLongField("seconds", this.duration); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of TranscriptTextUsageDuration from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of TranscriptTextUsageDuration if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TranscriptTextUsageDuration. - */ - @Generated - public static TranscriptTextUsageDuration fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - Duration duration = null; - TranscriptTextUsageType type = TranscriptTextUsageType.DURATION; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("seconds".equals(fieldName)) { - duration = Duration.ofSeconds(reader.getLong()); - } else if ("type".equals(fieldName)) { - type = TranscriptTextUsageType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - TranscriptTextUsageDuration deserializedTranscriptTextUsageDuration - = new TranscriptTextUsageDuration(duration); - deserializedTranscriptTextUsageDuration.type = type; - return deserializedTranscriptTextUsageDuration; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageTokens.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageTokens.java deleted file mode 100644 index e858459b941d1..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageTokens.java +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Token Usage - * - * Usage statistics for models billed by token usage. - */ -@Immutable -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TranscriptTextUsageTokens extends TranscriptTextUsage { - - /* - * The type property. - */ - @Generated - private TranscriptTextUsageType type = TranscriptTextUsageType.TOKENS; - - /* - * Number of input tokens billed for this request. - */ - @Generated - private final long inputTokens; - - /* - * Details about the input tokens billed for this request. - */ - @Generated - private TranscriptTextInputTokenDetails inputTokenDetails; - - /* - * Number of output tokens generated. - */ - @Generated - private final long outputTokens; - - /* - * Total number of tokens used (input + output). - */ - @Generated - private final long totalTokens; - - /** - * Creates an instance of TranscriptTextUsageTokens class. - * - * @param inputTokens the inputTokens value to set. - * @param outputTokens the outputTokens value to set. - * @param totalTokens the totalTokens value to set. - */ - @Generated - private TranscriptTextUsageTokens(long inputTokens, long outputTokens, long totalTokens) { - this.inputTokens = inputTokens; - this.outputTokens = outputTokens; - this.totalTokens = totalTokens; - } - - /** - * Get the type property: The type property. - * - * @return the type value. - */ - @Generated - @Override - public TranscriptTextUsageType getType() { - return this.type; - } - - /** - * Get the inputTokens property: Number of input tokens billed for this request. - * - * @return the inputTokens value. - */ - @Generated - public long getInputTokens() { - return this.inputTokens; - } - - /** - * Get the inputTokenDetails property: Details about the input tokens billed for this request. - * - * @return the inputTokenDetails value. - */ - @Generated - public TranscriptTextInputTokenDetails getInputTokenDetails() { - return this.inputTokenDetails; - } - - /** - * Get the outputTokens property: Number of output tokens generated. - * - * @return the outputTokens value. - */ - @Generated - public long getOutputTokens() { - return this.outputTokens; - } - - /** - * Get the totalTokens property: Total number of tokens used (input + output). - * - * @return the totalTokens value. - */ - @Generated - public long getTotalTokens() { - return this.totalTokens; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeLongField("input_tokens", this.inputTokens); - jsonWriter.writeLongField("output_tokens", this.outputTokens); - jsonWriter.writeLongField("total_tokens", this.totalTokens); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeJsonField("input_token_details", this.inputTokenDetails); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of TranscriptTextUsageTokens from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of TranscriptTextUsageTokens if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TranscriptTextUsageTokens. - */ - @Generated - public static TranscriptTextUsageTokens fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - long inputTokens = 0L; - long outputTokens = 0L; - long totalTokens = 0L; - TranscriptTextUsageType type = TranscriptTextUsageType.TOKENS; - TranscriptTextInputTokenDetails inputTokenDetails = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("input_tokens".equals(fieldName)) { - inputTokens = reader.getLong(); - } else if ("output_tokens".equals(fieldName)) { - outputTokens = reader.getLong(); - } else if ("total_tokens".equals(fieldName)) { - totalTokens = reader.getLong(); - } else if ("type".equals(fieldName)) { - type = TranscriptTextUsageType.fromString(reader.getString()); - } else if ("input_token_details".equals(fieldName)) { - inputTokenDetails = TranscriptTextInputTokenDetails.fromJson(reader); - } else { - reader.skipChildren(); - } - } - TranscriptTextUsageTokens deserializedTranscriptTextUsageTokens - = new TranscriptTextUsageTokens(inputTokens, outputTokens, totalTokens); - deserializedTranscriptTextUsageTokens.type = type; - deserializedTranscriptTextUsageTokens.inputTokenDetails = inputTokenDetails; - return deserializedTranscriptTextUsageTokens; - }); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageType.java deleted file mode 100644 index c72d862bd7100..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptTextUsageType.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for TranscriptTextUsageType. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TranscriptTextUsageType extends ExpandableStringEnum { - - /** - * Static value tokens for TranscriptTextUsageType. - */ - @Generated - public static final TranscriptTextUsageType TOKENS = fromString("tokens"); - - /** - * Static value duration for TranscriptTextUsageType. - */ - @Generated - public static final TranscriptTextUsageType DURATION = fromString("duration"); - - /** - * Creates a new instance of TranscriptTextUsageType value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public TranscriptTextUsageType() { - } - - /** - * Creates or finds a TranscriptTextUsageType from its string representation. - * - * @param name a name to look for. - * @return the corresponding TranscriptTextUsageType. - */ - @Generated - public static TranscriptTextUsageType fromString(String name) { - return fromString(name, TranscriptTextUsageType.class); - } - - /** - * Gets known TranscriptTextUsageType values. - * - * @return known TranscriptTextUsageType values. - */ - @Generated - public static Collection values() { - return values(TranscriptTextUsageType.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java index ad6ea0054400d..89f3e034978c6 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java @@ -4,8 +4,8 @@ package com.azure.ai.agents.models; import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; @@ -14,7 +14,7 @@ /** * A Twilio binding owned by a voice agent. */ -@Immutable +@Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") public final class TwilioTelephonyBinding extends TelephonyBinding { @@ -30,22 +30,6 @@ public final class TwilioTelephonyBinding extends TelephonyBinding { @Generated private final String phoneNumber; - /** - * Creates an instance of TwilioTelephonyBinding class. - * - * @param id the id value to set. - * @param connectionName the connectionName value to set. - * @param status the status value to set. - * @param incomingCallUrl the incomingCallUrl value to set. - * @param phoneNumber the phoneNumber value to set. - */ - @Generated - private TwilioTelephonyBinding(String id, String connectionName, TelephonyBindingStatus status, - String incomingCallUrl, String phoneNumber) { - super(id, connectionName, status, incomingCallUrl); - this.phoneNumber = phoneNumber; - } - /** * Get the provider property: The telephony provider. * @@ -74,10 +58,7 @@ public String getPhoneNumber() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("id", getId()); jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("status", getStatus() == null ? null : getStatus().toString()); - jsonWriter.writeStringField("incoming_call_url", getIncomingCallUrl()); jsonWriter.writeStringField("label", getLabel()); jsonWriter.writeStringField("phone_number", this.phoneNumber); jsonWriter.writeStringField("provider", this.provider == null ? null : this.provider.toString()); @@ -98,7 +79,6 @@ public static TwilioTelephonyBinding fromJson(JsonReader jsonReader) throws IOEx return jsonReader.readObject(reader -> { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; String label = null; String phoneNumber = null; @@ -110,8 +90,6 @@ public static TwilioTelephonyBinding fromJson(JsonReader jsonReader) throws IOEx id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("label".equals(fieldName)) { @@ -125,10 +103,34 @@ public static TwilioTelephonyBinding fromJson(JsonReader jsonReader) throws IOEx } } TwilioTelephonyBinding deserializedTwilioTelephonyBinding - = new TwilioTelephonyBinding(id, connectionName, status, incomingCallUrl, phoneNumber); + = new TwilioTelephonyBinding(connectionName, phoneNumber); + deserializedTwilioTelephonyBinding.setId(id); + deserializedTwilioTelephonyBinding.setIncomingCallUrl(incomingCallUrl); deserializedTwilioTelephonyBinding.setLabel(label); deserializedTwilioTelephonyBinding.provider = provider; return deserializedTwilioTelephonyBinding; }); } + + /** + * Creates an instance of TwilioTelephonyBinding class. + * + * @param connectionName the connectionName value to set. + * @param phoneNumber the phoneNumber value to set. + */ + @Generated + public TwilioTelephonyBinding(String connectionName, String phoneNumber) { + super(connectionName); + this.phoneNumber = phoneNumber; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public TwilioTelephonyBinding setLabel(String label) { + super.setLabel(label); + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java index 4b5a74cee9808..77c6f0323945d 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java @@ -30,22 +30,6 @@ public final class TwilioTelephonyBindingListItem extends TelephonyBindingListIt @Generated private final String phoneNumber; - /** - * Creates an instance of TwilioTelephonyBindingListItem class. - * - * @param id the id value to set. - * @param connectionName the connectionName value to set. - * @param status the status value to set. - * @param incomingCallUrl the incomingCallUrl value to set. - * @param phoneNumber the phoneNumber value to set. - */ - @Generated - private TwilioTelephonyBindingListItem(String id, String connectionName, TelephonyBindingStatus status, - String incomingCallUrl, String phoneNumber) { - super(id, connectionName, status, incomingCallUrl); - this.phoneNumber = phoneNumber; - } - /** * Get the provider property: The telephony provider. * @@ -76,7 +60,6 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("id", getId()); jsonWriter.writeStringField("connection_name", getConnectionName()); - jsonWriter.writeStringField("status", getStatus() == null ? null : getStatus().toString()); jsonWriter.writeStringField("incoming_call_url", getIncomingCallUrl()); jsonWriter.writeStringField("label", getLabel()); jsonWriter.writeStringField("phone_number", this.phoneNumber); @@ -98,7 +81,6 @@ public static TwilioTelephonyBindingListItem fromJson(JsonReader jsonReader) thr return jsonReader.readObject(reader -> { String id = null; String connectionName = null; - TelephonyBindingStatus status = null; String incomingCallUrl = null; String eTag = null; String label = null; @@ -111,8 +93,6 @@ public static TwilioTelephonyBindingListItem fromJson(JsonReader jsonReader) thr id = reader.getString(); } else if ("connection_name".equals(fieldName)) { connectionName = reader.getString(); - } else if ("status".equals(fieldName)) { - status = TelephonyBindingStatus.fromString(reader.getString()); } else if ("incoming_call_url".equals(fieldName)) { incomingCallUrl = reader.getString(); } else if ("etag".equals(fieldName)) { @@ -128,11 +108,26 @@ public static TwilioTelephonyBindingListItem fromJson(JsonReader jsonReader) thr } } TwilioTelephonyBindingListItem deserializedTwilioTelephonyBindingListItem - = new TwilioTelephonyBindingListItem(id, connectionName, status, incomingCallUrl, phoneNumber); + = new TwilioTelephonyBindingListItem(id, connectionName, incomingCallUrl, phoneNumber); deserializedTwilioTelephonyBindingListItem.setETag(eTag); deserializedTwilioTelephonyBindingListItem.setLabel(label); deserializedTwilioTelephonyBindingListItem.provider = provider; return deserializedTwilioTelephonyBindingListItem; }); } + + /** + * Creates an instance of TwilioTelephonyBindingListItem class. + * + * @param id the id value to set. + * @param connectionName the connectionName value to set. + * @param incomingCallUrl the incomingCallUrl value to set. + * @param phoneNumber the phoneNumber value to set. + */ + @Generated + private TwilioTelephonyBindingListItem(String id, String connectionName, String incomingCallUrl, + String phoneNumber) { + super(id, connectionName, incomingCallUrl); + this.phoneNumber = phoneNumber; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java index 79aaee8a3f24a..50d14000240c3 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java @@ -13,6 +13,7 @@ import com.azure.json.JsonWriter; import java.io.IOException; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -24,27 +25,20 @@ public final class UpdateTelephonyBindingInput implements JsonSerializable { /* - * The new lifecycle status. - */ - @Generated - private TelephonyBindingStatus status; - - /* - * The replacement display label. Omit it to preserve the current value; use null to clear it. + * Replacement label: omit to preserve, null/blank to clear. Trimmed before length validation. */ @Generated private String label; /* - * The replacement Foundry connection name. This property is valid only for a Teams Phone extensibility binding; a - * Twilio binding's connection is immutable. + * Replacement same-project connection for Teams or SIP (SipInbound only); immutable for Twilio. Null/blank names + * are invalid. */ @Generated private String connectionName; /* - * The replacement Teams Phone extensibility display phone number. Omit it to preserve the current value; use null - * to clear it. This property is valid only for a Teams Phone extensibility binding. + * Teams/SIP display number, not SIP routing. Omit to preserve; null/empty/blank clears. Unsupported for Twilio. */ @Generated private String phoneNumber; @@ -89,31 +83,8 @@ public UpdateTelephonyBindingInput() { } /** - * Get the status property: The new lifecycle status. - * - * @return the status value. - */ - @Generated - public TelephonyBindingStatus getStatus() { - return this.status; - } - - /** - * Set the status property: The new lifecycle status. - * - * @param status the status value to set. - * @return the UpdateTelephonyBindingInput object itself. - */ - @Generated - public UpdateTelephonyBindingInput setStatus(TelephonyBindingStatus status) { - this.status = status; - this.updatedProperties.add("status"); - return this; - } - - /** - * Get the label property: The replacement display label. Omit it to preserve the current value; use null to clear - * it. + * Get the label property: Replacement label: omit to preserve, null/blank to clear. Trimmed before length + * validation. * * @return the label value. */ @@ -123,8 +94,8 @@ public String getLabel() { } /** - * Set the label property: The replacement display label. Omit it to preserve the current value; use null to clear - * it. + * Set the label property: Replacement label: omit to preserve, null/blank to clear. Trimmed before length + * validation. * * @param label the label value to set. * @return the UpdateTelephonyBindingInput object itself. @@ -137,8 +108,8 @@ public UpdateTelephonyBindingInput setLabel(String label) { } /** - * Get the connectionName property: The replacement Foundry connection name. This property is valid only for a Teams - * Phone extensibility binding; a Twilio binding's connection is immutable. + * Get the connectionName property: Replacement same-project connection for Teams or SIP (SipInbound only); + * immutable for Twilio. Null/blank names are invalid. * * @return the connectionName value. */ @@ -148,8 +119,8 @@ public String getConnectionName() { } /** - * Set the connectionName property: The replacement Foundry connection name. This property is valid only for a Teams - * Phone extensibility binding; a Twilio binding's connection is immutable. + * Set the connectionName property: Replacement same-project connection for Teams or SIP (SipInbound only); + * immutable for Twilio. Null/blank names are invalid. * * @param connectionName the connectionName value to set. * @return the UpdateTelephonyBindingInput object itself. @@ -162,8 +133,8 @@ public UpdateTelephonyBindingInput setConnectionName(String connectionName) { } /** - * Get the phoneNumber property: The replacement Teams Phone extensibility display phone number. Omit it to preserve - * the current value; use null to clear it. This property is valid only for a Teams Phone extensibility binding. + * Get the phoneNumber property: Teams/SIP display number, not SIP routing. Omit to preserve; null/empty/blank + * clears. Unsupported for Twilio. * * @return the phoneNumber value. */ @@ -173,8 +144,8 @@ public String getPhoneNumber() { } /** - * Set the phoneNumber property: The replacement Teams Phone extensibility display phone number. Omit it to preserve - * the current value; use null to clear it. This property is valid only for a Teams Phone extensibility binding. + * Set the phoneNumber property: Teams/SIP display number, not SIP routing. Omit to preserve; null/empty/blank + * clears. Unsupported for Twilio. * * @param phoneNumber the phoneNumber value to set. * @return the UpdateTelephonyBindingInput object itself. @@ -196,10 +167,11 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { return toJsonMergePatch(jsonWriter); } else { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); jsonWriter.writeStringField("label", this.label); jsonWriter.writeStringField("connection_name", this.connectionName); jsonWriter.writeStringField("phone_number", this.phoneNumber); + jsonWriter.writeArrayField("allowed_calling_numbers", this.allowedCallingNumbers, + (writer, element) -> writer.writeString(element)); return jsonWriter.writeEndObject(); } } @@ -207,13 +179,6 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { @Generated private JsonWriter toJsonMergePatch(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - if (updatedProperties.contains("status")) { - if (this.status == null) { - jsonWriter.writeNullField("status"); - } else { - jsonWriter.writeStringField("status", this.status.toString()); - } - } if (updatedProperties.contains("label")) { if (this.label == null) { jsonWriter.writeNullField("label"); @@ -235,6 +200,14 @@ private JsonWriter toJsonMergePatch(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("phone_number", this.phoneNumber); } } + if (updatedProperties.contains("allowedCallingNumbers")) { + if (this.allowedCallingNumbers == null) { + jsonWriter.writeNullField("allowed_calling_numbers"); + } else { + jsonWriter.writeArrayField("allowed_calling_numbers", this.allowedCallingNumbers, + (writer, element) -> writer.writeString(element)); + } + } return jsonWriter.writeEndObject(); } @@ -253,15 +226,15 @@ public static UpdateTelephonyBindingInput fromJson(JsonReader jsonReader) throws while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("status".equals(fieldName)) { - deserializedUpdateTelephonyBindingInput.status - = TelephonyBindingStatus.fromString(reader.getString()); - } else if ("label".equals(fieldName)) { + if ("label".equals(fieldName)) { deserializedUpdateTelephonyBindingInput.label = reader.getString(); } else if ("connection_name".equals(fieldName)) { deserializedUpdateTelephonyBindingInput.connectionName = reader.getString(); } else if ("phone_number".equals(fieldName)) { deserializedUpdateTelephonyBindingInput.phoneNumber = reader.getString(); + } else if ("allowed_calling_numbers".equals(fieldName)) { + List allowedCallingNumbers = reader.readArray(reader1 -> reader1.getString()); + deserializedUpdateTelephonyBindingInput.allowedCallingNumbers = allowedCallingNumbers; } else { reader.skipChildren(); } @@ -269,4 +242,36 @@ public static UpdateTelephonyBindingInput fromJson(JsonReader jsonReader) throws return deserializedUpdateTelephonyBindingInput; }); } + + /* + * SIP caller restrictions: omit to preserve, [] to clear; null is invalid. Network restrictions belong to the + * connection. + */ + @Generated + private List allowedCallingNumbers; + + /** + * Get the allowedCallingNumbers property: SIP caller restrictions: omit to preserve, [] to clear; null is invalid. + * Network restrictions belong to the connection. + * + * @return the allowedCallingNumbers value. + */ + @Generated + public List getAllowedCallingNumbers() { + return this.allowedCallingNumbers; + } + + /** + * Set the allowedCallingNumbers property: SIP caller restrictions: omit to preserve, [] to clear; null is invalid. + * Network restrictions belong to the connection. + * + * @param allowedCallingNumbers the allowedCallingNumbers value to set. + * @return the UpdateTelephonyBindingInput object itself. + */ + @Generated + public UpdateTelephonyBindingInput setAllowedCallingNumbers(List allowedCallingNumbers) { + this.allowedCallingNumbers = allowedCallingNumbers; + this.updatedProperties.add("allowedCallingNumbers"); + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java index d53a351260ad6..daa58f4605d08 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java @@ -3,13 +3,16 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeAudioFormats; import java.io.IOException; /** @@ -23,7 +26,7 @@ public final class VoiceAgentAudioInputConfiguration implements JsonSerializable * The input audio format. */ @Generated - private RealtimeAudioFormat format; + private RealtimeAudioFormats format; /* * Input noise reduction. Set to null to disable. @@ -63,22 +66,10 @@ public VoiceAgentAudioInputConfiguration() { * @return the format value. */ @Generated - public RealtimeAudioFormat getFormat() { + public RealtimeAudioFormats getFormat() { return this.format; } - /** - * Set the format property: The input audio format. - * - * @param format the format value to set. - * @return the VoiceAgentAudioInputConfiguration object itself. - */ - @Generated - public VoiceAgentAudioInputConfiguration setFormat(RealtimeAudioFormat format) { - this.format = format; - return this; - } - /** * Get the noiseReduction property: Input noise reduction. Set to null to disable. * @@ -172,11 +163,14 @@ public VoiceAgentAudioInputConfiguration setTranscription(VoiceAgentInputTranscr /** * {@inheritDoc} */ - @Generated @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("format", this.format); + if (this.format != null) { + jsonWriter.writeFieldName("format"); + OpenAIJsonHelper.toBinaryData(this.format).writeTo(jsonWriter); + } jsonWriter.writeJsonField("noise_reduction", this.noiseReduction); jsonWriter.writeJsonField("turn_detection", this.turnDetection); jsonWriter.writeJsonField("echo_cancellation", this.echoCancellation); @@ -192,8 +186,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * null if it was pointing to JSON null. * @throws IOException If an error occurs while reading the VoiceAgentAudioInputConfiguration. */ - @Generated public static VoiceAgentAudioInputConfiguration fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup return jsonReader.readObject(reader -> { VoiceAgentAudioInputConfiguration deserializedVoiceAgentAudioInputConfiguration = new VoiceAgentAudioInputConfiguration(); @@ -201,7 +195,10 @@ public static VoiceAgentAudioInputConfiguration fromJson(JsonReader jsonReader) String fieldName = reader.getFieldName(); reader.nextToken(); if ("format".equals(fieldName)) { - deserializedVoiceAgentAudioInputConfiguration.format = RealtimeAudioFormat.fromJson(reader); + BinaryData formatData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + deserializedVoiceAgentAudioInputConfiguration.format + = OpenAIJsonHelper.fromBinaryData(formatData, RealtimeAudioFormats.class); } else if ("noise_reduction".equals(fieldName)) { deserializedVoiceAgentAudioInputConfiguration.noiseReduction = VoiceAgentNoiseReduction.fromJson(reader); @@ -221,4 +218,16 @@ public static VoiceAgentAudioInputConfiguration fromJson(JsonReader jsonReader) return deserializedVoiceAgentAudioInputConfiguration; }); } + + /** + * Set the format property: The input audio format. + * + * @param format the format value to set. + * @return the VoiceAgentAudioInputConfiguration object itself. + */ + @Generated + public VoiceAgentAudioInputConfiguration setFormat(RealtimeAudioFormats format) { + this.format = format; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java index 652f10eb1f12f..2d236495e7604 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java @@ -3,125 +3,31 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeAudioFormats; import java.io.IOException; import java.util.List; /** - * Output audio configuration for a voice agent. - * Provider-specific fields are selected by `voice_type`: - * - `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. + * Output audio configuration for a voice agent. Extends the voice configuration with the session-level `format` and + * `output_audio_timestamp_types` settings, which apply to every voice type. */ @Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class VoiceAgentAudioOutputConfiguration implements JsonSerializable { +public final class VoiceAgentAudioOutputConfiguration extends VoiceAgentVoiceConfiguration { /* * The output audio format. Applies to every `voice_type` and defaults to 24 kHz PCM. */ @Generated - private RealtimeAudioFormat format; - - /* - * 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. - */ - @Generated - private String voice; - - /* - * The voice implementation. - */ - @Generated - private VoiceType voiceType; - - /* - * The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and - * `avatar-voice-sync`. - */ - @Generated - private String voiceLocale; - - /* - * The numeric output speed multiplier. Applies to all known `voice_type` values and defaults to 1. - */ - @Generated - private Double speed; - - /* - * The voice variation temperature. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and - * `avatar-voice-sync`. - */ - @Generated - private Double voiceTemperature; - - /* - * The URL of a custom pronunciation lexicon. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and - * `avatar-voice-sync`. - */ - @Generated - private String customLexiconUrl; - - /* - * The URL of a custom text-normalization configuration. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - */ - @Generated - private String customTextNormalizationUrl; - - /* - * Preferred BCP-47 locales for multilingual synthesis. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - */ - @Generated - private List preferredLocales; - - /* - * The voice speaking style. Applies only when `voice_type` is `azure-standard`. - */ - @Generated - private String style; - - /* - * The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and - * `avatar-voice-sync`. - */ - @Generated - private String pitch; - - /* - * The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and - * `avatar-voice-sync`. - */ - @Generated - private String volume; - - /* - * The Azure custom-voice deployment endpoint identifier. Applies only when `voice_type` is `azure-custom`. - */ - @Generated - private String customVoiceEndpointId; - - /* - * The Azure personal or avatar voice model. Applies only when `voice_type` is `azure-personal` or - * `avatar-voice-sync`. - */ - @Generated - private String personalVoiceModel; + private RealtimeAudioFormats format; /* * Timestamp kinds to include with output audio. Applies to every `voice_type`. @@ -142,329 +48,137 @@ public VoiceAgentAudioOutputConfiguration() { * @return the format value. */ @Generated - public RealtimeAudioFormat getFormat() { + public RealtimeAudioFormats getFormat() { return this.format; } /** - * Set the format property: The output audio format. Applies to every `voice_type` and defaults to 24 kHz PCM. - * - * @param format the format value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. - */ - @Generated - public VoiceAgentAudioOutputConfiguration setFormat(RealtimeAudioFormat format) { - this.format = format; - return this; - } - - /** - * Get the voice property: 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. - * - * @return the voice value. - */ - @Generated - public String getVoice() { - return this.voice; - } - - /** - * Set the voice property: 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. - * - * @param voice the voice value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setVoice(String voice) { - this.voice = voice; + super.setVoice(voice); return this; } /** - * Get the voiceType property: The voice implementation. - * - * @return the voiceType value. - */ - @Generated - public VoiceType getVoiceType() { - return this.voiceType; - } - - /** - * Set the voiceType property: The voice implementation. - * - * @param voiceType the voiceType value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setVoiceType(VoiceType voiceType) { - this.voiceType = voiceType; + super.setVoiceType(voiceType); return this; } /** - * Get the voiceLocale property: The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @return the voiceLocale value. - */ - @Generated - public String getVoiceLocale() { - return this.voiceLocale; - } - - /** - * Set the voiceLocale property: The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @param voiceLocale the voiceLocale value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setVoiceLocale(String voiceLocale) { - this.voiceLocale = voiceLocale; + super.setVoiceLocale(voiceLocale); return this; } /** - * Get the speed property: The numeric output speed multiplier. Applies to all known `voice_type` values and - * defaults to 1. - * - * @return the speed value. - */ - @Generated - public Double getSpeed() { - return this.speed; - } - - /** - * Set the speed property: The numeric output speed multiplier. Applies to all known `voice_type` values and - * defaults to 1. - * - * @param speed the speed value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setSpeed(Double speed) { - this.speed = speed; + super.setSpeed(speed); return this; } /** - * Get the voiceTemperature property: The voice variation temperature. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @return the voiceTemperature value. - */ - @Generated - public Double getVoiceTemperature() { - return this.voiceTemperature; - } - - /** - * Set the voiceTemperature property: The voice variation temperature. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @param voiceTemperature the voiceTemperature value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setVoiceTemperature(Double voiceTemperature) { - this.voiceTemperature = voiceTemperature; + super.setVoiceTemperature(voiceTemperature); return this; } /** - * Get the customLexiconUrl property: The URL of a custom pronunciation lexicon. Applies to `azure-standard`, - * `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @return the customLexiconUrl value. - */ - @Generated - public String getCustomLexiconUrl() { - return this.customLexiconUrl; - } - - /** - * Set the customLexiconUrl property: The URL of a custom pronunciation lexicon. Applies to `azure-standard`, - * `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @param customLexiconUrl the customLexiconUrl value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setCustomLexiconUrl(String customLexiconUrl) { - this.customLexiconUrl = customLexiconUrl; + super.setCustomLexiconUrl(customLexiconUrl); return this; } /** - * Get the customTextNormalizationUrl property: The URL of a custom text-normalization configuration. Applies to - * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @return the customTextNormalizationUrl value. - */ - @Generated - public String getCustomTextNormalizationUrl() { - return this.customTextNormalizationUrl; - } - - /** - * Set the customTextNormalizationUrl property: The URL of a custom text-normalization configuration. Applies to - * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @param customTextNormalizationUrl the customTextNormalizationUrl value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setCustomTextNormalizationUrl(String customTextNormalizationUrl) { - this.customTextNormalizationUrl = customTextNormalizationUrl; + super.setCustomTextNormalizationUrl(customTextNormalizationUrl); return this; } /** - * Get the preferredLocales property: Preferred BCP-47 locales for multilingual synthesis. Applies to - * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @return the preferredLocales value. - */ - @Generated - public List getPreferredLocales() { - return this.preferredLocales; - } - - /** - * Set the preferredLocales property: Preferred BCP-47 locales for multilingual synthesis. Applies to - * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. - * - * @param preferredLocales the preferredLocales value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setPreferredLocales(List preferredLocales) { - this.preferredLocales = preferredLocales; + super.setPreferredLocales(preferredLocales); return this; } /** - * Get the style property: The voice speaking style. Applies only when `voice_type` is `azure-standard`. - * - * @return the style value. - */ - @Generated - public String getStyle() { - return this.style; - } - - /** - * Set the style property: The voice speaking style. Applies only when `voice_type` is `azure-standard`. - * - * @param style the style value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setStyle(String style) { - this.style = style; + super.setStyle(style); return this; } /** - * Get the pitch property: The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @return the pitch value. - */ - @Generated - public String getPitch() { - return this.pitch; - } - - /** - * Set the pitch property: The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @param pitch the pitch value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setPitch(String pitch) { - this.pitch = pitch; + super.setPitch(pitch); return this; } /** - * Get the volume property: The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @return the volume value. - */ - @Generated - public String getVolume() { - return this.volume; - } - - /** - * Set the volume property: The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, - * `azure-personal`, and `avatar-voice-sync`. - * - * @param volume the volume value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setVolume(String volume) { - this.volume = volume; + super.setVolume(volume); return this; } /** - * Get the customVoiceEndpointId property: The Azure custom-voice deployment endpoint identifier. Applies only when - * `voice_type` is `azure-custom`. - * - * @return the customVoiceEndpointId value. - */ - @Generated - public String getCustomVoiceEndpointId() { - return this.customVoiceEndpointId; - } - - /** - * Set the customVoiceEndpointId property: The Azure custom-voice deployment endpoint identifier. Applies only when - * `voice_type` is `azure-custom`. - * - * @param customVoiceEndpointId the customVoiceEndpointId value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setCustomVoiceEndpointId(String customVoiceEndpointId) { - this.customVoiceEndpointId = customVoiceEndpointId; + super.setCustomVoiceEndpointId(customVoiceEndpointId); return this; } /** - * Get the personalVoiceModel property: The Azure personal or avatar voice model. Applies only when `voice_type` is - * `azure-personal` or `avatar-voice-sync`. - * - * @return the personalVoiceModel value. - */ - @Generated - public String getPersonalVoiceModel() { - return this.personalVoiceModel; - } - - /** - * Set the personalVoiceModel property: The Azure personal or avatar voice model. Applies only when `voice_type` is - * `azure-personal` or `avatar-voice-sync`. - * - * @param personalVoiceModel the personalVoiceModel value to set. - * @return the VoiceAgentAudioOutputConfiguration object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentAudioOutputConfiguration setPersonalVoiceModel(String personalVoiceModel) { - this.personalVoiceModel = personalVoiceModel; + super.setPersonalVoiceModel(personalVoiceModel); return this; } @@ -496,25 +210,28 @@ public List getOutputAudioTimestampTypes() { /** * {@inheritDoc} */ - @Generated @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("format", this.format); - jsonWriter.writeStringField("voice", this.voice); - jsonWriter.writeStringField("voice_type", this.voiceType == null ? null : this.voiceType.toString()); - jsonWriter.writeStringField("voice_locale", this.voiceLocale); - jsonWriter.writeNumberField("speed", this.speed); - jsonWriter.writeNumberField("voice_temperature", this.voiceTemperature); - jsonWriter.writeStringField("custom_lexicon_url", this.customLexiconUrl); - jsonWriter.writeStringField("custom_text_normalization_url", this.customTextNormalizationUrl); - jsonWriter.writeArrayField("prefer_locales", this.preferredLocales, + jsonWriter.writeStringField("voice", getVoice()); + jsonWriter.writeStringField("voice_type", getVoiceType() == null ? null : getVoiceType().toString()); + jsonWriter.writeStringField("voice_locale", getVoiceLocale()); + jsonWriter.writeNumberField("speed", getSpeed()); + jsonWriter.writeNumberField("voice_temperature", getVoiceTemperature()); + jsonWriter.writeStringField("custom_lexicon_url", getCustomLexiconUrl()); + jsonWriter.writeStringField("custom_text_normalization_url", getCustomTextNormalizationUrl()); + jsonWriter.writeArrayField("prefer_locales", getPreferredLocales(), (writer, element) -> writer.writeString(element)); - jsonWriter.writeStringField("style", this.style); - jsonWriter.writeStringField("pitch", this.pitch); - jsonWriter.writeStringField("volume", this.volume); - jsonWriter.writeStringField("custom_voice_endpoint_id", this.customVoiceEndpointId); - jsonWriter.writeStringField("personal_voice_model", this.personalVoiceModel); + jsonWriter.writeStringField("style", getStyle()); + jsonWriter.writeStringField("pitch", getPitch()); + jsonWriter.writeStringField("volume", getVolume()); + jsonWriter.writeStringField("custom_voice_endpoint_id", getCustomVoiceEndpointId()); + jsonWriter.writeStringField("personal_voice_model", getPersonalVoiceModel()); + if (this.format != null) { + jsonWriter.writeFieldName("format"); + OpenAIJsonHelper.toBinaryData(this.format).writeTo(jsonWriter); + } jsonWriter.writeArrayField("output_audio_timestamp_types", this.outputAudioTimestampTypes, (writer, element) -> writer.writeString(element == null ? null : element.toString())); return jsonWriter.writeEndObject(); @@ -528,44 +245,48 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { * null if it was pointing to JSON null. * @throws IOException If an error occurs while reading the VoiceAgentAudioOutputConfiguration. */ - @Generated public static VoiceAgentAudioOutputConfiguration fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup return jsonReader.readObject(reader -> { VoiceAgentAudioOutputConfiguration deserializedVoiceAgentAudioOutputConfiguration = new VoiceAgentAudioOutputConfiguration(); while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("format".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.format = RealtimeAudioFormat.fromJson(reader); - } else if ("voice".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.voice = reader.getString(); + if ("voice".equals(fieldName)) { + deserializedVoiceAgentAudioOutputConfiguration.setVoice(reader.getString()); } else if ("voice_type".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.voiceType = VoiceType.fromString(reader.getString()); + deserializedVoiceAgentAudioOutputConfiguration + .setVoiceType(VoiceType.fromString(reader.getString())); } else if ("voice_locale".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.voiceLocale = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setVoiceLocale(reader.getString()); } else if ("speed".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.speed = reader.getNullable(JsonReader::getDouble); + deserializedVoiceAgentAudioOutputConfiguration.setSpeed(reader.getNullable(JsonReader::getDouble)); } else if ("voice_temperature".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.voiceTemperature - = reader.getNullable(JsonReader::getDouble); + deserializedVoiceAgentAudioOutputConfiguration + .setVoiceTemperature(reader.getNullable(JsonReader::getDouble)); } else if ("custom_lexicon_url".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.customLexiconUrl = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setCustomLexiconUrl(reader.getString()); } else if ("custom_text_normalization_url".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.customTextNormalizationUrl = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setCustomTextNormalizationUrl(reader.getString()); } else if ("prefer_locales".equals(fieldName)) { List preferredLocales = reader.readArray(reader1 -> reader1.getString()); - deserializedVoiceAgentAudioOutputConfiguration.preferredLocales = preferredLocales; + deserializedVoiceAgentAudioOutputConfiguration.setPreferredLocales(preferredLocales); } else if ("style".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.style = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setStyle(reader.getString()); } else if ("pitch".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.pitch = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setPitch(reader.getString()); } else if ("volume".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.volume = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setVolume(reader.getString()); } else if ("custom_voice_endpoint_id".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.customVoiceEndpointId = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setCustomVoiceEndpointId(reader.getString()); } else if ("personal_voice_model".equals(fieldName)) { - deserializedVoiceAgentAudioOutputConfiguration.personalVoiceModel = reader.getString(); + deserializedVoiceAgentAudioOutputConfiguration.setPersonalVoiceModel(reader.getString()); + } else if ("format".equals(fieldName)) { + BinaryData formatData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + deserializedVoiceAgentAudioOutputConfiguration.format + = OpenAIJsonHelper.fromBinaryData(formatData, RealtimeAudioFormats.class); } else if ("output_audio_timestamp_types".equals(fieldName)) { List outputAudioTimestampTypes = reader.readArray(reader1 -> VoiceAgentAudioTimestampType.fromString(reader1.getString())); @@ -578,4 +299,16 @@ public static VoiceAgentAudioOutputConfiguration fromJson(JsonReader jsonReader) return deserializedVoiceAgentAudioOutputConfiguration; }); } + + /** + * Set the format property: The output audio format. Applies to every `voice_type` and defaults to 24 kHz PCM. + * + * @param format the format value to set. + * @return the VoiceAgentAudioOutputConfiguration object itself. + */ + @Generated + public VoiceAgentAudioOutputConfiguration setFormat(RealtimeAudioFormats format) { + this.format = format; + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentBaseDefinition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentBaseDefinition.java new file mode 100644 index 0000000000000..fecacdebcd6a5 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentBaseDefinition.java @@ -0,0 +1,243 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.Map; + +/** + * Shared voice-agent settings; protocol-specific fields remain flat on each subtype. + * Creates and updates produce immutable versions. Each version selects its own protocol, so a new version can switch + * between Realtime and Live. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class VoiceAgentBaseDefinition extends AgentDefinition { + + /* + * The kind property. + */ + @Generated + private final AgentKind kind = AgentKind.VOICE; + + /* + * The voice protocol for this agent version. Null and unknown values are invalid. + */ + @Generated + private VoiceAgentSubProtocol subProtocol; + + /* + * Frontend instructions, templated with structured_inputs. Backend instructions belong in delegation.responses. + */ + @Generated + private String instructions; + + /* + * Template inputs for session instructions and supported greetings. + */ + @Generated + private Map structuredInputs; + + /* + * Persists conversation content and audio in Foundry, not native Live recordings. Defaults to false. + */ + @Generated + private Boolean store; + + /** + * Creates an instance of VoiceAgentBaseDefinition class. + */ + @Generated + protected VoiceAgentBaseDefinition() { + } + + /** + * Get the kind property: The kind property. + * + * @return the kind value. + */ + @Generated + @Override + public AgentKind getKind() { + return this.kind; + } + + /** + * Get the subProtocol property: The voice protocol for this agent version. Null and unknown values are invalid. + * + * @return the subProtocol value. + */ + @Generated + public VoiceAgentSubProtocol getSubProtocol() { + return this.subProtocol; + } + + /** + * Get the instructions property: Frontend instructions, templated with structured_inputs. Backend instructions + * belong in delegation.responses. + * + * @return the instructions value. + */ + @Generated + public String getInstructions() { + return this.instructions; + } + + /** + * Set the instructions property: Frontend instructions, templated with structured_inputs. Backend instructions + * belong in delegation.responses. + * + * @param instructions the instructions value to set. + * @return the VoiceAgentBaseDefinition object itself. + */ + @Generated + public VoiceAgentBaseDefinition setInstructions(String instructions) { + this.instructions = instructions; + return this; + } + + /** + * Get the structuredInputs property: Template inputs for session instructions and supported greetings. + * + * @return the structuredInputs value. + */ + @Generated + public Map getStructuredInputs() { + return this.structuredInputs; + } + + /** + * Set the structuredInputs property: Template inputs for session instructions and supported greetings. + * + * @param structuredInputs the structuredInputs value to set. + * @return the VoiceAgentBaseDefinition object itself. + */ + @Generated + public VoiceAgentBaseDefinition setStructuredInputs(Map structuredInputs) { + this.structuredInputs = structuredInputs; + return this; + } + + /** + * Get the store property: Persists conversation content and audio in Foundry, not native Live recordings. Defaults + * to false. + * + * @return the store value. + */ + @Generated + public Boolean isStore() { + return this.store; + } + + /** + * Set the store property: Persists conversation content and audio in Foundry, not native Live recordings. Defaults + * to false. + * + * @param store the store value to set. + * @return the VoiceAgentBaseDefinition object itself. + */ + @Generated + public VoiceAgentBaseDefinition setStore(Boolean store) { + this.store = store; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentBaseDefinition setRaiConfig(RaiConfig raiConfig) { + super.setRaiConfig(raiConfig); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeJsonField("rai_config", getRaiConfig()); + jsonWriter.writeStringField("sub_protocol", this.subProtocol == null ? null : this.subProtocol.toString()); + jsonWriter.writeStringField("instructions", this.instructions); + jsonWriter.writeMapField("structured_inputs", this.structuredInputs, + (writer, element) -> writer.writeJson(element)); + jsonWriter.writeBooleanField("store", this.store); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentBaseDefinition from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentBaseDefinition if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentBaseDefinition. + */ + @Generated + public static VoiceAgentBaseDefinition fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("sub_protocol".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("realtime".equals(discriminatorValue)) { + return VoiceAgentDefinition.fromJson(readerToUse.reset()); + } else if ("live".equals(discriminatorValue)) { + return VoiceAgentLiveDefinition.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static VoiceAgentBaseDefinition fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentBaseDefinition deserializedVoiceAgentBaseDefinition = new VoiceAgentBaseDefinition(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("rai_config".equals(fieldName)) { + deserializedVoiceAgentBaseDefinition.setRaiConfig(RaiConfig.fromJson(reader)); + } else if ("sub_protocol".equals(fieldName)) { + deserializedVoiceAgentBaseDefinition.subProtocol + = VoiceAgentSubProtocol.fromString(reader.getString()); + } else if ("instructions".equals(fieldName)) { + deserializedVoiceAgentBaseDefinition.instructions = reader.getString(); + } else if ("structured_inputs".equals(fieldName)) { + Map structuredInputs + = reader.readMap(reader1 -> StructuredInputDefinition.fromJson(reader1)); + deserializedVoiceAgentBaseDefinition.structuredInputs = structuredInputs; + } else if ("store".equals(fieldName)) { + deserializedVoiceAgentBaseDefinition.store = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentBaseDefinition; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectDtmfSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectDtmfSystemTool.java new file mode 100644 index 0000000000000..95e0f62710328 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectDtmfSystemTool.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Collects keypad digits on the current call. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentCollectDtmfSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.COLLECT_DTMF; + + /** + * Creates an instance of VoiceAgentCollectDtmfSystemTool class. + */ + @Generated + public VoiceAgentCollectDtmfSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentCollectDtmfSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentCollectDtmfSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentCollectDtmfSystemTool if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentCollectDtmfSystemTool. + */ + @Generated + public static VoiceAgentCollectDtmfSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentCollectDtmfSystemTool deserializedVoiceAgentCollectDtmfSystemTool + = new VoiceAgentCollectDtmfSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentCollectDtmfSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentCollectDtmfSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentCollectDtmfSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentCollectDtmfSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentCollectDtmfSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectSmsSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectSmsSystemTool.java new file mode 100644 index 0000000000000..2144fa46a21fe --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentCollectSmsSystemTool.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Collects one complete SMS from an explicitly selected sender. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentCollectSmsSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.COLLECT_SMS; + + /** + * Creates an instance of VoiceAgentCollectSmsSystemTool class. + */ + @Generated + public VoiceAgentCollectSmsSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentCollectSmsSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentCollectSmsSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentCollectSmsSystemTool if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentCollectSmsSystemTool. + */ + @Generated + public static VoiceAgentCollectSmsSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentCollectSmsSystemTool deserializedVoiceAgentCollectSmsSystemTool + = new VoiceAgentCollectSmsSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentCollectSmsSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentCollectSmsSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentCollectSmsSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentCollectSmsSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentCollectSmsSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java index 6536283756c02..f6f5a534f1bf2 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java @@ -10,10 +10,6 @@ import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import java.io.IOException; import java.util.List; import java.util.Map; @@ -25,13 +21,13 @@ */ @Fluent @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class VoiceAgentDefinition extends AgentDefinition { +public final class VoiceAgentDefinition extends VoiceAgentBaseDefinition { /* * The kind property. */ @Generated - private AgentKind kind = AgentKind.VOICE; + private final AgentKind kind = AgentKind.VOICE; /* * How the model backing this voice agent is served. Required with `model` for a model-backed voice agent and @@ -58,13 +54,6 @@ public final class VoiceAgentDefinition extends AgentDefinition { @Generated private VoiceConversationEngine conversationEngine; - /* - * 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. - */ - @Generated - private String instructions; - /* * 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. @@ -132,25 +121,6 @@ public final class VoiceAgentDefinition extends AgentDefinition { @Generated private Boolean parallelToolCalls; - /* - * Set of structured inputs that participate in prompt template substitution, rendered per session before the live - * session starts. - */ - @Generated - private Map structuredInputs; - - /* - * 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. - */ - @Generated - private Boolean store; - /** * Creates an instance of VoiceAgentDefinition class. */ @@ -250,26 +220,12 @@ public VoiceAgentDefinition setConversationEngine(VoiceConversationEngine conver } /** - * Get the instructions property: 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. - * - * @return the instructions value. - */ - @Generated - public String getInstructions() { - return this.instructions; - } - - /** - * Set the instructions property: 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. - * - * @param instructions the instructions value to set. - * @return the VoiceAgentDefinition object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentDefinition setInstructions(String instructions) { - this.instructions = instructions; + super.setInstructions(instructions); return this; } @@ -327,9 +283,9 @@ public VoiceAgentDefinition setOutputModalities(List output * * @return the maxOutputTokens value. */ - BinaryData getMaxOutputTokens() { + public VoiceAgentMaxOutputTokens getMaxOutputTokens() { // AI Tooling: union type - return this.maxOutputTokens; + return this.maxOutputTokens == null ? null : this.maxOutputTokens.toObject(VoiceAgentMaxOutputTokens.class); } /** @@ -338,9 +294,9 @@ BinaryData getMaxOutputTokens() { * @param maxOutputTokens the maxOutputTokens value to set. * @return the VoiceAgentDefinition object itself. */ - VoiceAgentDefinition setMaxOutputTokens(BinaryData maxOutputTokens) { + public VoiceAgentDefinition setMaxOutputTokens(VoiceAgentMaxOutputTokens maxOutputTokens) { // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens; + this.maxOutputTokens = maxOutputTokens == null ? null : BinaryData.fromObject(maxOutputTokens); return this; } @@ -421,11 +377,10 @@ public VoiceAgentDefinition setTools(List tools) { * `required` requires at least one tool call, and a specific function or MCP tool can be selected with an object. * Defaults to `auto`. * - * @return the toolChoice value. + * @return the tool choice, or {@code null} when absent or JSON null. */ - BinaryData getToolChoice() { - // AI Tooling: union type - return this.toolChoice; + public VoiceAgentToolChoice getToolChoice() { + return this.toolChoice == null ? null : this.toolChoice.toObject(VoiceAgentToolChoice.class); } /** @@ -434,12 +389,11 @@ BinaryData getToolChoice() { * `required` requires at least one tool call, and a specific function or MCP tool can be selected with an object. * Defaults to `auto`. * - * @param toolChoice the toolChoice value to set. + * @param toolChoice the tool choice, or {@code null} to clear the property. * @return the VoiceAgentDefinition object itself. */ - VoiceAgentDefinition setToolChoice(BinaryData toolChoice) { - // AI Tooling: union type - this.toolChoice = toolChoice; + public VoiceAgentDefinition setToolChoice(VoiceAgentToolChoice toolChoice) { + this.toolChoice = toolChoice == null ? null : BinaryData.fromObject(toolChoice); return this; } @@ -466,62 +420,22 @@ public VoiceAgentDefinition setParallelToolCalls(Boolean parallelToolCalls) { } /** - * Get the structuredInputs property: Set of structured inputs that participate in prompt template substitution, - * rendered per session before the live session starts. - * - * @return the structuredInputs value. - */ - @Generated - public Map getStructuredInputs() { - return this.structuredInputs; - } - - /** - * Set the structuredInputs property: Set of structured inputs that participate in prompt template substitution, - * rendered per session before the live session starts. - * - * @param structuredInputs the structuredInputs value to set. - * @return the VoiceAgentDefinition object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentDefinition setStructuredInputs(Map structuredInputs) { - this.structuredInputs = structuredInputs; + super.setStructuredInputs(structuredInputs); return this; } /** - * Get the store property: 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. - * - * @return the store value. - */ - @Generated - public Boolean isStore() { - return this.store; - } - - /** - * Set the store property: 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. - * - * @param store the store value to set. - * @return the VoiceAgentDefinition object itself. + * {@inheritDoc} */ @Generated + @Override public VoiceAgentDefinition setStore(Boolean store) { - this.store = store; + super.setStore(store); return this; } @@ -542,12 +456,16 @@ public VoiceAgentDefinition setRaiConfig(RaiConfig raiConfig) { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("rai_config", getRaiConfig()); jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeJsonField("rai_config", getRaiConfig()); + jsonWriter.writeStringField("instructions", getInstructions()); + jsonWriter.writeMapField("structured_inputs", getStructuredInputs(), + (writer, element) -> writer.writeJson(element)); + jsonWriter.writeBooleanField("store", isStore()); + jsonWriter.writeStringField("sub_protocol", this.subProtocol == null ? null : this.subProtocol.toString()); jsonWriter.writeStringField("model_type", this.modelType == null ? null : this.modelType.toString()); jsonWriter.writeStringField("model", this.model); jsonWriter.writeJsonField("conversation_engine", this.conversationEngine); - jsonWriter.writeStringField("instructions", this.instructions); jsonWriter.writeJsonField("greeting", this.greeting); jsonWriter.writeJsonField("audio", this.audio); jsonWriter.writeJsonField("soundscape", this.soundscape); @@ -567,10 +485,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { this.toolChoice.writeTo(jsonWriter); } jsonWriter.writeBooleanField("parallel_tool_calls", this.parallelToolCalls); - jsonWriter.writeMapField("structured_inputs", this.structuredInputs, - (writer, element) -> writer.writeJson(element)); jsonWriter.writeJsonField("subagent_config", this.subagentConfiguration); - jsonWriter.writeBooleanField("store", this.store); + jsonWriter.writeJsonField("post_call", this.postCall); return jsonWriter.writeEndObject(); } @@ -591,16 +507,22 @@ public static VoiceAgentDefinition fromJson(JsonReader jsonReader) throws IOExce reader.nextToken(); if ("rai_config".equals(fieldName)) { deserializedVoiceAgentDefinition.setRaiConfig(RaiConfig.fromJson(reader)); - } else if ("kind".equals(fieldName)) { - deserializedVoiceAgentDefinition.kind = AgentKind.fromString(reader.getString()); + } else if ("instructions".equals(fieldName)) { + deserializedVoiceAgentDefinition.setInstructions(reader.getString()); + } else if ("structured_inputs".equals(fieldName)) { + Map structuredInputs + = reader.readMap(reader1 -> StructuredInputDefinition.fromJson(reader1)); + deserializedVoiceAgentDefinition.setStructuredInputs(structuredInputs); + } else if ("store".equals(fieldName)) { + deserializedVoiceAgentDefinition.setStore(reader.getNullable(JsonReader::getBoolean)); + } else if ("sub_protocol".equals(fieldName)) { + deserializedVoiceAgentDefinition.subProtocol = VoiceAgentSubProtocol.fromString(reader.getString()); } else if ("model_type".equals(fieldName)) { deserializedVoiceAgentDefinition.modelType = VoiceModelType.fromString(reader.getString()); } else if ("model".equals(fieldName)) { deserializedVoiceAgentDefinition.model = reader.getString(); } else if ("conversation_engine".equals(fieldName)) { deserializedVoiceAgentDefinition.conversationEngine = VoiceConversationEngine.fromJson(reader); - } else if ("instructions".equals(fieldName)) { - deserializedVoiceAgentDefinition.instructions = reader.getString(); } else if ("greeting".equals(fieldName)) { deserializedVoiceAgentDefinition.greeting = VoiceAgentGreetingConfiguration.fromJson(reader); } else if ("audio".equals(fieldName)) { @@ -631,15 +553,11 @@ public static VoiceAgentDefinition fromJson(JsonReader jsonReader) throws IOExce = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); } else if ("parallel_tool_calls".equals(fieldName)) { deserializedVoiceAgentDefinition.parallelToolCalls = reader.getNullable(JsonReader::getBoolean); - } else if ("structured_inputs".equals(fieldName)) { - Map structuredInputs - = reader.readMap(reader1 -> StructuredInputDefinition.fromJson(reader1)); - deserializedVoiceAgentDefinition.structuredInputs = structuredInputs; } else if ("subagent_config".equals(fieldName)) { deserializedVoiceAgentDefinition.subagentConfiguration = VoiceAgentSubagentConfiguration.fromJson(reader); - } else if ("store".equals(fieldName)) { - deserializedVoiceAgentDefinition.store = reader.getNullable(JsonReader::getBoolean); + } else if ("post_call".equals(fieldName)) { + deserializedVoiceAgentDefinition.postCall = VoiceAgentPostCallConfiguration.fromJson(reader); } else { reader.skipChildren(); } @@ -648,171 +566,9 @@ public static VoiceAgentDefinition fromJson(JsonReader jsonReader) throws IOExce }); } - /** - * Set the maxOutputTokens property: The maximum output-token count for one response. - * - * @param maxOutputTokens the maximum number of output tokens to set. - * @return the VoiceAgentDefinition object itself. - */ - public VoiceAgentDefinition setMaxOutputTokens(long maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Set the maxOutputTokens property: The maximum output-token count for one response. - * - * @param maxOutputTokens the token-limit string to set, for example {@code "inf"} for an unlimited count. - * @return the VoiceAgentDefinition object itself. - */ - public VoiceAgentDefinition setMaxOutputTokens(String maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens == null ? null : BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } - - /** - * Set the toolChoice property: How the model chooses tools for generated responses. - * - * @param toolChoice the {@link ToolChoiceOptions} mode to set ({@code NONE}, {@code AUTO} or {@code REQUIRED}). - * @return the VoiceAgentDefinition object itself. - */ - public VoiceAgentDefinition setToolChoice(ToolChoiceOptions toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Set the toolChoice property to a specific function tool: How the model chooses tools for generated responses. - * - * @param toolChoice the openai-java {@link ToolChoiceFunction} to set, or null to clear. - * @return the VoiceAgentDefinition object itself. - */ - public VoiceAgentDefinition setToolChoice(ToolChoiceFunction toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceFunction}: How the model chooses tools for - * generated responses. - * - * @return the toolChoice value as a ToolChoiceFunction, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceFunction getToolChoiceAsToolChoiceFunction() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isFunction()) { - return null; - } - return choice.asFunction(); - } - - /** - * Set the toolChoice property to a specific MCP tool: How the model chooses tools for generated responses. - * - * @param toolChoice the openai-java {@link ToolChoiceMcp} to set, or null to clear. - * @return the VoiceAgentDefinition object itself. - */ - public VoiceAgentDefinition setToolChoice(ToolChoiceMcp toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceMcp}: How the model chooses tools for generated - * responses. - * - * @return the toolChoice value as a ToolChoiceMcp, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceMcp getToolChoiceAsToolChoiceMcp() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isMcp()) { - return null; - } - return choice.asMcp(); - } - - private ResponseCreateParams.ToolChoice getOpenAIToolChoice() { - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!json.startsWith("{")) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ResponseCreateParams.ToolChoice.class); - } - - /** - * Get the toolChoice property: How the model chooses tools for generated responses. - * - * @return the toolChoice value as a {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another - * variant. - */ - public ToolChoiceOptions getToolChoiceAsToolChoiceOptions() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ToolChoiceOptions.class); - } - /* - * Optional configuration for sibling Foundry text agents that this voice agent may consult as background - * specialists. + * Optional subagent configuration. Set `subagent_type` to `delegate` for delegated background specialists or + * `inline` for inline voice subagents. */ @Generated private VoiceAgentSubagentConfiguration subagentConfiguration; @@ -870,8 +626,8 @@ public VoiceAgentDefinition setAvatar(VoiceAgentAvatarConfiguration avatar) { } /** - * Get the subagentConfiguration property: Optional configuration for sibling Foundry text agents that this voice - * agent may consult as background specialists. + * Get the subagentConfiguration property: Optional subagent configuration. Set `subagent_type` to `delegate` for + * delegated background specialists or `inline` for inline voice subagents. * * @return the subagentConfiguration value. */ @@ -881,8 +637,8 @@ public VoiceAgentSubagentConfiguration getSubagentConfiguration() { } /** - * Set the subagentConfiguration property: Optional configuration for sibling Foundry text agents that this voice - * agent may consult as background specialists. + * Set the subagentConfiguration property: Optional subagent configuration. Set `subagent_type` to `delegate` for + * delegated background specialists or `inline` for inline voice subagents. * * @param subagentConfiguration the subagentConfiguration value to set. * @return the VoiceAgentDefinition object itself. @@ -929,4 +685,52 @@ public VoiceAgentDefinition setSoundscape(VoiceAgentSoundscapeConfiguration soun this.soundscape = soundscape; return this; } + + /* + * Optional post-call delivery configuration. After each session ends, the service notifies the configured + * destinations. + */ + @Generated + private VoiceAgentPostCallConfiguration postCall; + + /** + * Get the postCall property: Optional post-call delivery configuration. After each session ends, the service + * notifies the configured destinations. + * + * @return the postCall value. + */ + @Generated + public VoiceAgentPostCallConfiguration getPostCall() { + return this.postCall; + } + + /** + * Set the postCall property: Optional post-call delivery configuration. After each session ends, the service + * notifies the configured destinations. + * + * @param postCall the postCall value to set. + * @return the VoiceAgentDefinition object itself. + */ + @Generated + public VoiceAgentDefinition setPostCall(VoiceAgentPostCallConfiguration postCall) { + this.postCall = postCall; + return this; + } + + /* + * The voice protocol for this agent version. Null and unknown values are invalid. + */ + @Generated + private VoiceAgentSubProtocol subProtocol = VoiceAgentSubProtocol.REALTIME; + + /** + * Get the subProtocol property: The voice protocol for this agent version. Null and unknown values are invalid. + * + * @return the subProtocol value. + */ + @Generated + @Override + public VoiceAgentSubProtocol getSubProtocol() { + return this.subProtocol; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDelegateSubagentConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDelegateSubagentConfiguration.java new file mode 100644 index 0000000000000..1a066ba32ad52 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDelegateSubagentConfiguration.java @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Configuration for referenced Foundry agents invoked as delegated background specialists. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentDelegateSubagentConfiguration extends VoiceAgentSubagentConfiguration { + + /* + * The subagent mode. + */ + @Generated + private VoiceAgentSubagentType subagentType = VoiceAgentSubagentType.DELEGATE; + + /* + * The sibling Foundry text agents, in the same project, that this Voice Agent may consult. + */ + @Generated + private final List subagents; + + /** + * Creates an instance of VoiceAgentDelegateSubagentConfiguration class. + * + * @param subagents the subagents value to set. + */ + @Generated + public VoiceAgentDelegateSubagentConfiguration(List subagents) { + this.subagents = subagents; + } + + /** + * Get the subagentType property: The subagent mode. + * + * @return the subagentType value. + */ + @Generated + @Override + public VoiceAgentSubagentType getSubagentType() { + return this.subagentType; + } + + /** + * Get the subagents property: The sibling Foundry text agents, in the same project, that this Voice Agent may + * consult. + * + * @return the subagents value. + */ + @Generated + public List getSubagents() { + return this.subagents; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeArrayField("subagents", this.subagents, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeStringField("subagent_type", this.subagentType == null ? null : this.subagentType.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentDelegateSubagentConfiguration from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentDelegateSubagentConfiguration if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentDelegateSubagentConfiguration. + */ + @Generated + public static VoiceAgentDelegateSubagentConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + List subagents = null; + VoiceAgentSubagentType subagentType = VoiceAgentSubagentType.DELEGATE; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("subagents".equals(fieldName)) { + subagents = reader.readArray(reader1 -> VoiceAgentSubagent.fromJson(reader1)); + } else if ("subagent_type".equals(fieldName)) { + subagentType = VoiceAgentSubagentType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentDelegateSubagentConfiguration deserializedVoiceAgentDelegateSubagentConfiguration + = new VoiceAgentDelegateSubagentConfiguration(subagents); + deserializedVoiceAgentDelegateSubagentConfiguration.subagentType = subagentType; + return deserializedVoiceAgentDelegateSubagentConfiguration; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDigitRecognitionSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDigitRecognitionSystemTool.java new file mode 100644 index 0000000000000..83fa72cfde260 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentDigitRecognitionSystemTool.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Retrieves the unchanged transcript of the last user audio turn. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentDigitRecognitionSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.DIGIT_RECOGNITION; + + /** + * Creates an instance of VoiceAgentDigitRecognitionSystemTool class. + */ + @Generated + public VoiceAgentDigitRecognitionSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentDigitRecognitionSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentDigitRecognitionSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentDigitRecognitionSystemTool if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentDigitRecognitionSystemTool. + */ + @Generated + public static VoiceAgentDigitRecognitionSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentDigitRecognitionSystemTool deserializedVoiceAgentDigitRecognitionSystemTool + = new VoiceAgentDigitRecognitionSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentDigitRecognitionSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentDigitRecognitionSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentDigitRecognitionSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentDigitRecognitionSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentDigitRecognitionSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java index 3e698b8ea098c..278fdd79ec5a5 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java @@ -10,6 +10,7 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import java.io.IOException; +import java.time.Duration; /** * A service-managed control that ends the active conversation. @@ -22,7 +23,7 @@ public final class VoiceAgentEndConversationSystemTool extends VoiceAgentSystemT * The tool kind. */ @Generated - private final String type = "system"; + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; /* * The service-managed control action. Known values are stable; additional values may be added over time. @@ -44,7 +45,7 @@ public VoiceAgentEndConversationSystemTool() { */ @Generated @Override - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -77,8 +78,11 @@ public VoiceAgentEndConversationSystemTool setDescription(String description) { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); return jsonWriter.writeEndObject(); } @@ -101,6 +105,11 @@ public static VoiceAgentEndConversationSystemTool fromJson(JsonReader jsonReader reader.nextToken(); if ("description".equals(fieldName)) { deserializedVoiceAgentEndConversationSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentEndConversationSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } } else if ("name".equals(fieldName)) { deserializedVoiceAgentEndConversationSystemTool.name = VoiceAgentSystemToolName.fromString(reader.getString()); @@ -111,4 +120,14 @@ public static VoiceAgentEndConversationSystemTool fromJson(JsonReader jsonReader return deserializedVoiceAgentEndConversationSystemTool; }); } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentEndConversationSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEventGridPostCallDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEventGridPostCallDestination.java new file mode 100644 index 0000000000000..1ae282a6aea48 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentEventGridPostCallDestination.java @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * An Event Grid connection that receives post-call events. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentEventGridPostCallDestination extends VoiceAgentPostCallDestination { + + /* + * The destination type. + */ + @Generated + private VoiceAgentPostCallDestinationType type = VoiceAgentPostCallDestinationType.EVENT_GRID; + + /* + * The name of the Event Grid connection. + */ + @Generated + private final String connectionName; + + /** + * Creates an instance of VoiceAgentEventGridPostCallDestination class. + * + * @param connectionName the connectionName value to set. + */ + @Generated + public VoiceAgentEventGridPostCallDestination(String connectionName) { + this.connectionName = connectionName; + } + + /** + * Get the type property: The destination type. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentPostCallDestinationType getType() { + return this.type; + } + + /** + * Get the connectionName property: The name of the Event Grid connection. + * + * @return the connectionName value. + */ + @Generated + public String getConnectionName() { + return this.connectionName; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("connection_name", this.connectionName); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentEventGridPostCallDestination from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentEventGridPostCallDestination if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentEventGridPostCallDestination. + */ + @Generated + public static VoiceAgentEventGridPostCallDestination fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String connectionName = null; + VoiceAgentPostCallDestinationType type = VoiceAgentPostCallDestinationType.EVENT_GRID; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("connection_name".equals(fieldName)) { + connectionName = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentPostCallDestinationType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentEventGridPostCallDestination deserializedVoiceAgentEventGridPostCallDestination + = new VoiceAgentEventGridPostCallDestination(connectionName); + deserializedVoiceAgentEventGridPostCallDestination.type = type; + return deserializedVoiceAgentEventGridPostCallDestination; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java index 68eeeb7bdc598..ba7767f6d86ed 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java @@ -23,7 +23,7 @@ public final class VoiceAgentFunctionTool extends VoiceAgentTool { * The tool kind. */ @Generated - private String type = "function"; + private VoiceAgentToolType type = VoiceAgentToolType.FUNCTION; /* * The description of the function, including guidance on when and how @@ -62,7 +62,7 @@ public VoiceAgentFunctionTool(String name) { */ @Generated @Override - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -132,7 +132,7 @@ public String getName() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("name", this.name); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("description", this.description); if (this.parameters != null) { jsonWriter.writeFieldName("parameters"); @@ -154,7 +154,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static VoiceAgentFunctionTool fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String name = null; - String type = "function"; + VoiceAgentToolType type = VoiceAgentToolType.FUNCTION; String description = null; BinaryData parameters = null; while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -163,7 +163,7 @@ public static VoiceAgentFunctionTool fromJson(JsonReader jsonReader) throws IOEx if ("name".equals(fieldName)) { name = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentToolType.fromString(reader.getString()); } else if ("description".equals(fieldName)) { description = reader.getString(); } else if ("parameters".equals(fieldName)) { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java index d549290ea6240..dfaae1f58340d 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java @@ -23,7 +23,7 @@ public class VoiceAgentGreetingConfiguration implements JsonSerializable { + + /** + * Speak a deterministic greeting rendered from a text template. + */ + @Generated + public static final VoiceAgentGreetingMode TEMPLATE = fromString("template"); + + /** + * Generate the greeting with the session model from an opening-turn prompt. + */ + @Generated + public static final VoiceAgentGreetingMode LLM_GENERATED = fromString("llm_generated"); + + /** + * Creates a new instance of VoiceAgentGreetingMode value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentGreetingMode() { + } + + /** + * Creates or finds a VoiceAgentGreetingMode from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentGreetingMode. + */ + @Generated + public static VoiceAgentGreetingMode fromString(String name) { + return fromString(name, VoiceAgentGreetingMode.class); + } + + /** + * Gets known VoiceAgentGreetingMode values. + * + * @return known VoiceAgentGreetingMode values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentGreetingMode.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffAbortReason.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffAbortReason.java new file mode 100644 index 0000000000000..23c1e690e5361 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffAbortReason.java @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Why a server-managed handoff ended before target commit. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentHandoffAbortReason { + + /** + * Enum value user_interruption. + */ + USER_INTERRUPTION("user_interruption"), + /** + * Enum value error. + */ + ERROR("error"); + + /** + * The actual serialized value for a VoiceAgentHandoffAbortReason instance. + */ + private final String value; + + VoiceAgentHandoffAbortReason(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentHandoffAbortReason instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentHandoffAbortReason object, or null if unable to parse. + */ + public static VoiceAgentHandoffAbortReason fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentHandoffAbortReason[] items = VoiceAgentHandoffAbortReason.values(); + for (VoiceAgentHandoffAbortReason item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffCondition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffCondition.java new file mode 100644 index 0000000000000..720eeaa8245f2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffCondition.java @@ -0,0 +1,290 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * One allowed outgoing handoff from an inline voice subagent. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentHandoffCondition implements JsonSerializable { + + /* + * The handoff condition identifier. + */ + @Generated + private final String id; + + /* + * The target subagent identifier or `$entrypoint`. The containing subagent supplies the source. + */ + @Generated + private final String target; + + /* + * Natural-language routing guidance supplied alongside the active subagent instructions, from 1 through 500 + * characters. This is not an executable Boolean predicate. + */ + @Generated + private final String condition; + + /* + * Whether user interruption before commit cancels the pending handoff. If omitted, the service defaults to false. + */ + @Generated + private Boolean cancelOnInterruption; + + /* + * The minimum delay before target activation, in milliseconds, from 0 through 10000. If omitted, the service + * defaults to 0. + */ + @Generated + private Long delay; + + /* + * Optional deterministic source-voice announcement played before target activation. Supported by cascaded + * pipelines and realtime pipelines using local Azure TTS; model-native realtime voice requires omission or null. + * At most 500 characters. If omitted or null, no announcement is played. + */ + @Generated + private String transferMessage; + + /* + * Whether Voice Live automatically starts a response after target activation. If omitted, the service defaults to + * `auto`. + */ + @Generated + private VoiceAgentHandoffTargetResponse targetResponse; + + /** + * Creates an instance of VoiceAgentHandoffCondition class. + * + * @param id the id value to set. + * @param target the target value to set. + * @param condition the condition value to set. + */ + @Generated + public VoiceAgentHandoffCondition(String id, String target, String condition) { + this.id = id; + this.target = target; + this.condition = condition; + } + + /** + * Get the id property: The handoff condition identifier. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the target property: The target subagent identifier or `$entrypoint`. The containing subagent supplies the + * source. + * + * @return the target value. + */ + @Generated + public String getTarget() { + return this.target; + } + + /** + * Get the condition property: Natural-language routing guidance supplied alongside the active subagent + * instructions, from 1 through 500 characters. This is not an executable Boolean predicate. + * + * @return the condition value. + */ + @Generated + public String getCondition() { + return this.condition; + } + + /** + * Get the cancelOnInterruption property: Whether user interruption before commit cancels the pending handoff. If + * omitted, the service defaults to false. + * + * @return the cancelOnInterruption value. + */ + @Generated + public Boolean isCancelOnInterruption() { + return this.cancelOnInterruption; + } + + /** + * Set the cancelOnInterruption property: Whether user interruption before commit cancels the pending handoff. If + * omitted, the service defaults to false. + * + * @param cancelOnInterruption the cancelOnInterruption value to set. + * @return the VoiceAgentHandoffCondition object itself. + */ + @Generated + public VoiceAgentHandoffCondition setCancelOnInterruption(Boolean cancelOnInterruption) { + this.cancelOnInterruption = cancelOnInterruption; + return this; + } + + /** + * Get the delay property: The minimum delay before target activation, in milliseconds, from 0 through 10000. If + * omitted, the service defaults to 0. + * + * @return the delay value. + */ + @Generated + public Duration getDelay() { + if (this.delay == null) { + return null; + } + return Duration.ofMillis(this.delay); + } + + /** + * Set the delay property: The minimum delay before target activation, in milliseconds, from 0 through 10000. If + * omitted, the service defaults to 0. + * + * @param delay the delay value to set. + * @return the VoiceAgentHandoffCondition object itself. + */ + @Generated + public VoiceAgentHandoffCondition setDelay(Duration delay) { + if (delay == null) { + this.delay = null; + } else { + this.delay = delay.toMillis(); + } + return this; + } + + /** + * Get the transferMessage property: Optional deterministic source-voice announcement played before target + * activation. Supported by cascaded + * pipelines and realtime pipelines using local Azure TTS; model-native realtime voice requires omission or null. + * At most 500 characters. If omitted or null, no announcement is played. + * + * @return the transferMessage value. + */ + @Generated + public String getTransferMessage() { + return this.transferMessage; + } + + /** + * Set the transferMessage property: Optional deterministic source-voice announcement played before target + * activation. Supported by cascaded + * pipelines and realtime pipelines using local Azure TTS; model-native realtime voice requires omission or null. + * At most 500 characters. If omitted or null, no announcement is played. + * + * @param transferMessage the transferMessage value to set. + * @return the VoiceAgentHandoffCondition object itself. + */ + @Generated + public VoiceAgentHandoffCondition setTransferMessage(String transferMessage) { + this.transferMessage = transferMessage; + return this; + } + + /** + * Get the targetResponse property: Whether Voice Live automatically starts a response after target activation. If + * omitted, the service defaults to `auto`. + * + * @return the targetResponse value. + */ + @Generated + public VoiceAgentHandoffTargetResponse getTargetResponse() { + return this.targetResponse; + } + + /** + * Set the targetResponse property: Whether Voice Live automatically starts a response after target activation. If + * omitted, the service defaults to `auto`. + * + * @param targetResponse the targetResponse value to set. + * @return the VoiceAgentHandoffCondition object itself. + */ + @Generated + public VoiceAgentHandoffCondition setTargetResponse(VoiceAgentHandoffTargetResponse targetResponse) { + this.targetResponse = targetResponse; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("target", this.target); + jsonWriter.writeStringField("condition", this.condition); + jsonWriter.writeBooleanField("cancel_on_interruption", this.cancelOnInterruption); + jsonWriter.writeNumberField("delay_ms", this.delay); + jsonWriter.writeStringField("transfer_message", this.transferMessage); + jsonWriter.writeStringField("target_response", + this.targetResponse == null ? null : this.targetResponse.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentHandoffCondition from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentHandoffCondition if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffCondition. + */ + @Generated + public static VoiceAgentHandoffCondition fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String target = null; + String condition = null; + Boolean cancelOnInterruption = null; + Long delay = null; + String transferMessage = null; + VoiceAgentHandoffTargetResponse targetResponse = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("target".equals(fieldName)) { + target = reader.getString(); + } else if ("condition".equals(fieldName)) { + condition = reader.getString(); + } else if ("cancel_on_interruption".equals(fieldName)) { + cancelOnInterruption = reader.getNullable(JsonReader::getBoolean); + } else if ("delay_ms".equals(fieldName)) { + delay = reader.getNullable(JsonReader::getLong); + } else if ("transfer_message".equals(fieldName)) { + transferMessage = reader.getString(); + } else if ("target_response".equals(fieldName)) { + targetResponse = VoiceAgentHandoffTargetResponse.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentHandoffCondition deserializedVoiceAgentHandoffCondition + = new VoiceAgentHandoffCondition(id, target, condition); + deserializedVoiceAgentHandoffCondition.cancelOnInterruption = cancelOnInterruption; + deserializedVoiceAgentHandoffCondition.delay = delay; + deserializedVoiceAgentHandoffCondition.transferMessage = transferMessage; + deserializedVoiceAgentHandoffCondition.targetResponse = targetResponse; + return deserializedVoiceAgentHandoffCondition; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffEdgeState.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffEdgeState.java new file mode 100644 index 0000000000000..1e2087b70a6fc --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffEdgeState.java @@ -0,0 +1,219 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Non-sensitive topology metadata for one compiled handoff edge. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentHandoffEdgeState implements JsonSerializable { + + /* + * The edge identifier. + */ + @Generated + private final String id; + + /* + * The source node identifier or `$entrypoint`. + */ + @Generated + private final String source; + + /* + * The target node identifier or `$entrypoint`. + */ + @Generated + private final String target; + + /* + * Whether user interruption before commit cancels the pending handoff. + */ + @Generated + private Boolean cancelOnInterruption; + + /* + * The minimum delay before target activation, in milliseconds. + */ + @Generated + private Long delay; + + /* + * The deterministic source-voice announcement played before target activation. + */ + @Generated + private String transferMessage; + + /* + * Whether Voice Live automatically starts a response after target activation. + */ + @Generated + private VoiceAgentHandoffTargetResponse targetResponse; + + /** + * Creates an instance of VoiceAgentHandoffEdgeState class. + * + * @param id the id value to set. + * @param source the source value to set. + * @param target the target value to set. + */ + @Generated + private VoiceAgentHandoffEdgeState(String id, String source, String target) { + this.id = id; + this.source = source; + this.target = target; + } + + /** + * Get the id property: The edge identifier. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the source property: The source node identifier or `$entrypoint`. + * + * @return the source value. + */ + @Generated + public String getSource() { + return this.source; + } + + /** + * Get the target property: The target node identifier or `$entrypoint`. + * + * @return the target value. + */ + @Generated + public String getTarget() { + return this.target; + } + + /** + * Get the cancelOnInterruption property: Whether user interruption before commit cancels the pending handoff. + * + * @return the cancelOnInterruption value. + */ + @Generated + public Boolean isCancelOnInterruption() { + return this.cancelOnInterruption; + } + + /** + * Get the delay property: The minimum delay before target activation, in milliseconds. + * + * @return the delay value. + */ + @Generated + public Duration getDelay() { + if (this.delay == null) { + return null; + } + return Duration.ofMillis(this.delay); + } + + /** + * Get the transferMessage property: The deterministic source-voice announcement played before target activation. + * + * @return the transferMessage value. + */ + @Generated + public String getTransferMessage() { + return this.transferMessage; + } + + /** + * Get the targetResponse property: Whether Voice Live automatically starts a response after target activation. + * + * @return the targetResponse value. + */ + @Generated + public VoiceAgentHandoffTargetResponse getTargetResponse() { + return this.targetResponse; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("source", this.source); + jsonWriter.writeStringField("target", this.target); + jsonWriter.writeBooleanField("cancel_on_interruption", this.cancelOnInterruption); + jsonWriter.writeNumberField("delay_ms", this.delay); + jsonWriter.writeStringField("transfer_message", this.transferMessage); + jsonWriter.writeStringField("target_response", + this.targetResponse == null ? null : this.targetResponse.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentHandoffEdgeState from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentHandoffEdgeState if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffEdgeState. + */ + @Generated + public static VoiceAgentHandoffEdgeState fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String source = null; + String target = null; + Boolean cancelOnInterruption = null; + Long delay = null; + String transferMessage = null; + VoiceAgentHandoffTargetResponse targetResponse = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("source".equals(fieldName)) { + source = reader.getString(); + } else if ("target".equals(fieldName)) { + target = reader.getString(); + } else if ("cancel_on_interruption".equals(fieldName)) { + cancelOnInterruption = reader.getNullable(JsonReader::getBoolean); + } else if ("delay_ms".equals(fieldName)) { + delay = reader.getNullable(JsonReader::getLong); + } else if ("transfer_message".equals(fieldName)) { + transferMessage = reader.getString(); + } else if ("target_response".equals(fieldName)) { + targetResponse = VoiceAgentHandoffTargetResponse.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentHandoffEdgeState deserializedVoiceAgentHandoffEdgeState + = new VoiceAgentHandoffEdgeState(id, source, target); + deserializedVoiceAgentHandoffEdgeState.cancelOnInterruption = cancelOnInterruption; + deserializedVoiceAgentHandoffEdgeState.delay = delay; + deserializedVoiceAgentHandoffEdgeState.transferMessage = transferMessage; + deserializedVoiceAgentHandoffEdgeState.targetResponse = targetResponse; + return deserializedVoiceAgentHandoffEdgeState; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffNodeState.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffNodeState.java new file mode 100644 index 0000000000000..25d34849f5525 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffNodeState.java @@ -0,0 +1,129 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Non-sensitive topology metadata for one compiled handoff node. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentHandoffNodeState implements JsonSerializable { + + /* + * The node identifier or `$entrypoint`. + */ + @Generated + private final String id; + + /* + * The display-only node description. This value is not provided to the model. + */ + @Generated + private final String displayDescription; + + /* + * Whether this is the implicit `$entrypoint` node. + */ + @Generated + private Boolean implicit; + + /** + * Creates an instance of VoiceAgentHandoffNodeState class. + * + * @param id the id value to set. + * @param displayDescription the displayDescription value to set. + */ + @Generated + private VoiceAgentHandoffNodeState(String id, String displayDescription) { + this.id = id; + this.displayDescription = displayDescription; + } + + /** + * Get the id property: The node identifier or `$entrypoint`. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the displayDescription property: The display-only node description. This value is not provided to the model. + * + * @return the displayDescription value. + */ + @Generated + public String getDisplayDescription() { + return this.displayDescription; + } + + /** + * Get the implicit property: Whether this is the implicit `$entrypoint` node. + * + * @return the implicit value. + */ + @Generated + public Boolean isImplicit() { + return this.implicit; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("description", this.displayDescription); + jsonWriter.writeBooleanField("implicit", this.implicit); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentHandoffNodeState from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentHandoffNodeState if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffNodeState. + */ + @Generated + public static VoiceAgentHandoffNodeState fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + String displayDescription = null; + Boolean implicit = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("description".equals(fieldName)) { + displayDescription = reader.getString(); + } else if ("implicit".equals(fieldName)) { + implicit = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + VoiceAgentHandoffNodeState deserializedVoiceAgentHandoffNodeState + = new VoiceAgentHandoffNodeState(id, displayDescription); + deserializedVoiceAgentHandoffNodeState.implicit = implicit; + return deserializedVoiceAgentHandoffNodeState; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPipelineFamily.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPipelineFamily.java new file mode 100644 index 0000000000000..8249f01672952 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPipelineFamily.java @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * The immutable pipeline family selected for a voice-agent handoff graph. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentHandoffPipelineFamily { + + /** + * Enum value cascaded. + */ + CASCADED("cascaded"), + /** + * Enum value realtime. + */ + REALTIME("realtime"); + + /** + * The actual serialized value for a VoiceAgentHandoffPipelineFamily instance. + */ + private final String value; + + VoiceAgentHandoffPipelineFamily(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentHandoffPipelineFamily instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentHandoffPipelineFamily object, or null if unable to parse. + */ + public static VoiceAgentHandoffPipelineFamily fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentHandoffPipelineFamily[] items = VoiceAgentHandoffPipelineFamily.values(); + for (VoiceAgentHandoffPipelineFamily item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPolicy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPolicy.java new file mode 100644 index 0000000000000..63975238459f4 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPolicy.java @@ -0,0 +1,129 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Session-wide limits shared by all handoff conditions in one Voice Agent session. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentHandoffPolicy implements JsonSerializable { + + /* + * The maximum number of successfully completed handoffs in one session, from 1 through 100. If omitted, the service + * defaults to 16. + */ + @Generated + private Integer maxTransfers; + + /* + * The maximum number of attempted handoffs, from 1 through 100. If omitted, the service uses `max_transfers`. The + * service requires this value to be greater than or equal to `max_transfers`. + */ + @Generated + private Integer maxAttempts; + + /** + * Creates an instance of VoiceAgentHandoffPolicy class. + */ + @Generated + public VoiceAgentHandoffPolicy() { + } + + /** + * Get the maxTransfers property: The maximum number of successfully completed handoffs in one session, from 1 + * through 100. If omitted, the service defaults to 16. + * + * @return the maxTransfers value. + */ + @Generated + public Integer getMaxTransfers() { + return this.maxTransfers; + } + + /** + * Set the maxTransfers property: The maximum number of successfully completed handoffs in one session, from 1 + * through 100. If omitted, the service defaults to 16. + * + * @param maxTransfers the maxTransfers value to set. + * @return the VoiceAgentHandoffPolicy object itself. + */ + @Generated + public VoiceAgentHandoffPolicy setMaxTransfers(Integer maxTransfers) { + this.maxTransfers = maxTransfers; + return this; + } + + /** + * Get the maxAttempts property: The maximum number of attempted handoffs, from 1 through 100. If omitted, the + * service uses `max_transfers`. The service requires this value to be greater than or equal to `max_transfers`. + * + * @return the maxAttempts value. + */ + @Generated + public Integer getMaxAttempts() { + return this.maxAttempts; + } + + /** + * Set the maxAttempts property: The maximum number of attempted handoffs, from 1 through 100. If omitted, the + * service uses `max_transfers`. The service requires this value to be greater than or equal to `max_transfers`. + * + * @param maxAttempts the maxAttempts value to set. + * @return the VoiceAgentHandoffPolicy object itself. + */ + @Generated + public VoiceAgentHandoffPolicy setMaxAttempts(Integer maxAttempts) { + this.maxAttempts = maxAttempts; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeNumberField("max_transfers", this.maxTransfers); + jsonWriter.writeNumberField("max_attempts", this.maxAttempts); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentHandoffPolicy from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentHandoffPolicy if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffPolicy. + */ + @Generated + public static VoiceAgentHandoffPolicy fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentHandoffPolicy deserializedVoiceAgentHandoffPolicy = new VoiceAgentHandoffPolicy(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("max_transfers".equals(fieldName)) { + deserializedVoiceAgentHandoffPolicy.maxTransfers = reader.getNullable(JsonReader::getInt); + } else if ("max_attempts".equals(fieldName)) { + deserializedVoiceAgentHandoffPolicy.maxAttempts = reader.getNullable(JsonReader::getInt); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentHandoffPolicy; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffReasoningEffort.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffReasoningEffort.java new file mode 100644 index 0000000000000..ad29c2a6fb263 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffReasoningEffort.java @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Reasoning effort applied by a compatible handoff-node model. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentHandoffReasoningEffort { + + /** + * Enum value none. + */ + NONE("none"), + /** + * Enum value minimal. + */ + MINIMAL("minimal"), + /** + * Enum value low. + */ + LOW("low"), + /** + * Enum value medium. + */ + MEDIUM("medium"), + /** + * Enum value high. + */ + HIGH("high"), + /** + * Enum value xhigh. + */ + XHIGH("xhigh"); + + /** + * The actual serialized value for a VoiceAgentHandoffReasoningEffort instance. + */ + private final String value; + + VoiceAgentHandoffReasoningEffort(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentHandoffReasoningEffort instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentHandoffReasoningEffort object, or null if unable to parse. + */ + public static VoiceAgentHandoffReasoningEffort fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentHandoffReasoningEffort[] items = VoiceAgentHandoffReasoningEffort.values(); + for (VoiceAgentHandoffReasoningEffort item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffState.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffState.java new file mode 100644 index 0000000000000..f4896abba92cb --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffState.java @@ -0,0 +1,269 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * The effective topology and runtime state of a voice-agent handoff graph. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentHandoffState implements JsonSerializable { + + /* + * The immutable execution pipeline family. + */ + @Generated + private final VoiceAgentHandoffPipelineFamily pipelineFamily; + + /* + * The currently committed node identifier or `$entrypoint`. + */ + @Generated + private final String activeNodeId; + + /* + * The monotonically increasing generation of the committed active-node configuration. + */ + @Generated + private final int nodeGeneration; + + /* + * The number of successfully completed handoffs. + */ + @Generated + private final int transferCount; + + /* + * The number of unique reserved handoff attempts. + */ + @Generated + private final int attemptCount; + + /* + * The edge identifiers currently available from the active node. + */ + @Generated + private final List availableEdgeIds; + + /* + * The generated handoff function visible to the active model, or null when no route is available. + */ + @Generated + private final VoiceAgentFunctionTool transferTool; + + /* + * The compiled handoff nodes, including the implicit or explicit `$entrypoint`. + */ + @Generated + private final List nodes; + + /* + * The compiled handoff edges. + */ + @Generated + private final List edges; + + /** + * Creates an instance of VoiceAgentHandoffState class. + * + * @param pipelineFamily the pipelineFamily value to set. + * @param activeNodeId the activeNodeId value to set. + * @param nodeGeneration the nodeGeneration value to set. + * @param transferCount the transferCount value to set. + * @param attemptCount the attemptCount value to set. + * @param availableEdgeIds the availableEdgeIds value to set. + * @param transferTool the transferTool value to set. + * @param nodes the nodes value to set. + * @param edges the edges value to set. + */ + @Generated + private VoiceAgentHandoffState(VoiceAgentHandoffPipelineFamily pipelineFamily, String activeNodeId, + int nodeGeneration, int transferCount, int attemptCount, List availableEdgeIds, + VoiceAgentFunctionTool transferTool, List nodes, + List edges) { + this.pipelineFamily = pipelineFamily; + this.activeNodeId = activeNodeId; + this.nodeGeneration = nodeGeneration; + this.transferCount = transferCount; + this.attemptCount = attemptCount; + this.availableEdgeIds = availableEdgeIds; + this.transferTool = transferTool; + this.nodes = nodes; + this.edges = edges; + } + + /** + * Get the pipelineFamily property: The immutable execution pipeline family. + * + * @return the pipelineFamily value. + */ + @Generated + public VoiceAgentHandoffPipelineFamily getPipelineFamily() { + return this.pipelineFamily; + } + + /** + * Get the activeNodeId property: The currently committed node identifier or `$entrypoint`. + * + * @return the activeNodeId value. + */ + @Generated + public String getActiveNodeId() { + return this.activeNodeId; + } + + /** + * Get the nodeGeneration property: The monotonically increasing generation of the committed active-node + * configuration. + * + * @return the nodeGeneration value. + */ + @Generated + public int getNodeGeneration() { + return this.nodeGeneration; + } + + /** + * Get the transferCount property: The number of successfully completed handoffs. + * + * @return the transferCount value. + */ + @Generated + public int getTransferCount() { + return this.transferCount; + } + + /** + * Get the attemptCount property: The number of unique reserved handoff attempts. + * + * @return the attemptCount value. + */ + @Generated + public int getAttemptCount() { + return this.attemptCount; + } + + /** + * Get the availableEdgeIds property: The edge identifiers currently available from the active node. + * + * @return the availableEdgeIds value. + */ + @Generated + public List getAvailableEdgeIds() { + return this.availableEdgeIds; + } + + /** + * Get the transferTool property: The generated handoff function visible to the active model, or null when no route + * is available. + * + * @return the transferTool value. + */ + @Generated + public VoiceAgentFunctionTool getTransferTool() { + return this.transferTool; + } + + /** + * Get the nodes property: The compiled handoff nodes, including the implicit or explicit `$entrypoint`. + * + * @return the nodes value. + */ + @Generated + public List getNodes() { + return this.nodes; + } + + /** + * Get the edges property: The compiled handoff edges. + * + * @return the edges value. + */ + @Generated + public List getEdges() { + return this.edges; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("pipeline_family", + this.pipelineFamily == null ? null : this.pipelineFamily.toString()); + jsonWriter.writeStringField("active_node_id", this.activeNodeId); + jsonWriter.writeIntField("node_generation", this.nodeGeneration); + jsonWriter.writeIntField("transfer_count", this.transferCount); + jsonWriter.writeIntField("attempt_count", this.attemptCount); + jsonWriter.writeArrayField("available_edge_ids", this.availableEdgeIds, + (writer, element) -> writer.writeString(element)); + jsonWriter.writeJsonField("transfer_tool", this.transferTool); + jsonWriter.writeArrayField("nodes", this.nodes, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeArrayField("edges", this.edges, (writer, element) -> writer.writeJson(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentHandoffState from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentHandoffState if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffState. + */ + @Generated + public static VoiceAgentHandoffState fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentHandoffPipelineFamily pipelineFamily = null; + String activeNodeId = null; + int nodeGeneration = 0; + int transferCount = 0; + int attemptCount = 0; + List availableEdgeIds = null; + VoiceAgentFunctionTool transferTool = null; + List nodes = null; + List edges = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("pipeline_family".equals(fieldName)) { + pipelineFamily = VoiceAgentHandoffPipelineFamily.fromString(reader.getString()); + } else if ("active_node_id".equals(fieldName)) { + activeNodeId = reader.getString(); + } else if ("node_generation".equals(fieldName)) { + nodeGeneration = reader.getInt(); + } else if ("transfer_count".equals(fieldName)) { + transferCount = reader.getInt(); + } else if ("attempt_count".equals(fieldName)) { + attemptCount = reader.getInt(); + } else if ("available_edge_ids".equals(fieldName)) { + availableEdgeIds = reader.readArray(reader1 -> reader1.getString()); + } else if ("transfer_tool".equals(fieldName)) { + transferTool = VoiceAgentFunctionTool.fromJson(reader); + } else if ("nodes".equals(fieldName)) { + nodes = reader.readArray(reader1 -> VoiceAgentHandoffNodeState.fromJson(reader1)); + } else if ("edges".equals(fieldName)) { + edges = reader.readArray(reader1 -> VoiceAgentHandoffEdgeState.fromJson(reader1)); + } else { + reader.skipChildren(); + } + } + return new VoiceAgentHandoffState(pipelineFamily, activeNodeId, nodeGeneration, transferCount, attemptCount, + availableEdgeIds, transferTool, nodes, edges); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffTargetResponse.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffTargetResponse.java new file mode 100644 index 0000000000000..028167bbcd4a3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffTargetResponse.java @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Whether Voice Live automatically starts a response after a handoff target becomes active. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentHandoffTargetResponse { + + /** + * Enum value auto. + */ + AUTO("auto"), + /** + * Enum value none. + */ + NONE("none"); + + /** + * The actual serialized value for a VoiceAgentHandoffTargetResponse instance. + */ + private final String value; + + VoiceAgentHandoffTargetResponse(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentHandoffTargetResponse instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentHandoffTargetResponse object, or null if unable to parse. + */ + public static VoiceAgentHandoffTargetResponse fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentHandoffTargetResponse[] items = VoiceAgentHandoffTargetResponse.values(); + for (VoiceAgentHandoffTargetResponse item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptionLanguage.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffVoiceAdaptation.java similarity index 52% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptionLanguage.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffVoiceAdaptation.java index 513e649c333f2..3c67dfd521a4e 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TranscriptionLanguage.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffVoiceAdaptation.java @@ -13,36 +13,33 @@ import java.io.IOException; /** - * A language detected in transcribed audio. + * Voice-optimized instruction adaptation applied while a handoff node is active. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TranscriptionLanguage implements JsonSerializable { +public final class VoiceAgentHandoffVoiceAdaptation implements JsonSerializable { /* - * The code of a language detected in the audio. + * The adaptation strategy. Currently only `auto` is supported. */ @Generated - private final String code; + private final String type = "auto"; /** - * Creates an instance of TranscriptionLanguage class. - * - * @param code the code value to set. + * Creates an instance of VoiceAgentHandoffVoiceAdaptation class. */ @Generated - private TranscriptionLanguage(String code) { - this.code = code; + public VoiceAgentHandoffVoiceAdaptation() { } /** - * Get the code property: The code of a language detected in the audio. + * Get the type property: The adaptation strategy. Currently only `auto` is supported. * - * @return the code value. + * @return the type value. */ @Generated - public String getCode() { - return this.code; + public String getType() { + return this.type; } /** @@ -52,33 +49,30 @@ public String getCode() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("code", this.code); + jsonWriter.writeStringField("type", this.type); return jsonWriter.writeEndObject(); } /** - * Reads an instance of TranscriptionLanguage from the JsonReader. + * Reads an instance of VoiceAgentHandoffVoiceAdaptation from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of TranscriptionLanguage if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. + * @return An instance of VoiceAgentHandoffVoiceAdaptation if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TranscriptionLanguage. + * @throws IOException If an error occurs while reading the VoiceAgentHandoffVoiceAdaptation. */ @Generated - public static TranscriptionLanguage fromJson(JsonReader jsonReader) throws IOException { + public static VoiceAgentHandoffVoiceAdaptation fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - String code = null; + VoiceAgentHandoffVoiceAdaptation deserializedVoiceAgentHandoffVoiceAdaptation + = new VoiceAgentHandoffVoiceAdaptation(); while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("code".equals(fieldName)) { - code = reader.getString(); - } else { - reader.skipChildren(); - } + reader.skipChildren(); } - return new TranscriptionLanguage(code); + return deserializedVoiceAgentHandoffVoiceAdaptation; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInlineSubagentConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInlineSubagentConfiguration.java new file mode 100644 index 0000000000000..cfd4edde27ef8 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInlineSubagentConfiguration.java @@ -0,0 +1,149 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Configuration for inline voice subagents that may become active through Handoff. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentInlineSubagentConfiguration extends VoiceAgentSubagentConfiguration { + + /* + * The subagent mode. + */ + @Generated + private VoiceAgentSubagentType subagentType = VoiceAgentSubagentType.INLINE; + + /* + * Inline voice subagents owned and versioned with the parent Voice Agent. `$entrypoint` must be first, followed + * by at least one specialist and at most 31 additional subagents. Each subagent declares its outgoing + * `handoff_conditions`; condition identifiers and the 128-condition limit apply across the entire Agent. + */ + @Generated + private final List subagents; + + /* + * Session-wide Handoff limits. Requires `$entrypoint` with at least one outgoing condition. When omitted, the + * service permits up to 16 completed and 16 attempted handoffs. + */ + @Generated + private VoiceAgentHandoffPolicy handoffPolicy; + + /** + * Creates an instance of VoiceAgentInlineSubagentConfiguration class. + * + * @param subagents the subagents value to set. + */ + @Generated + public VoiceAgentInlineSubagentConfiguration(List subagents) { + this.subagents = subagents; + } + + /** + * Get the subagentType property: The subagent mode. + * + * @return the subagentType value. + */ + @Generated + @Override + public VoiceAgentSubagentType getSubagentType() { + return this.subagentType; + } + + /** + * Get the subagents property: Inline voice subagents owned and versioned with the parent Voice Agent. `$entrypoint` + * must be first, followed + * by at least one specialist and at most 31 additional subagents. Each subagent declares its outgoing + * `handoff_conditions`; condition identifiers and the 128-condition limit apply across the entire Agent. + * + * @return the subagents value. + */ + @Generated + public List getSubagents() { + return this.subagents; + } + + /** + * Get the handoffPolicy property: Session-wide Handoff limits. Requires `$entrypoint` with at least one outgoing + * condition. When omitted, the service permits up to 16 completed and 16 attempted handoffs. + * + * @return the handoffPolicy value. + */ + @Generated + public VoiceAgentHandoffPolicy getHandoffPolicy() { + return this.handoffPolicy; + } + + /** + * Set the handoffPolicy property: Session-wide Handoff limits. Requires `$entrypoint` with at least one outgoing + * condition. When omitted, the service permits up to 16 completed and 16 attempted handoffs. + * + * @param handoffPolicy the handoffPolicy value to set. + * @return the VoiceAgentInlineSubagentConfiguration object itself. + */ + @Generated + public VoiceAgentInlineSubagentConfiguration setHandoffPolicy(VoiceAgentHandoffPolicy handoffPolicy) { + this.handoffPolicy = handoffPolicy; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeArrayField("subagents", this.subagents, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeStringField("subagent_type", this.subagentType == null ? null : this.subagentType.toString()); + jsonWriter.writeJsonField("handoff_policy", this.handoffPolicy); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentInlineSubagentConfiguration from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentInlineSubagentConfiguration if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentInlineSubagentConfiguration. + */ + @Generated + public static VoiceAgentInlineSubagentConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + List subagents = null; + VoiceAgentSubagentType subagentType = VoiceAgentSubagentType.INLINE; + VoiceAgentHandoffPolicy handoffPolicy = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("subagents".equals(fieldName)) { + subagents = reader.readArray(reader1 -> InlineVoiceSubagent.fromJson(reader1)); + } else if ("subagent_type".equals(fieldName)) { + subagentType = VoiceAgentSubagentType.fromString(reader.getString()); + } else if ("handoff_policy".equals(fieldName)) { + handoffPolicy = VoiceAgentHandoffPolicy.fromJson(reader); + } else { + reader.skipChildren(); + } + } + VoiceAgentInlineSubagentConfiguration deserializedVoiceAgentInlineSubagentConfiguration + = new VoiceAgentInlineSubagentConfiguration(subagents); + deserializedVoiceAgentInlineSubagentConfiguration.subagentType = subagentType; + deserializedVoiceAgentInlineSubagentConfiguration.handoffPolicy = handoffPolicy; + return deserializedVoiceAgentInlineSubagentConfiguration; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionChannel.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionChannel.java new file mode 100644 index 0000000000000..455e4ca1c05b6 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionChannel.java @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * The receiver used by an input collection. Voice collection is not supported. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentInputCollectionChannel { + + /** + * Receives one complete SMS from the selected sender. + */ + SMS("sms"), + /** + * Receives individual keypad digits from the active call. + */ + DTMF("dtmf"); + + /** + * The actual serialized value for a VoiceAgentInputCollectionChannel instance. + */ + private final String value; + + VoiceAgentInputCollectionChannel(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentInputCollectionChannel instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentInputCollectionChannel object, or null if unable to parse. + */ + public static VoiceAgentInputCollectionChannel fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentInputCollectionChannel[] items = VoiceAgentInputCollectionChannel.values(); + for (VoiceAgentInputCollectionChannel item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatus.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatus.java new file mode 100644 index 0000000000000..2c328f8b5e782 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatus.java @@ -0,0 +1,153 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Collection lifecycle and value-free telephony-operation outcomes. Additional outcomes may be introduced over time. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentInputCollectionStatus extends ExpandableStringEnum { + + /** + * The invocation was accepted; the receiver is not yet ready and no value has been collected. + */ + @Generated + public static final VoiceAgentInputCollectionStatus ACCEPTED = fromString("accepted"); + + /** + * The receiver is ready, allowing the service to prompt the caller for input. + */ + @Generated + public static final VoiceAgentInputCollectionStatus LISTENING = fromString("listening"); + + /** + * Collection completed with an ordinary value or a privately stored variable reference. + */ + @Generated + public static final VoiceAgentInputCollectionStatus COMPLETED = fromString("completed"); + + /** + * A collection deadline or input timer expired without completing collection. + */ + @Generated + public static final VoiceAgentInputCollectionStatus EXPIRED = fromString("expired"); + + /** + * The service cancelled collection and cleaned up its receiver. + */ + @Generated + public static final VoiceAgentInputCollectionStatus CANCELLED = fromString("cancelled"); + + /** + * Collection failed without creating an output variable. + */ + @Generated + public static final VoiceAgentInputCollectionStatus FAILED = fromString("failed"); + + /** + * The invocation was rejected because another operation is active. + */ + @Generated + public static final VoiceAgentInputCollectionStatus BUSY = fromString("busy"); + + /** + * The received input did not satisfy the collection policy. + */ + @Generated + public static final VoiceAgentInputCollectionStatus INVALID_INPUT = fromString("invalid_input"); + + /** + * The model-generated tool arguments were invalid. + */ + @Generated + public static final VoiceAgentInputCollectionStatus INVALID_ARGUMENTS = fromString("invalid_arguments"); + + /** + * The result does not match the current collection or receiver request. + */ + @Generated + public static final VoiceAgentInputCollectionStatus STALE_COLLECTION = fromString("stale_collection"); + + /** + * No supported receiver. Also used when omitting an unsupported tool before model exposure; no collection or + * variable is created. + */ + @Generated + public static final VoiceAgentInputCollectionStatus UNSUPPORTED_CHANNEL = fromString("unsupported_channel"); + + /** + * The service could not dispatch the operation to its executor; this does not confirm a provider outcome. + */ + @Generated + public static final VoiceAgentInputCollectionStatus DISPATCH_FAILED = fromString("dispatch_failed"); + + /** + * The provider accepted the operation; this does not confirm SMS delivery, IVR recognition or authentication. + */ + @Generated + public static final VoiceAgentInputCollectionStatus PROVIDER_ACCEPTED = fromString("provider_accepted"); + + /** + * The transfer target did not answer and the original conversation remains available. + */ + @Generated + public static final VoiceAgentInputCollectionStatus TRANSFER_NOT_ANSWERED = fromString("transfer_not_answered"); + + /** + * The provider reported failure or does not support the requested operation. + */ + @Generated + public static final VoiceAgentInputCollectionStatus PROVIDER_FAILED_OR_UNSUPPORTED + = fromString("provider_failed_or_unsupported"); + + /** + * The provider outcome could not be confirmed after possible dispatch; the service does not automatically retry. + */ + @Generated + public static final VoiceAgentInputCollectionStatus PROVIDER_RESULT_UNCERTAIN + = fromString("provider_result_uncertain"); + + /** + * Rejected before any provider side effect; nothing was sent or dialed. Includes unavailable executors and + * unavailable-sender tool-resolution failures before model exposure. + */ + @Generated + public static final VoiceAgentInputCollectionStatus PROVIDER_NOT_EXECUTED = fromString("provider_not_executed"); + + /** + * Creates a new instance of VoiceAgentInputCollectionStatus value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentInputCollectionStatus() { + } + + /** + * Creates or finds a VoiceAgentInputCollectionStatus from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentInputCollectionStatus. + */ + @Generated + public static VoiceAgentInputCollectionStatus fromString(String name) { + return fromString(name, VoiceAgentInputCollectionStatus.class); + } + + /** + * Gets known VoiceAgentInputCollectionStatus values. + * + * @return known VoiceAgentInputCollectionStatus values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentInputCollectionStatus.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatusEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatusEvent.java new file mode 100644 index 0000000000000..6f8980d52e411 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatusEvent.java @@ -0,0 +1,259 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Reports collection or telephony outcomes for a model call. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentInputCollectionStatusEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.INPUT_COLLECTION_STATUS; + + /* + * An optional event identifier. + */ + @Generated + private String eventId; + + /* + * The originating system-tool invocation. + */ + @Generated + private final String callId; + + /* + * The collection operation identifier, when this outcome concerns a collection. + */ + @Generated + private String collectionId; + + /* + * The current receiver request identifier, when applicable. + */ + @Generated + private String requestId; + + /* + * The collection receiver, omitted for telephony-operation feedback. + */ + @Generated + private VoiceAgentInputCollectionChannel channel; + + /* + * The reported outcome. Generation completion of a system-tool item is separate. + */ + @Generated + private final VoiceAgentInputCollectionStatus status; + + /* + * Completed ASCII digits, including leading zeros, only for `secret: false`; absent for private collection and + * telephony-operation feedback. + */ + @Generated + private String value; + + /* + * Actual bare variable name from successful private collection, not its value. May be suffixed on collision; + * reference it with `{{name}}`. + */ + @Generated + private String outputReference; + + /** + * Creates an instance of VoiceAgentInputCollectionStatusEvent class. + * + * @param callId the callId value to set. + * @param status the status value to set. + */ + @Generated + private VoiceAgentInputCollectionStatusEvent(String callId, VoiceAgentInputCollectionStatus status) { + this.callId = callId; + this.status = status; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: An optional event identifier. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the callId property: The originating system-tool invocation. + * + * @return the callId value. + */ + @Generated + public String getCallId() { + return this.callId; + } + + /** + * Get the collectionId property: The collection operation identifier, when this outcome concerns a collection. + * + * @return the collectionId value. + */ + @Generated + public String getCollectionId() { + return this.collectionId; + } + + /** + * Get the requestId property: The current receiver request identifier, when applicable. + * + * @return the requestId value. + */ + @Generated + public String getRequestId() { + return this.requestId; + } + + /** + * Get the channel property: The collection receiver, omitted for telephony-operation feedback. + * + * @return the channel value. + */ + @Generated + public VoiceAgentInputCollectionChannel getChannel() { + return this.channel; + } + + /** + * Get the status property: The reported outcome. Generation completion of a system-tool item is separate. + * + * @return the status value. + */ + @Generated + public VoiceAgentInputCollectionStatus getStatus() { + return this.status; + } + + /** + * Get the value property: Completed ASCII digits, including leading zeros, only for `secret: false`; absent for + * private collection and telephony-operation feedback. + * + * @return the value value. + */ + @Generated + public String getValue() { + return this.value; + } + + /** + * Get the outputReference property: Actual bare variable name from successful private collection, not its value. + * May be suffixed on collision; reference it with `{{name}}`. + * + * @return the outputReference value. + */ + @Generated + public String getOutputReference() { + return this.outputReference; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("call_id", this.callId); + jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("collection_id", this.collectionId); + jsonWriter.writeStringField("request_id", this.requestId); + jsonWriter.writeStringField("channel", this.channel == null ? null : this.channel.toString()); + jsonWriter.writeStringField("value", this.value); + jsonWriter.writeStringField("output_ref", this.outputReference); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentInputCollectionStatusEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentInputCollectionStatusEvent if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentInputCollectionStatusEvent. + */ + @Generated + public static VoiceAgentInputCollectionStatusEvent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String callId = null; + VoiceAgentInputCollectionStatus status = null; + RealtimeServerEventType type = RealtimeServerEventType.INPUT_COLLECTION_STATUS; + String eventId = null; + String collectionId = null; + String requestId = null; + VoiceAgentInputCollectionChannel channel = null; + String value = null; + String outputReference = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("call_id".equals(fieldName)) { + callId = reader.getString(); + } else if ("status".equals(fieldName)) { + status = VoiceAgentInputCollectionStatus.fromString(reader.getString()); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("collection_id".equals(fieldName)) { + collectionId = reader.getString(); + } else if ("request_id".equals(fieldName)) { + requestId = reader.getString(); + } else if ("channel".equals(fieldName)) { + channel = VoiceAgentInputCollectionChannel.fromString(reader.getString()); + } else if ("value".equals(fieldName)) { + value = reader.getString(); + } else if ("output_ref".equals(fieldName)) { + outputReference = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentInputCollectionStatusEvent deserializedVoiceAgentInputCollectionStatusEvent + = new VoiceAgentInputCollectionStatusEvent(callId, status); + deserializedVoiceAgentInputCollectionStatusEvent.type = type; + deserializedVoiceAgentInputCollectionStatusEvent.eventId = eventId; + deserializedVoiceAgentInputCollectionStatusEvent.collectionId = collectionId; + deserializedVoiceAgentInputCollectionStatusEvent.requestId = requestId; + deserializedVoiceAgentInputCollectionStatusEvent.channel = channel; + deserializedVoiceAgentInputCollectionStatusEvent.value = value; + deserializedVoiceAgentInputCollectionStatusEvent.outputReference = outputReference; + return deserializedVoiceAgentInputCollectionStatusEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java index 4ee9d6eef9eab..c792eb1d5806d 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java @@ -52,6 +52,7 @@ public final class VoiceAgentInputTranscription implements JsonSerializable keywords; /* + * * An optional text to guide the model's style or continue a previous audio * segment. * For `whisper-1`, the [prompt is a list of @@ -178,7 +179,8 @@ public VoiceAgentInputTranscription setKeywords(List keywords) { } /** - * Get the prompt property: An optional text to guide the model's style or continue a previous audio + * Get the prompt property: + * 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](https://developers.openai.com/api/docs/guides/speech-to-text#prompting). @@ -194,7 +196,8 @@ public String getPrompt() { } /** - * Set the prompt property: An optional text to guide the model's style or continue a previous audio + * Set the prompt property: + * 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](https://developers.openai.com/api/docs/guides/speech-to-text#prompting). diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java index 0f52ead3dde4c..13a5790efa5cc 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java @@ -26,7 +26,8 @@ public class VoiceAgentInterimResponseConfiguration * The interim-response implementation. */ @Generated - private String type = "VoiceAgentInterimResponseConfiguration"; + private VoiceAgentInterimResponseType type + = VoiceAgentInterimResponseType.fromString("VoiceAgentInterimResponseConfiguration"); /* * Conditions that may trigger one interim response. @@ -53,7 +54,7 @@ protected VoiceAgentInterimResponseConfiguration() { * @return the type value. */ @Generated - public String getType() { + public VoiceAgentInterimResponseType getType() { return this.type; } @@ -115,7 +116,7 @@ public VoiceAgentInterimResponseConfiguration setLatencyThresholdMs(Duration lat @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeArrayField("triggers", this.triggers, (writer, element) -> writer.writeString(element == null ? null : element.toString())); jsonWriter.writeNumberField("latency_threshold_ms", this.latencyThresholdMs); @@ -168,7 +169,8 @@ static VoiceAgentInterimResponseConfiguration fromJsonKnownDiscriminator(JsonRea String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - deserializedVoiceAgentInterimResponseConfiguration.type = reader.getString(); + deserializedVoiceAgentInterimResponseConfiguration.type + = VoiceAgentInterimResponseType.fromString(reader.getString()); } else if ("triggers".equals(fieldName)) { List triggers = reader.readArray(reader1 -> VoiceAgentInterimResponseTrigger.fromString(reader1.getString())); diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseType.java new file mode 100644 index 0000000000000..68ce05276373e --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseType.java @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The interim-response implementations supported by a voice agent. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentInterimResponseType extends ExpandableStringEnum { + + /** + * Select a static interim response from configured text. + */ + @Generated + public static final VoiceAgentInterimResponseType STATIC_INTERIM_RESPONSE = fromString("static_interim_response"); + + /** + * Generate an interim response with a language model. + */ + @Generated + public static final VoiceAgentInterimResponseType LLM_INTERIM_RESPONSE = fromString("llm_interim_response"); + + /** + * Creates a new instance of VoiceAgentInterimResponseType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentInterimResponseType() { + } + + /** + * Creates or finds a VoiceAgentInterimResponseType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentInterimResponseType. + */ + @Generated + public static VoiceAgentInterimResponseType fromString(String name) { + return fromString(name, VoiceAgentInterimResponseType.class); + } + + /** + * Gets known VoiceAgentInterimResponseType values. + * + * @return known VoiceAgentInterimResponseType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentInterimResponseType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLanguageDetectionSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLanguageDetectionSystemTool.java new file mode 100644 index 0000000000000..d284395412623 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLanguageDetectionSystemTool.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Switches supported conversation language settings. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLanguageDetectionSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.LANGUAGE_DETECTION; + + /** + * Creates an instance of VoiceAgentLanguageDetectionSystemTool class. + */ + @Generated + public VoiceAgentLanguageDetectionSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLanguageDetectionSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLanguageDetectionSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLanguageDetectionSystemTool if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentLanguageDetectionSystemTool. + */ + @Generated + public static VoiceAgentLanguageDetectionSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentLanguageDetectionSystemTool deserializedVoiceAgentLanguageDetectionSystemTool + = new VoiceAgentLanguageDetectionSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentLanguageDetectionSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentLanguageDetectionSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentLanguageDetectionSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentLanguageDetectionSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLanguageDetectionSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegation.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegation.java new file mode 100644 index 0000000000000..db656a6a8f8f7 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegation.java @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Delegates work to the application using native client delegation. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveClientDelegation extends VoiceAgentLiveDelegation { + + /* + * The delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationType type = VoiceAgentLiveDelegationType.CLIENT; + + /** + * Creates an instance of VoiceAgentLiveClientDelegation class. + */ + @Generated + public VoiceAgentLiveClientDelegation() { + } + + /** + * Get the type property: The delegation owner. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationType getType() { + return this.type; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeNumberField("acknowledgement_delay_ms", this.acknowledgementDelay); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveClientDelegation from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveClientDelegation if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentLiveClientDelegation. + */ + @Generated + public static VoiceAgentLiveClientDelegation fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentLiveClientDelegation deserializedVoiceAgentLiveClientDelegation + = new VoiceAgentLiveClientDelegation(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("type".equals(fieldName)) { + deserializedVoiceAgentLiveClientDelegation.type + = VoiceAgentLiveDelegationType.fromString(reader.getString()); + } else if ("acknowledgement_delay_ms".equals(fieldName)) { + deserializedVoiceAgentLiveClientDelegation.acknowledgementDelay + = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentLiveClientDelegation; + }); + } + + /* + * Milliseconds to wait before requesting an automatic spoken acknowledgement for a delegation. The model may still + * speak before this delay. Any commentary or thinking appended to the session cancels all pending acknowledgements, + * including those for other delegations. Defaults to 400 for Decisions sessions and 0 (request immediately) for + * other sessions. Omission in a session update preserves the current value. Updates apply to subsequent + * delegations. + */ + @Generated + private Long acknowledgementDelay; + + /** + * Get the acknowledgementDelay property: Milliseconds to wait before requesting an automatic spoken acknowledgement + * for a delegation. The model may still speak before this delay. Any commentary or thinking appended to the session + * cancels all pending acknowledgements, including those for other delegations. Defaults to 400 for Decisions + * sessions and 0 (request immediately) for other sessions. Omission in a session update preserves the current + * value. Updates apply to subsequent delegations. + * + * @return the acknowledgementDelay value. + */ + @Generated + public Duration getAcknowledgementDelay() { + if (this.acknowledgementDelay == null) { + return null; + } + return Duration.ofMillis(this.acknowledgementDelay); + } + + /** + * Set the acknowledgementDelay property: Milliseconds to wait before requesting an automatic spoken acknowledgement + * for a delegation. The model may still speak before this delay. Any commentary or thinking appended to the session + * cancels all pending acknowledgements, including those for other delegations. Defaults to 400 for Decisions + * sessions and 0 (request immediately) for other sessions. Omission in a session update preserves the current + * value. Updates apply to subsequent delegations. + * + * @param acknowledgementDelay the acknowledgementDelay value to set. + * @return the VoiceAgentLiveClientDelegation object itself. + */ + @Generated + public VoiceAgentLiveClientDelegation setAcknowledgementDelay(Duration acknowledgementDelay) { + if (acknowledgementDelay == null) { + this.acknowledgementDelay = null; + } else { + this.acknowledgementDelay = acknowledgementDelay.toMillis(); + } + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegationConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegationConversationItem.java new file mode 100644 index 0000000000000..a1118ee52f25d --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegationConversationItem.java @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Results supplied by the application for client delegation. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveClientDelegationConversationItem extends VoiceAgentLiveDelegationConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private final VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.DELEGATION; + + /* + * The configured delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.CLIENT; + + /* + * Guidance for Live to communicate to the user, when accepted. + */ + @Generated + private String commentary; + + /* + * Accepted background context, not private reasoning or a request to speak. + */ + @Generated + private String thinking; + + /** + * Creates an instance of VoiceAgentLiveClientDelegationConversationItem class. + * + * @param id the id value to set. + * @param createdAt the createdAt value to set. + */ + @Generated + private VoiceAgentLiveClientDelegationConversationItem(String id, OffsetDateTime createdAt) { + super(id, createdAt); + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the target property: The configured delegation owner. + * + * @return the target value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationTarget getTarget() { + return this.target; + } + + /** + * Get the commentary property: Guidance for Live to communicate to the user, when accepted. + * + * @return the commentary value. + */ + @Generated + public String getCommentary() { + return this.commentary; + } + + /** + * Get the thinking property: Accepted background context, not private reasoning or a request to speak. + * + * @return the thinking value. + */ + @Generated + public String getThinking() { + return this.thinking; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("id", getId()); + if (getCreatedAt() != null) { + jsonWriter.writeLongField("created_at", getCreatedAt().toEpochSecond()); + } + jsonWriter.writeStringField("response_id", getResponseId()); + jsonWriter.writeStringField("target", this.target == null ? null : this.target.toString()); + jsonWriter.writeStringField("commentary", this.commentary); + jsonWriter.writeStringField("thinking", this.thinking); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveClientDelegationConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveClientDelegationConversationItem if the JsonReader was pointing to an + * instance of it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveClientDelegationConversationItem. + */ + @Generated + public static VoiceAgentLiveClientDelegationConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + OffsetDateTime createdAt = null; + String responseId = null; + VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.CLIENT; + String commentary = null; + String thinking = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("created_at".equals(fieldName)) { + createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else if ("target".equals(fieldName)) { + target = VoiceAgentLiveDelegationTarget.fromString(reader.getString()); + } else if ("commentary".equals(fieldName)) { + commentary = reader.getString(); + } else if ("thinking".equals(fieldName)) { + thinking = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveClientDelegationConversationItem deserializedVoiceAgentLiveClientDelegationConversationItem + = new VoiceAgentLiveClientDelegationConversationItem(id, createdAt); + deserializedVoiceAgentLiveClientDelegationConversationItem.setResponseId(responseId); + deserializedVoiceAgentLiveClientDelegationConversationItem.target = target; + deserializedVoiceAgentLiveClientDelegationConversationItem.commentary = commentary; + deserializedVoiceAgentLiveClientDelegationConversationItem.thinking = thinking; + return deserializedVoiceAgentLiveClientDelegationConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversation.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversation.java new file mode 100644 index 0000000000000..653ac6ee50de3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversation.java @@ -0,0 +1,255 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import com.openai.models.live.SessionUsage; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.Map; + +/** + * A Live session persisted when effective store is true. Uses voice-conversation lifecycle and retention; items are + * retrieved separately. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveConversation implements JsonSerializable { + + /* + * The unique id of the conversation. + */ + @Generated + private final String id; + + /* + * The object type. Always `voice.conversation`. + */ + @Generated + private final String objectType = "voice.conversation"; + + /* + * The lifecycle status of the conversation. + */ + @Generated + private final VoiceConversationStatus status; + + /* + * The Unix timestamp (in seconds) for when the conversation was created. + */ + @Generated + private final long createdAt; + + /* + * The Unix timestamp (in seconds) for when session and persistence finalization reached the terminal `completed` or + * `failed` status. Absent while `status` is `in_progress`. + */ + @Generated + private Long completedAt; + + /* + * A set of key-value pairs attached to the conversation. + */ + @Generated + private Map metadata; + + /* + * The terminal error that prevented persistence finalization. Present only when `status` is `failed`. + */ + @Generated + private ApiError lastError; + + /* + * Cumulative Live audio usage, excluding delegated-model tokens. May be absent after abnormal close. + */ + @Generated + private SessionUsage usage; + + /** + * Creates an instance of VoiceAgentLiveConversation class. + * + * @param id the id value to set. + * @param status the status value to set. + * @param createdAt the createdAt value to set. + */ + @Generated + private VoiceAgentLiveConversation(String id, VoiceConversationStatus status, OffsetDateTime createdAt) { + this.id = id; + this.status = status; + if (createdAt == null) { + this.createdAt = 0L; + } else { + this.createdAt = createdAt.toEpochSecond(); + } + } + + /** + * Get the id property: The unique id of the conversation. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Get the objectType property: The object type. Always `voice.conversation`. + * + * @return the objectType value. + */ + @Generated + public String getObjectType() { + return this.objectType; + } + + /** + * Get the status property: The lifecycle status of the conversation. + * + * @return the status value. + */ + @Generated + public VoiceConversationStatus getStatus() { + return this.status; + } + + /** + * Get the createdAt property: The Unix timestamp (in seconds) for when the conversation was created. + * + * @return the createdAt value. + */ + @Generated + public OffsetDateTime getCreatedAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.createdAt), ZoneOffset.UTC); + } + + /** + * Get the completedAt property: The Unix timestamp (in seconds) for when session and persistence finalization + * reached the terminal `completed` or `failed` status. Absent while `status` is `in_progress`. + * + * @return the completedAt value. + */ + @Generated + public OffsetDateTime getCompletedAt() { + if (this.completedAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.completedAt), ZoneOffset.UTC); + } + + /** + * Get the metadata property: A set of key-value pairs attached to the conversation. + * + * @return the metadata value. + */ + @Generated + public Map getMetadata() { + return this.metadata; + } + + /** + * Get the lastError property: The terminal error that prevented persistence finalization. Present only when + * `status` is `failed`. + * + * @return the lastError value. + */ + @Generated + public ApiError getLastError() { + return this.lastError; + } + + /** + * Get the usage property: Cumulative Live audio usage, excluding delegated-model tokens. May be absent after + * abnormal close. + * + * @return the usage value. + */ + @Generated + public SessionUsage getUsage() { + return this.usage; + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("object", this.objectType); + jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); + jsonWriter.writeLongField("created_at", this.createdAt); + jsonWriter.writeNumberField("completed_at", this.completedAt); + jsonWriter.writeMapField("metadata", this.metadata, (writer, element) -> writer.writeString(element)); + jsonWriter.writeJsonField("last_error", this.lastError); + if (this.usage != null) { + jsonWriter.writeFieldName("usage"); + OpenAIJsonHelper.toBinaryData(this.usage).writeTo(jsonWriter); + } + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveConversation from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveConversation if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveConversation. + */ + public static VoiceAgentLiveConversation fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup + return jsonReader.readObject(reader -> { + String id = null; + VoiceConversationStatus status = null; + OffsetDateTime createdAt = null; + Long completedAt = null; + Map metadata = null; + ApiError lastError = null; + SessionUsage usage = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("status".equals(fieldName)) { + status = VoiceConversationStatus.fromString(reader.getString()); + } else if ("created_at".equals(fieldName)) { + createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("completed_at".equals(fieldName)) { + completedAt = reader.getNullable(JsonReader::getLong); + } else if ("metadata".equals(fieldName)) { + metadata = reader.readMap(reader1 -> reader1.getString()); + } else if ("last_error".equals(fieldName)) { + lastError = ApiError.fromJson(reader); + } else if ("usage".equals(fieldName)) { + BinaryData usageData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + usage = OpenAIJsonHelper.fromBinaryData(usageData, SessionUsage.class); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveConversation deserializedVoiceAgentLiveConversation + = new VoiceAgentLiveConversation(id, status, createdAt); + deserializedVoiceAgentLiveConversation.completedAt = completedAt; + deserializedVoiceAgentLiveConversation.metadata = metadata; + deserializedVoiceAgentLiveConversation.lastError = lastError; + deserializedVoiceAgentLiveConversation.usage = usage; + return deserializedVoiceAgentLiveConversation; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItem.java new file mode 100644 index 0000000000000..eda878f0e9617 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItem.java @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * A stored speech segment or delegation. Speech segments are not native turns or proof of playback; delegation results + * are separate from spoken transcripts. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class VoiceAgentLiveConversationItem implements JsonSerializable { + + /* + * The persisted item kind. + */ + @Generated + private VoiceAgentLiveConversationItemType type + = VoiceAgentLiveConversationItemType.fromString("VoiceAgentLiveConversationItem"); + + /* + * Item ID used for retrieval. Foundry assigns speech IDs; delegation IDs retain their native value. + */ + @Generated + private final String id; + + /** + * Creates an instance of VoiceAgentLiveConversationItem class. + * + * @param id the id value to set. + */ + @Generated + protected VoiceAgentLiveConversationItem(String id) { + this.id = id; + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the id property: Item ID used for retrieval. Foundry assigns speech IDs; delegation IDs retain their native + * value. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveConversationItem if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveConversationItem. + */ + @Generated + public static VoiceAgentLiveConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("type".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("input".equals(discriminatorValue)) { + return VoiceAgentLiveInputConversationItem.fromJson(readerToUse.reset()); + } else if ("output".equals(discriminatorValue)) { + return VoiceAgentLiveOutputConversationItem.fromJson(readerToUse.reset()); + } else if ("delegation".equals(discriminatorValue)) { + return VoiceAgentLiveDelegationConversationItem.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static VoiceAgentLiveConversationItem fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + VoiceAgentLiveConversationItemType type = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentLiveConversationItemType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveConversationItem deserializedVoiceAgentLiveConversationItem + = new VoiceAgentLiveConversationItem(id); + deserializedVoiceAgentLiveConversationItem.type = type; + return deserializedVoiceAgentLiveConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItemType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItemType.java new file mode 100644 index 0000000000000..16b84470b4e80 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItemType.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The kind of a persisted Live conversation item. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveConversationItemType extends ExpandableStringEnum { + + /** + * Static value input for VoiceAgentLiveConversationItemType. + */ + @Generated + public static final VoiceAgentLiveConversationItemType INPUT = fromString("input"); + + /** + * Static value output for VoiceAgentLiveConversationItemType. + */ + @Generated + public static final VoiceAgentLiveConversationItemType OUTPUT = fromString("output"); + + /** + * Static value delegation for VoiceAgentLiveConversationItemType. + */ + @Generated + public static final VoiceAgentLiveConversationItemType DELEGATION = fromString("delegation"); + + /** + * Creates a new instance of VoiceAgentLiveConversationItemType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentLiveConversationItemType() { + } + + /** + * Creates or finds a VoiceAgentLiveConversationItemType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentLiveConversationItemType. + */ + @Generated + public static VoiceAgentLiveConversationItemType fromString(String name) { + return fromString(name, VoiceAgentLiveConversationItemType.class); + } + + /** + * Gets known VoiceAgentLiveConversationItemType values. + * + * @return known VoiceAgentLiveConversationItemType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentLiveConversationItemType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDefinition.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDefinition.java new file mode 100644 index 0000000000000..525893df12347 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDefinition.java @@ -0,0 +1,319 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import com.openai.models.live.SessionConfig.Audio; +import java.io.IOException; +import java.util.Map; + +/** + * The Live voice agent definition. Its configuration (model, instructions, audio, and delegation) drives a + * managed speech-to-speech experience using a Foundry GPT Live deployment. Establish Live voice sessions through + * `GET /agents/{agent_name}/endpoint/protocols/voice/live/sessions`. Every create or update produces a new immutable + * version. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveDefinition extends VoiceAgentBaseDefinition { + + /* + * The kind property. + */ + @Generated + private final AgentKind kind = AgentKind.VOICE; + + /* + * The voice protocol for this agent version. Null and unknown values are invalid. + */ + @Generated + private VoiceAgentSubProtocol subProtocol = VoiceAgentSubProtocol.LIVE; + + /* + * Uses a Foundry model deployment. + */ + @Generated + private final VoiceModelType modelType = VoiceModelType.SELF_DEPLOYED; + + /* + * The GPT Live deployment name. + */ + @Generated + private final String model; + + /* + * Template-only startup greeting, rendered with session structured inputs. Foundry-only; not sent in native Live + * settings. + */ + @Generated + private VoiceAgentTemplateGreetingConfiguration greeting; + + /* + * Startup audio formats and output voice. + */ + @Generated + private Audio audio; + + /* + * Delegation settings. Omit for client mode. responses.model is a backend deployment name in the Live resource, not + * a model catalog ID. + */ + @Generated + private VoiceAgentLiveDelegation delegation; + + /** + * Creates an instance of VoiceAgentLiveDefinition class. + * + * @param model the model value to set. + */ + @Generated + public VoiceAgentLiveDefinition(String model) { + this.model = model; + } + + /** + * Get the kind property: The kind property. + * + * @return the kind value. + */ + @Generated + @Override + public AgentKind getKind() { + return this.kind; + } + + /** + * Get the subProtocol property: The voice protocol for this agent version. Null and unknown values are invalid. + * + * @return the subProtocol value. + */ + @Generated + @Override + public VoiceAgentSubProtocol getSubProtocol() { + return this.subProtocol; + } + + /** + * Get the modelType property: Uses a Foundry model deployment. + * + * @return the modelType value. + */ + @Generated + public VoiceModelType getModelType() { + return this.modelType; + } + + /** + * Get the model property: The GPT Live deployment name. + * + * @return the model value. + */ + @Generated + public String getModel() { + return this.model; + } + + /** + * Get the greeting property: Template-only startup greeting, rendered with session structured inputs. Foundry-only; + * not sent in native Live settings. + * + * @return the greeting value. + */ + @Generated + public VoiceAgentTemplateGreetingConfiguration getGreeting() { + return this.greeting; + } + + /** + * Set the greeting property: Template-only startup greeting, rendered with session structured inputs. Foundry-only; + * not sent in native Live settings. + * + * @param greeting the greeting value to set. + * @return the VoiceAgentLiveDefinition object itself. + */ + @Generated + public VoiceAgentLiveDefinition setGreeting(VoiceAgentTemplateGreetingConfiguration greeting) { + this.greeting = greeting; + return this; + } + + /** + * Get the audio property: Startup audio formats and output voice. + * + * @return the audio value. + */ + @Generated + public Audio getAudio() { + return this.audio; + } + + /** + * Get the delegation property: Delegation settings. Omit for client mode. responses.model is a backend deployment + * name in the Live resource, not a model catalog ID. + * + * @return the delegation value. + */ + @Generated + public VoiceAgentLiveDelegation getDelegation() { + return this.delegation; + } + + /** + * Set the delegation property: Delegation settings. Omit for client mode. responses.model is a backend deployment + * name in the Live resource, not a model catalog ID. + * + * @param delegation the delegation value to set. + * @return the VoiceAgentLiveDefinition object itself. + */ + @Generated + public VoiceAgentLiveDefinition setDelegation(VoiceAgentLiveDelegation delegation) { + this.delegation = delegation; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLiveDefinition setInstructions(String instructions) { + super.setInstructions(instructions); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLiveDefinition setStructuredInputs(Map structuredInputs) { + super.setStructuredInputs(structuredInputs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLiveDefinition setStore(Boolean store) { + super.setStore(store); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentLiveDefinition setRaiConfig(RaiConfig raiConfig) { + super.setRaiConfig(raiConfig); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeJsonField("rai_config", getRaiConfig()); + jsonWriter.writeStringField("instructions", getInstructions()); + jsonWriter.writeMapField("structured_inputs", getStructuredInputs(), + (writer, element) -> writer.writeJson(element)); + jsonWriter.writeBooleanField("store", isStore()); + jsonWriter.writeStringField("model_type", this.modelType == null ? null : this.modelType.toString()); + jsonWriter.writeStringField("model", this.model); + jsonWriter.writeStringField("sub_protocol", this.subProtocol == null ? null : this.subProtocol.toString()); + jsonWriter.writeJsonField("greeting", this.greeting); + if (this.audio != null) { + jsonWriter.writeFieldName("audio"); + OpenAIJsonHelper.toBinaryData(this.audio).writeTo(jsonWriter); + } + jsonWriter.writeJsonField("delegation", this.delegation); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveDefinition from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveDefinition if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveDefinition. + */ + public static VoiceAgentLiveDefinition fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup + return jsonReader.readObject(reader -> { + RaiConfig raiConfig = null; + String instructions = null; + Map structuredInputs = null; + Boolean store = null; + String model = null; + VoiceAgentSubProtocol subProtocol = VoiceAgentSubProtocol.LIVE; + VoiceAgentTemplateGreetingConfiguration greeting = null; + Audio audio = null; + VoiceAgentLiveDelegation delegation = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("rai_config".equals(fieldName)) { + raiConfig = RaiConfig.fromJson(reader); + } else if ("instructions".equals(fieldName)) { + instructions = reader.getString(); + } else if ("structured_inputs".equals(fieldName)) { + structuredInputs = reader.readMap(reader1 -> StructuredInputDefinition.fromJson(reader1)); + } else if ("store".equals(fieldName)) { + store = reader.getNullable(JsonReader::getBoolean); + } else if ("model".equals(fieldName)) { + model = reader.getString(); + } else if ("sub_protocol".equals(fieldName)) { + subProtocol = VoiceAgentSubProtocol.fromString(reader.getString()); + } else if ("greeting".equals(fieldName)) { + greeting = VoiceAgentTemplateGreetingConfiguration.fromJson(reader); + } else if ("audio".equals(fieldName)) { + BinaryData audioData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + audio = OpenAIJsonHelper.fromBinaryData(audioData, Audio.class); + } else if ("delegation".equals(fieldName)) { + delegation = VoiceAgentLiveDelegation.fromJson(reader); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveDefinition deserializedVoiceAgentLiveDefinition = new VoiceAgentLiveDefinition(model); + deserializedVoiceAgentLiveDefinition.setRaiConfig(raiConfig); + deserializedVoiceAgentLiveDefinition.setInstructions(instructions); + deserializedVoiceAgentLiveDefinition.setStructuredInputs(structuredInputs); + deserializedVoiceAgentLiveDefinition.setStore(store); + deserializedVoiceAgentLiveDefinition.subProtocol = subProtocol; + deserializedVoiceAgentLiveDefinition.greeting = greeting; + deserializedVoiceAgentLiveDefinition.audio = audio; + deserializedVoiceAgentLiveDefinition.delegation = delegation; + return deserializedVoiceAgentLiveDefinition; + }); + } + + /** + * Set the audio property: Startup audio formats and output voice. + * + * @param audio the audio value to set. + * @return the VoiceAgentLiveDefinition object itself. + */ + @Generated + public VoiceAgentLiveDefinition setAudio(Audio audio) { + this.audio = audio; + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfigurationBase.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegation.java similarity index 60% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfigurationBase.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegation.java index 446dd2ee8f4fc..c9fde074c4293 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeSessionConfigurationBase.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegation.java @@ -13,32 +13,32 @@ import java.io.IOException; /** - * The RealtimeSessionConfigurationBase model. + * Who handles delegated work for a Live voice agent. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class RealtimeSessionConfigurationBase implements JsonSerializable { +public class VoiceAgentLiveDelegation implements JsonSerializable { /* - * The type property. + * The delegation owner. */ @Generated - private RealtimeSessionType type = RealtimeSessionType.fromString("RealtimeSessionConfigurationBase"); + private VoiceAgentLiveDelegationType type; /** - * Creates an instance of RealtimeSessionConfigurationBase class. + * Creates an instance of VoiceAgentLiveDelegation class. */ @Generated - protected RealtimeSessionConfigurationBase() { + protected VoiceAgentLiveDelegation() { } /** - * Get the type property: The type property. + * Get the type property: The delegation owner. * * @return the type value. */ @Generated - public RealtimeSessionType getType() { + public VoiceAgentLiveDelegationType getType() { return this.type; } @@ -54,15 +54,15 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } /** - * Reads an instance of RealtimeSessionConfigurationBase from the JsonReader. + * Reads an instance of VoiceAgentLiveDelegation from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeSessionConfigurationBase if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeSessionConfigurationBase. + * @return An instance of VoiceAgentLiveDelegation if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentLiveDelegation. */ @Generated - public static RealtimeSessionConfigurationBase fromJson(JsonReader jsonReader) throws IOException { + public static VoiceAgentLiveDelegation fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String discriminatorValue = null; try (JsonReader readerToUse = reader.bufferObject()) { @@ -79,10 +79,12 @@ public static RealtimeSessionConfigurationBase fromJson(JsonReader jsonReader) t } } // Use the discriminator value to determine which subtype should be deserialized. - if ("realtime".equals(discriminatorValue)) { - return RealtimeSessionConfiguration.fromJson(readerToUse.reset()); - } else if ("transcription".equals(discriminatorValue)) { - return RealtimeTranscriptionSessionConfiguration.fromJson(readerToUse.reset()); + if ("client".equals(discriminatorValue)) { + return VoiceAgentLiveClientDelegation.fromJson(readerToUse.reset()); + } else if ("responses".equals(discriminatorValue)) { + return VoiceAgentLiveResponsesDelegation.fromJson(readerToUse.reset()); + } else if ("foundry_managed_agent".equals(discriminatorValue)) { + return VoiceAgentLiveManagedAgentDelegation.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } @@ -91,21 +93,20 @@ public static RealtimeSessionConfigurationBase fromJson(JsonReader jsonReader) t } @Generated - static RealtimeSessionConfigurationBase fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + static VoiceAgentLiveDelegation fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - RealtimeSessionConfigurationBase deserializedRealtimeSessionConfigurationBase - = new RealtimeSessionConfigurationBase(); + VoiceAgentLiveDelegation deserializedVoiceAgentLiveDelegation = new VoiceAgentLiveDelegation(); while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - deserializedRealtimeSessionConfigurationBase.type - = RealtimeSessionType.fromString(reader.getString()); + deserializedVoiceAgentLiveDelegation.type + = VoiceAgentLiveDelegationType.fromString(reader.getString()); } else { reader.skipChildren(); } } - return deserializedRealtimeSessionConfigurationBase; + return deserializedVoiceAgentLiveDelegation; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationConversationItem.java new file mode 100644 index 0000000000000..2d175ec554ab6 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationConversationItem.java @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * A stored delegation using native fields with Foundry-specific targets. Its id is the native delegation ID. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class VoiceAgentLiveDelegationConversationItem extends VoiceAgentLiveConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private final VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.DELEGATION; + + /* + * The configured delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.fromString("delegation"); + + /* + * The ID of the Responses API response associated with a Responses delegation. Omitted for client delegations. + */ + @Generated + private String responseId; + + /* + * Observed delegation creation time, in Unix seconds. + */ + @Generated + private final long createdAt; + + /** + * Creates an instance of VoiceAgentLiveDelegationConversationItem class. + * + * @param id the id value to set. + * @param createdAt the createdAt value to set. + */ + @Generated + protected VoiceAgentLiveDelegationConversationItem(String id, OffsetDateTime createdAt) { + super(id); + if (createdAt == null) { + this.createdAt = 0L; + } else { + this.createdAt = createdAt.toEpochSecond(); + } + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the target property: The configured delegation owner. + * + * @return the target value. + */ + @Generated + public VoiceAgentLiveDelegationTarget getTarget() { + return this.target; + } + + /** + * Get the responseId property: The ID of the Responses API response associated with a Responses delegation. Omitted + * for client delegations. + * + * @return the responseId value. + */ + @Generated + public String getResponseId() { + return this.responseId; + } + + /** + * Set the responseId property: The ID of the Responses API response associated with a Responses delegation. Omitted + * for client delegations. + * + * @param responseId the responseId value to set. + * @return the VoiceAgentLiveDelegationConversationItem object itself. + */ + @Generated + VoiceAgentLiveDelegationConversationItem setResponseId(String responseId) { + this.responseId = responseId; + return this; + } + + /** + * Get the createdAt property: Observed delegation creation time, in Unix seconds. + * + * @return the createdAt value. + */ + @Generated + public OffsetDateTime getCreatedAt() { + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.createdAt), ZoneOffset.UTC); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeLongField("created_at", this.createdAt); + jsonWriter.writeStringField("target", this.target == null ? null : this.target.toString()); + jsonWriter.writeStringField("response_id", this.responseId); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveDelegationConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveDelegationConversationItem if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveDelegationConversationItem. + */ + @Generated + public static VoiceAgentLiveDelegationConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("target".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("client".equals(discriminatorValue)) { + return VoiceAgentLiveClientDelegationConversationItem.fromJson(readerToUse.reset()); + } else if ("responses".equals(discriminatorValue)) { + return VoiceAgentLiveResponsesDelegationConversationItem.fromJson(readerToUse.reset()); + } else if ("foundry_managed_agent".equals(discriminatorValue)) { + return VoiceAgentLiveFoundryManagedAgentDelegationItem.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static VoiceAgentLiveDelegationConversationItem fromJsonKnownDiscriminator(JsonReader jsonReader) + throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + OffsetDateTime createdAt = null; + VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.fromString("delegation"); + String responseId = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("created_at".equals(fieldName)) { + createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("target".equals(fieldName)) { + target = VoiceAgentLiveDelegationTarget.fromString(reader.getString()); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveDelegationConversationItem deserializedVoiceAgentLiveDelegationConversationItem + = new VoiceAgentLiveDelegationConversationItem(id, createdAt); + deserializedVoiceAgentLiveDelegationConversationItem.target = target; + deserializedVoiceAgentLiveDelegationConversationItem.responseId = responseId; + return deserializedVoiceAgentLiveDelegationConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationResultItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationResultItem.java new file mode 100644 index 0000000000000..2c0808f1a0e83 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationResultItem.java @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Persisted guidance accepted by Live. The service populates commentary, thinking, or both. Agent delegation section + * markers are removed before storage. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveDelegationResultItem implements JsonSerializable { + + /* + * Guidance for Live to communicate to the user. + */ + @Generated + private String commentary; + + /* + * Background context, not private reasoning or a request to speak. + */ + @Generated + private String thinking; + + /** + * Creates an instance of VoiceAgentLiveDelegationResultItem class. + */ + @Generated + private VoiceAgentLiveDelegationResultItem() { + } + + /** + * Get the commentary property: Guidance for Live to communicate to the user. + * + * @return the commentary value. + */ + @Generated + public String getCommentary() { + return this.commentary; + } + + /** + * Get the thinking property: Background context, not private reasoning or a request to speak. + * + * @return the thinking value. + */ + @Generated + public String getThinking() { + return this.thinking; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("commentary", this.commentary); + jsonWriter.writeStringField("thinking", this.thinking); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveDelegationResultItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveDelegationResultItem if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentLiveDelegationResultItem. + */ + @Generated + public static VoiceAgentLiveDelegationResultItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentLiveDelegationResultItem deserializedVoiceAgentLiveDelegationResultItem + = new VoiceAgentLiveDelegationResultItem(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("commentary".equals(fieldName)) { + deserializedVoiceAgentLiveDelegationResultItem.commentary = reader.getString(); + } else if ("thinking".equals(fieldName)) { + deserializedVoiceAgentLiveDelegationResultItem.thinking = reader.getString(); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentLiveDelegationResultItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationStatus.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationStatus.java new file mode 100644 index 0000000000000..113591bcb21a3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationStatus.java @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Persisted delegation outcome, not speech or playback status. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveDelegationStatus extends ExpandableStringEnum { + + /** + * Static value in_progress for VoiceAgentLiveDelegationStatus. + */ + @Generated + public static final VoiceAgentLiveDelegationStatus IN_PROGRESS = fromString("in_progress"); + + /** + * Static value completed for VoiceAgentLiveDelegationStatus. + */ + @Generated + public static final VoiceAgentLiveDelegationStatus COMPLETED = fromString("completed"); + + /** + * Static value failed for VoiceAgentLiveDelegationStatus. + */ + @Generated + public static final VoiceAgentLiveDelegationStatus FAILED = fromString("failed"); + + /** + * Static value incomplete for VoiceAgentLiveDelegationStatus. + */ + @Generated + public static final VoiceAgentLiveDelegationStatus INCOMPLETE = fromString("incomplete"); + + /** + * Static value cancelled for VoiceAgentLiveDelegationStatus. + */ + @Generated + public static final VoiceAgentLiveDelegationStatus CANCELLED = fromString("cancelled"); + + /** + * Creates a new instance of VoiceAgentLiveDelegationStatus value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentLiveDelegationStatus() { + } + + /** + * Creates or finds a VoiceAgentLiveDelegationStatus from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentLiveDelegationStatus. + */ + @Generated + public static VoiceAgentLiveDelegationStatus fromString(String name) { + return fromString(name, VoiceAgentLiveDelegationStatus.class); + } + + /** + * Gets known VoiceAgentLiveDelegationStatus values. + * + * @return known VoiceAgentLiveDelegationStatus values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentLiveDelegationStatus.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationTarget.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationTarget.java new file mode 100644 index 0000000000000..c1e314b6c8404 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationTarget.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Delegation owner. Foundry agent targets use native client delegation upstream. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveDelegationTarget extends ExpandableStringEnum { + + /** + * Static value responses for VoiceAgentLiveDelegationTarget. + */ + @Generated + public static final VoiceAgentLiveDelegationTarget RESPONSES = fromString("responses"); + + /** + * Static value client for VoiceAgentLiveDelegationTarget. + */ + @Generated + public static final VoiceAgentLiveDelegationTarget CLIENT = fromString("client"); + + /** + * Static value foundry_managed_agent for VoiceAgentLiveDelegationTarget. + */ + @Generated + public static final VoiceAgentLiveDelegationTarget FOUNDRY_MANAGED_AGENT = fromString("foundry_managed_agent"); + + /** + * Creates a new instance of VoiceAgentLiveDelegationTarget value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentLiveDelegationTarget() { + } + + /** + * Creates or finds a VoiceAgentLiveDelegationTarget from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentLiveDelegationTarget. + */ + @Generated + public static VoiceAgentLiveDelegationTarget fromString(String name) { + return fromString(name, VoiceAgentLiveDelegationTarget.class); + } + + /** + * Gets known VoiceAgentLiveDelegationTarget values. + * + * @return known VoiceAgentLiveDelegationTarget values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentLiveDelegationTarget.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationType.java new file mode 100644 index 0000000000000..a0a625f886f8e --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationType.java @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Supported owners of work delegated by a Live voice agent. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentLiveDelegationType { + + /** + * The application handles delegated work. + */ + CLIENT("client"), + /** + * A Responses backend handles delegated work. + */ + RESPONSES("responses"), + /** + * A prompt agent in the same project handles delegated work. + */ + FOUNDRY_MANAGED_AGENT("foundry_managed_agent"); + + /** + * The actual serialized value for a VoiceAgentLiveDelegationType instance. + */ + private final String value; + + VoiceAgentLiveDelegationType(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentLiveDelegationType instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentLiveDelegationType object, or null if unable to parse. + */ + public static VoiceAgentLiveDelegationType fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentLiveDelegationType[] items = VoiceAgentLiveDelegationType.values(); + for (VoiceAgentLiveDelegationType item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveFoundryManagedAgentDelegationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveFoundryManagedAgentDelegationItem.java new file mode 100644 index 0000000000000..a3bd9d521ada7 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveFoundryManagedAgentDelegationItem.java @@ -0,0 +1,289 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.List; + +/** + * Stored prompt-agent delegation state and accepted results. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveFoundryManagedAgentDelegationItem extends VoiceAgentLiveDelegationConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private final VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.DELEGATION; + + /* + * The configured delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.FOUNDRY_MANAGED_AGENT; + + /* + * Target agent name in the same project. + */ + @Generated + private final String agentName; + + /* + * Target version pinned at connection start. + */ + @Generated + private final String agentVersion; + + /* + * Backend conversation ID, distinct from the voice conversation and Live session IDs. + */ + @Generated + private String backendConversationId; + + /* + * Accepted guidance in order; empty until a result is accepted. Entries have no individual IDs, are noncumulative, + * and are independent of backend output_index. Partial results survive failure or cancellation. + */ + @Generated + private final List output; + + /* + * Task context sent to the target agent, not the full request body. + */ + @Generated + private String delegationContext; + + /* + * The persisted delegation outcome. + */ + @Generated + private final VoiceAgentLiveDelegationStatus status; + + /** + * Creates an instance of VoiceAgentLiveFoundryManagedAgentDelegationItem class. + * + * @param id the id value to set. + * @param createdAt the createdAt value to set. + * @param agentName the agentName value to set. + * @param agentVersion the agentVersion value to set. + * @param offset the offset value to set. + * @param output the output value to set. + * @param status the status value to set. + */ + @Generated + private VoiceAgentLiveFoundryManagedAgentDelegationItem(String id, OffsetDateTime createdAt, String agentName, + String agentVersion, Duration offset, List output, + VoiceAgentLiveDelegationStatus status) { + super(id, createdAt); + this.agentName = agentName; + this.agentVersion = agentVersion; + if (offset == null) { + this.offset = 0L; + } else { + this.offset = offset.toMillis(); + } + this.output = output; + this.status = status; + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the target property: The configured delegation owner. + * + * @return the target value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationTarget getTarget() { + return this.target; + } + + /** + * Get the agentName property: Target agent name in the same project. + * + * @return the agentName value. + */ + @Generated + public String getAgentName() { + return this.agentName; + } + + /** + * Get the agentVersion property: Target version pinned at connection start. + * + * @return the agentVersion value. + */ + @Generated + public String getAgentVersion() { + return this.agentVersion; + } + + /** + * Get the backendConversationId property: Backend conversation ID, distinct from the voice conversation and Live + * session IDs. + * + * @return the backendConversationId value. + */ + @Generated + public String getBackendConversationId() { + return this.backendConversationId; + } + + /** + * Get the output property: Accepted guidance in order; empty until a result is accepted. Entries have no individual + * IDs, are noncumulative, and are independent of backend output_index. Partial results survive failure or + * cancellation. + * + * @return the output value. + */ + @Generated + public List getOutput() { + return this.output; + } + + /** + * Get the delegationContext property: Task context sent to the target agent, not the full request body. + * + * @return the delegationContext value. + */ + @Generated + public String getDelegationContext() { + return this.delegationContext; + } + + /** + * Get the status property: The persisted delegation outcome. + * + * @return the status value. + */ + @Generated + public VoiceAgentLiveDelegationStatus getStatus() { + return this.status; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("id", getId()); + if (getCreatedAt() != null) { + jsonWriter.writeLongField("created_at", getCreatedAt().toEpochSecond()); + } + jsonWriter.writeStringField("response_id", getResponseId()); + jsonWriter.writeStringField("agent_name", this.agentName); + jsonWriter.writeStringField("agent_version", this.agentVersion); + jsonWriter.writeLongField("offset_ms", this.offset); + jsonWriter.writeArrayField("output", this.output, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); + jsonWriter.writeStringField("target", this.target == null ? null : this.target.toString()); + jsonWriter.writeStringField("backend_conversation_id", this.backendConversationId); + jsonWriter.writeStringField("delegation_context", this.delegationContext); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveFoundryManagedAgentDelegationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveFoundryManagedAgentDelegationItem if the JsonReader was pointing to an + * instance of it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveFoundryManagedAgentDelegationItem. + */ + @Generated + public static VoiceAgentLiveFoundryManagedAgentDelegationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + OffsetDateTime createdAt = null; + String responseId = null; + String agentName = null; + String agentVersion = null; + Duration offset = null; + List output = null; + VoiceAgentLiveDelegationStatus status = null; + VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.FOUNDRY_MANAGED_AGENT; + String backendConversationId = null; + String delegationContext = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("created_at".equals(fieldName)) { + createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else if ("agent_name".equals(fieldName)) { + agentName = reader.getString(); + } else if ("agent_version".equals(fieldName)) { + agentVersion = reader.getString(); + } else if ("offset_ms".equals(fieldName)) { + offset = Duration.ofMillis(reader.getLong()); + } else if ("output".equals(fieldName)) { + output = reader.readArray(reader1 -> VoiceAgentLiveDelegationResultItem.fromJson(reader1)); + } else if ("status".equals(fieldName)) { + status = VoiceAgentLiveDelegationStatus.fromString(reader.getString()); + } else if ("target".equals(fieldName)) { + target = VoiceAgentLiveDelegationTarget.fromString(reader.getString()); + } else if ("backend_conversation_id".equals(fieldName)) { + backendConversationId = reader.getString(); + } else if ("delegation_context".equals(fieldName)) { + delegationContext = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveFoundryManagedAgentDelegationItem deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem + = new VoiceAgentLiveFoundryManagedAgentDelegationItem(id, createdAt, agentName, agentVersion, offset, + output, status); + deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem.setResponseId(responseId); + deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem.target = target; + deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem.backendConversationId = backendConversationId; + deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem.delegationContext = delegationContext; + return deserializedVoiceAgentLiveFoundryManagedAgentDelegationItem; + }); + } + + /* + * Native delegation offset from session start, in milliseconds. + */ + @Generated + private final long offset; + + /** + * Get the offset property: Native delegation offset from session start, in milliseconds. + * + * @return the offset value. + */ + @Generated + public Duration getOffset() { + return Duration.ofMillis(this.offset); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveInputConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveInputConversationItem.java new file mode 100644 index 0000000000000..f443ccbdc8e1e --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveInputConversationItem.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * A stored user speech segment. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveInputConversationItem extends VoiceAgentLiveConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.INPUT; + + /* + * Captured user transcription, when available. + */ + @Generated + private String transcription; + + /* + * Captured audio metadata; audio.item_id matches this item's id. + */ + @Generated + private VoiceAudioItem audio; + + /** + * Creates an instance of VoiceAgentLiveInputConversationItem class. + * + * @param id the id value to set. + */ + @Generated + private VoiceAgentLiveInputConversationItem(String id) { + super(id); + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the transcription property: Captured user transcription, when available. + * + * @return the transcription value. + */ + @Generated + public String getTranscription() { + return this.transcription; + } + + /** + * Get the audio property: Captured audio metadata; audio.item_id matches this item's id. + * + * @return the audio value. + */ + @Generated + public VoiceAudioItem getAudio() { + return this.audio; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("transcription", this.transcription); + jsonWriter.writeJsonField("audio", this.audio); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveInputConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveInputConversationItem if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveInputConversationItem. + */ + @Generated + public static VoiceAgentLiveInputConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.INPUT; + String transcription = null; + VoiceAudioItem audio = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentLiveConversationItemType.fromString(reader.getString()); + } else if ("transcription".equals(fieldName)) { + transcription = reader.getString(); + } else if ("audio".equals(fieldName)) { + audio = VoiceAudioItem.fromJson(reader); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveInputConversationItem deserializedVoiceAgentLiveInputConversationItem + = new VoiceAgentLiveInputConversationItem(id); + deserializedVoiceAgentLiveInputConversationItem.type = type; + deserializedVoiceAgentLiveInputConversationItem.transcription = transcription; + deserializedVoiceAgentLiveInputConversationItem.audio = audio; + return deserializedVoiceAgentLiveInputConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveManagedAgentDelegation.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveManagedAgentDelegation.java new file mode 100644 index 0000000000000..c4115564d31c6 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveManagedAgentDelegation.java @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Delegates to a same-project prompt agent using native client delegation. Requires [thinking] and/or [commentary] + * output sections. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveManagedAgentDelegation extends VoiceAgentLiveDelegation { + + /* + * The delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationType type = VoiceAgentLiveDelegationType.FOUNDRY_MANAGED_AGENT; + + /* + * Name of a prompt agent in the same project. + */ + @Generated + private final String agentName; + + /* + * Agent version, pinned per connection. Omit to select the active version. + */ + @Generated + private String agentVersion; + + /** + * Creates an instance of VoiceAgentLiveManagedAgentDelegation class. + * + * @param agentName the agentName value to set. + */ + @Generated + public VoiceAgentLiveManagedAgentDelegation(String agentName) { + this.agentName = agentName; + } + + /** + * Get the type property: The delegation owner. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationType getType() { + return this.type; + } + + /** + * Get the agentName property: Name of a prompt agent in the same project. + * + * @return the agentName value. + */ + @Generated + public String getAgentName() { + return this.agentName; + } + + /** + * Get the agentVersion property: Agent version, pinned per connection. Omit to select the active version. + * + * @return the agentVersion value. + */ + @Generated + public String getAgentVersion() { + return this.agentVersion; + } + + /** + * Set the agentVersion property: Agent version, pinned per connection. Omit to select the active version. + * + * @param agentVersion the agentVersion value to set. + * @return the VoiceAgentLiveManagedAgentDelegation object itself. + */ + @Generated + public VoiceAgentLiveManagedAgentDelegation setAgentVersion(String agentVersion) { + this.agentVersion = agentVersion; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("agent_name", this.agentName); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("agent_version", this.agentVersion); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveManagedAgentDelegation from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveManagedAgentDelegation if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveManagedAgentDelegation. + */ + @Generated + public static VoiceAgentLiveManagedAgentDelegation fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String agentName = null; + VoiceAgentLiveDelegationType type = VoiceAgentLiveDelegationType.FOUNDRY_MANAGED_AGENT; + String agentVersion = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("agent_name".equals(fieldName)) { + agentName = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentLiveDelegationType.fromString(reader.getString()); + } else if ("agent_version".equals(fieldName)) { + agentVersion = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveManagedAgentDelegation deserializedVoiceAgentLiveManagedAgentDelegation + = new VoiceAgentLiveManagedAgentDelegation(agentName); + deserializedVoiceAgentLiveManagedAgentDelegation.type = type; + deserializedVoiceAgentLiveManagedAgentDelegation.agentVersion = agentVersion; + return deserializedVoiceAgentLiveManagedAgentDelegation; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveOutputConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveOutputConversationItem.java new file mode 100644 index 0000000000000..4c9bd36bc59b9 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveOutputConversationItem.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * A stored assistant speech segment. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveOutputConversationItem extends VoiceAgentLiveConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.OUTPUT; + + /* + * Captured assistant transcription, not backend output or commentary guidance. + */ + @Generated + private String transcription; + + /* + * Captured audio metadata; audio.item_id matches this item's id. + */ + @Generated + private VoiceAudioItem audio; + + /** + * Creates an instance of VoiceAgentLiveOutputConversationItem class. + * + * @param id the id value to set. + */ + @Generated + private VoiceAgentLiveOutputConversationItem(String id) { + super(id); + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the transcription property: Captured assistant transcription, not backend output or commentary guidance. + * + * @return the transcription value. + */ + @Generated + public String getTranscription() { + return this.transcription; + } + + /** + * Get the audio property: Captured audio metadata; audio.item_id matches this item's id. + * + * @return the audio value. + */ + @Generated + public VoiceAudioItem getAudio() { + return this.audio; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("transcription", this.transcription); + jsonWriter.writeJsonField("audio", this.audio); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveOutputConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveOutputConversationItem if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveOutputConversationItem. + */ + @Generated + public static VoiceAgentLiveOutputConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.OUTPUT; + String transcription = null; + VoiceAudioItem audio = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentLiveConversationItemType.fromString(reader.getString()); + } else if ("transcription".equals(fieldName)) { + transcription = reader.getString(); + } else if ("audio".equals(fieldName)) { + audio = VoiceAudioItem.fromJson(reader); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveOutputConversationItem deserializedVoiceAgentLiveOutputConversationItem + = new VoiceAgentLiveOutputConversationItem(id); + deserializedVoiceAgentLiveOutputConversationItem.type = type; + deserializedVoiceAgentLiveOutputConversationItem.transcription = transcription; + deserializedVoiceAgentLiveOutputConversationItem.audio = audio; + return deserializedVoiceAgentLiveOutputConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegation.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegation.java new file mode 100644 index 0000000000000..2734d2f68c470 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegation.java @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import com.openai.models.live.ResponsesDelegationConfig; +import java.io.IOException; +import java.time.Duration; + +/** + * Delegates work to a Responses backend using native Responses settings. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveResponsesDelegation extends VoiceAgentLiveDelegation { + + /* + * The delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationType type = VoiceAgentLiveDelegationType.RESPONSES; + + /* + * Backend model, prompt, and tools used when the Live session delegates a task to Responses. + */ + @Generated + private final ResponsesDelegationConfig responses; + + /** + * Creates an instance of VoiceAgentLiveResponsesDelegation class. + * + * @param responses the responses value to set. + */ + @Generated + public VoiceAgentLiveResponsesDelegation(ResponsesDelegationConfig responses) { + this.responses = responses; + } + + /** + * Get the type property: The delegation owner. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationType getType() { + return this.type; + } + + /** + * Get the responses property: Backend model, prompt, and tools used when the Live session delegates a task to + * Responses. + * + * @return the responses value. + */ + @Generated + public ResponsesDelegationConfig getResponses() { + return this.responses; + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + if (this.responses != null) { + jsonWriter.writeFieldName("responses"); + OpenAIJsonHelper.toBinaryData(this.responses).writeTo(jsonWriter); + } + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeNumberField("acknowledgement_delay_ms", this.acknowledgementDelay); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveResponsesDelegation from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveResponsesDelegation if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveResponsesDelegation. + */ + public static VoiceAgentLiveResponsesDelegation fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + ResponsesDelegationConfig responses = null; + VoiceAgentLiveDelegationType type = VoiceAgentLiveDelegationType.RESPONSES; + Long acknowledgementDelay = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("responses".equals(fieldName)) { + BinaryData responsesData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + responses = OpenAIJsonHelper.fromBinaryData(responsesData, ResponsesDelegationConfig.class); + } else if ("type".equals(fieldName)) { + type = VoiceAgentLiveDelegationType.fromString(reader.getString()); + } else if ("acknowledgement_delay_ms".equals(fieldName)) { + acknowledgementDelay = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveResponsesDelegation deserializedVoiceAgentLiveResponsesDelegation + = new VoiceAgentLiveResponsesDelegation(responses); + deserializedVoiceAgentLiveResponsesDelegation.type = type; + deserializedVoiceAgentLiveResponsesDelegation.acknowledgementDelay = acknowledgementDelay; + return deserializedVoiceAgentLiveResponsesDelegation; + }); + } + + /* + * Milliseconds to wait before requesting an automatic spoken acknowledgement for a delegation. The model may still + * speak before this delay. Any commentary or thinking appended to the session cancels all pending acknowledgements, + * including those for other delegations. Defaults to 400 for Decisions sessions and 0 (request immediately) for + * other sessions. Omission in a session update preserves the current value. Updates apply to subsequent + * delegations. + */ + @Generated + private Long acknowledgementDelay; + + /** + * Get the acknowledgementDelay property: Milliseconds to wait before requesting an automatic spoken acknowledgement + * for a delegation. The model may still speak before this delay. Any commentary or thinking appended to the session + * cancels all pending acknowledgements, including those for other delegations. Defaults to 400 for Decisions + * sessions and 0 (request immediately) for other sessions. Omission in a session update preserves the current + * value. Updates apply to subsequent delegations. + * + * @return the acknowledgementDelay value. + */ + @Generated + public Duration getAcknowledgementDelay() { + if (this.acknowledgementDelay == null) { + return null; + } + return Duration.ofMillis(this.acknowledgementDelay); + } + + /** + * Set the acknowledgementDelay property: Milliseconds to wait before requesting an automatic spoken acknowledgement + * for a delegation. The model may still speak before this delay. Any commentary or thinking appended to the session + * cancels all pending acknowledgements, including those for other delegations. Defaults to 400 for Decisions + * sessions and 0 (request immediately) for other sessions. Omission in a session update preserves the current + * value. Updates apply to subsequent delegations. + * + * @param acknowledgementDelay the acknowledgementDelay value to set. + * @return the VoiceAgentLiveResponsesDelegation object itself. + */ + @Generated + public VoiceAgentLiveResponsesDelegation setAcknowledgementDelay(Duration acknowledgementDelay) { + if (acknowledgementDelay == null) { + this.acknowledgementDelay = null; + } else { + this.acknowledgementDelay = acknowledgementDelay.toMillis(); + } + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationConversationItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationConversationItem.java new file mode 100644 index 0000000000000..2a08ffff10bb1 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationConversationItem.java @@ -0,0 +1,145 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Stored Responses delegation output, separate from Live speech. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentLiveResponsesDelegationConversationItem extends VoiceAgentLiveDelegationConversationItem { + + /* + * The persisted item kind. + */ + @Generated + private final VoiceAgentLiveConversationItemType type = VoiceAgentLiveConversationItemType.DELEGATION; + + /* + * The configured delegation owner. + */ + @Generated + private VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.RESPONSES; + + /* + * Final backend text, omitted when unavailable; excludes raw tool output. + */ + @Generated + private String output; + + /** + * Creates an instance of VoiceAgentLiveResponsesDelegationConversationItem class. + * + * @param id the id value to set. + * @param createdAt the createdAt value to set. + */ + @Generated + private VoiceAgentLiveResponsesDelegationConversationItem(String id, OffsetDateTime createdAt) { + super(id, createdAt); + } + + /** + * Get the type property: The persisted item kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentLiveConversationItemType getType() { + return this.type; + } + + /** + * Get the target property: The configured delegation owner. + * + * @return the target value. + */ + @Generated + @Override + public VoiceAgentLiveDelegationTarget getTarget() { + return this.target; + } + + /** + * Get the output property: Final backend text, omitted when unavailable; excludes raw tool output. + * + * @return the output value. + */ + @Generated + public String getOutput() { + return this.output; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("id", getId()); + if (getCreatedAt() != null) { + jsonWriter.writeLongField("created_at", getCreatedAt().toEpochSecond()); + } + jsonWriter.writeStringField("response_id", getResponseId()); + jsonWriter.writeStringField("target", this.target == null ? null : this.target.toString()); + jsonWriter.writeStringField("output", this.output); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentLiveResponsesDelegationConversationItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentLiveResponsesDelegationConversationItem if the JsonReader was pointing to an + * instance of it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentLiveResponsesDelegationConversationItem. + */ + @Generated + public static VoiceAgentLiveResponsesDelegationConversationItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String id = null; + OffsetDateTime createdAt = null; + String responseId = null; + VoiceAgentLiveDelegationTarget target = VoiceAgentLiveDelegationTarget.RESPONSES; + String output = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("created_at".equals(fieldName)) { + createdAt = OffsetDateTime.ofInstant(Instant.ofEpochSecond(reader.getLong()), ZoneOffset.UTC); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else if ("target".equals(fieldName)) { + target = VoiceAgentLiveDelegationTarget.fromString(reader.getString()); + } else if ("output".equals(fieldName)) { + output = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentLiveResponsesDelegationConversationItem deserializedVoiceAgentLiveResponsesDelegationConversationItem + = new VoiceAgentLiveResponsesDelegationConversationItem(id, createdAt); + deserializedVoiceAgentLiveResponsesDelegationConversationItem.setResponseId(responseId); + deserializedVoiceAgentLiveResponsesDelegationConversationItem.target = target; + deserializedVoiceAgentLiveResponsesDelegationConversationItem.output = output; + return deserializedVoiceAgentLiveResponsesDelegationConversationItem; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveWebSocketConnectionOptions.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveWebSocketConnectionOptions.java new file mode 100644 index 0000000000000..06bc43c606477 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLiveWebSocketConnectionOptions.java @@ -0,0 +1,258 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.util.logging.ClientLogger; + +import java.time.Duration; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * Connection and buffering options for a persisted GPT Live voice agent. + * Configure these options before opening a session; clients snapshot them when opening. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +@Fluent +public final class VoiceAgentLiveWebSocketConnectionOptions { + private static final ClientLogger LOGGER = new ClientLogger(VoiceAgentLiveWebSocketConnectionOptions.class); + private int receiveBufferCapacity = 256; + private int maxMessageSize = 32 * 1024 * 1024; + private VoiceAgentWebSocketOverflowStrategy overflowStrategy = VoiceAgentWebSocketOverflowStrategy.ERROR; + private Consumer malformedEventHandler; + private Duration handshakeTimeout = Duration.ofSeconds(30); + private Duration closeTimeout = Duration.ofSeconds(10); + private Boolean store; + private String agentVersionOverride; + private String structuredInputs; + + /** + * Creates options with a 30-second handshake timeout and a 256-event receive buffer. + */ + public VoiceAgentLiveWebSocketConnectionOptions() { + } + + /** + * Copies connection options. + * + * @param source the options to copy. + */ + public VoiceAgentLiveWebSocketConnectionOptions(VoiceAgentLiveWebSocketConnectionOptions source) { + Objects.requireNonNull(source, "'source' cannot be null."); + this.receiveBufferCapacity = source.receiveBufferCapacity; + this.maxMessageSize = source.maxMessageSize; + this.overflowStrategy = source.overflowStrategy; + this.malformedEventHandler = source.malformedEventHandler; + this.handshakeTimeout = source.handshakeTimeout; + this.closeTimeout = source.closeTimeout; + this.store = source.store; + this.agentVersionOverride = source.agentVersionOverride; + this.structuredInputs = source.structuredInputs; + } + + /** + * Gets the receive queue capacity. + * + * @return the maximum queued events, default 256. + */ + public int getReceiveBufferCapacity() { + return receiveBufferCapacity; + } + + /** + * Sets the receive queue capacity. + * + * @param capacity the capacity, between 1 and 65536. + * @return this options instance. + * @throws IllegalArgumentException if the capacity is outside the supported range. + */ + public VoiceAgentLiveWebSocketConnectionOptions setReceiveBufferCapacity(int capacity) { + if (capacity < 1 || capacity > 65536) { + throw LOGGER + .logExceptionAsError(new IllegalArgumentException("Receive capacity must be between 1 and 65536.")); + } + this.receiveBufferCapacity = capacity; + return this; + } + + /** + * Gets the maximum accepted message size. + * + * @return the size in bytes, default 32 MiB. + */ + public int getMaxMessageSize() { + return maxMessageSize; + } + + /** + * Sets the maximum accepted message size. + * + * @param bytes the positive maximum message size in bytes. + * @return this options instance. + * @throws IllegalArgumentException if the size is not positive. + */ + public VoiceAgentLiveWebSocketConnectionOptions setMaxMessageSize(int bytes) { + if (bytes <= 0) { + throw LOGGER.logExceptionAsError(new IllegalArgumentException("Message size must be positive.")); + } + this.maxMessageSize = bytes; + return this; + } + + /** + * Gets the receive queue overflow strategy. + * + * @return the strategy, default ERROR. + */ + public VoiceAgentWebSocketOverflowStrategy getOverflowStrategy() { + return overflowStrategy; + } + + /** + * Sets the overflow strategy. Drop strategies explicitly permit event loss. + * + * @param strategy the non-null strategy. + * @return this options instance. + */ + public VoiceAgentLiveWebSocketConnectionOptions setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy strategy) { + this.overflowStrategy = Objects.requireNonNull(strategy, "'strategy' cannot be null."); + return this; + } + + /** + * Gets the callback for malformed events. + * + * @return the callback, or null to terminate the session. + */ + public Consumer getMalformedEventHandler() { + return malformedEventHandler; + } + + /** + * Sets a callback to report and skip malformed events. It runs while receiving events and must not block. + * JSON decoding failures are reported only by typed receivers; raw receivers do not parse JSON. + * Invalid UTF-8 is reported by the transport for either receiver type. + * If the callback throws, the session terminates. Transport errors and oversized messages are not skipped. + * + * @param handler the callback, or null to terminate on malformed events. + * @return this options instance. + */ + public VoiceAgentLiveWebSocketConnectionOptions setMalformedEventHandler(Consumer handler) { + this.malformedEventHandler = handler; + return this; + } + + /** + * Gets the handshake timeout. + * + * @return the timeout, default 30 seconds. + */ + public Duration getHandshakeTimeout() { + return handshakeTimeout; + } + + /** + * Sets the handshake timeout. + * + * @param timeout a non-null positive timeout. + * @return this options instance. + * @throws IllegalArgumentException if the timeout is not positive. + */ + public VoiceAgentLiveWebSocketConnectionOptions setHandshakeTimeout(Duration timeout) { + validatePositive(timeout, "handshakeTimeout"); + this.handshakeTimeout = timeout; + return this; + } + + /** + * Gets the close timeout. + * + * @return the timeout, default 10 seconds. + */ + public Duration getCloseTimeout() { + return closeTimeout; + } + + /** + * Sets the close timeout. + * + * @param timeout a non-null positive timeout. + * @return this options instance. + * @throws IllegalArgumentException if the timeout is not positive. + */ + public VoiceAgentLiveWebSocketConnectionOptions setCloseTimeout(Duration timeout) { + validatePositive(timeout, "closeTimeout"); + this.closeTimeout = timeout; + return this; + } + + /** + * Gets the persistence override. + * + * @return the override, or null to use the persisted agent configuration. + */ + public Boolean isStoreEnabled() { + return store; + } + + /** + * Overrides Foundry conversation and audio persistence for this session. + * + * @param store the override, or null to use the persisted agent configuration. + * @return this options instance. + */ + public VoiceAgentLiveWebSocketConnectionOptions setStoreEnabled(Boolean store) { + this.store = store; + return this; + } + + /** + * Gets the agent version override. + * + * @return the version override, or null. + */ + public String getAgentVersionOverride() { + return agentVersionOverride; + } + + /** + * Sets the agent version to connect to. + * + * @param version the version override, or null to use the default version. + * @return this options instance. + */ + public VoiceAgentLiveWebSocketConnectionOptions setAgentVersionOverride(String version) { + this.agentVersionOverride = version; + return this; + } + + /** + * Gets structured inputs for instruction and greeting templates. + * + * @return the JSON inputs, or null. + */ + public String getStructuredInputs() { + return structuredInputs; + } + + /** + * Sets the JSON inputs for instruction and greeting templates. + * The SDK URL-encodes this value into the {@code structured_inputs} query parameter. + * + * @param inputs the unencoded JSON inputs, or null. + * @return this options instance. + */ + public VoiceAgentLiveWebSocketConnectionOptions setStructuredInputs(String inputs) { + this.structuredInputs = inputs; + return this; + } + + private static void validatePositive(Duration duration, String name) { + if (duration == null || duration.isZero() || duration.isNegative()) { + throw new IllegalArgumentException("'" + name + "' must be positive."); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java index 002ae2f8f0648..457b562ea9dc0 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java @@ -10,10 +10,6 @@ import com.azure.json.JsonReader; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import java.io.IOException; /** @@ -27,7 +23,7 @@ public final class VoiceAgentLlmGeneratedGreetingConfiguration extends VoiceAgen * The greeting mode. */ @Generated - private String type = "llm_generated"; + private VoiceAgentGreetingMode type = VoiceAgentGreetingMode.LLM_GENERATED; /* * The Handlebars prompt that guides the opening turn. @@ -58,7 +54,7 @@ public VoiceAgentLlmGeneratedGreetingConfiguration(String prompt) { */ @Generated @Override - public String getType() { + public VoiceAgentGreetingMode getType() { return this.type; } @@ -75,22 +71,20 @@ public String getPrompt() { /** * Get the toolChoice property: The tool-selection policy for the opening response. Defaults to `none`. * - * @return the toolChoice value. + * @return the tool choice, or {@code null} when absent or JSON null. */ - BinaryData getToolChoice() { - // AI Tooling: union type - return this.toolChoice; + public VoiceAgentToolChoice getToolChoice() { + return this.toolChoice == null ? null : this.toolChoice.toObject(VoiceAgentToolChoice.class); } /** * Set the toolChoice property: The tool-selection policy for the opening response. Defaults to `none`. * - * @param toolChoice the toolChoice value to set. + * @param toolChoice the tool choice, or {@code null} to clear the property. * @return the VoiceAgentLlmGeneratedGreetingConfiguration object itself. */ - VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(BinaryData toolChoice) { - // AI Tooling: union type - this.toolChoice = toolChoice; + public VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(VoiceAgentToolChoice toolChoice) { + this.toolChoice = toolChoice == null ? null : BinaryData.fromObject(toolChoice); return this; } @@ -102,7 +96,7 @@ VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(BinaryData toolChoice) public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("prompt", this.prompt); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); if (this.toolChoice != null) { jsonWriter.writeFieldName("tool_choice"); this.toolChoice.writeTo(jsonWriter); @@ -123,7 +117,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static VoiceAgentLlmGeneratedGreetingConfiguration fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String prompt = null; - String type = "llm_generated"; + VoiceAgentGreetingMode type = VoiceAgentGreetingMode.LLM_GENERATED; BinaryData toolChoice = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); @@ -131,7 +125,7 @@ public static VoiceAgentLlmGeneratedGreetingConfiguration fromJson(JsonReader js if ("prompt".equals(fieldName)) { prompt = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentGreetingMode.fromString(reader.getString()); } else if ("tool_choice".equals(fieldName)) { toolChoice = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); @@ -146,110 +140,4 @@ public static VoiceAgentLlmGeneratedGreetingConfiguration fromJson(JsonReader js return deserializedVoiceAgentLlmGeneratedGreetingConfiguration; }); } - - /** - * Set the toolChoice property: The tool-selection policy for the opening response. Defaults to `none`. - * - * @param toolChoice the {@link ToolChoiceOptions} mode to set ({@code NONE}, {@code AUTO} or {@code REQUIRED}). - * @return the VoiceAgentLlmGeneratedGreetingConfiguration object itself. - */ - public VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(ToolChoiceOptions toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Set the toolChoice property to a specific function tool: The tool-selection policy for the opening response. - * Defaults to `none`. - * - * @param toolChoice the openai-java {@link ToolChoiceFunction} to set, or null to clear. - * @return the VoiceAgentLlmGeneratedGreetingConfiguration object itself. - */ - public VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(ToolChoiceFunction toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceFunction}: The tool-selection policy for the - * opening response. Defaults to `none`. - * - * @return the toolChoice value as a ToolChoiceFunction, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceFunction getToolChoiceAsToolChoiceFunction() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isFunction()) { - return null; - } - return choice.asFunction(); - } - - /** - * Set the toolChoice property to a specific MCP tool: The tool-selection policy for the opening response. Defaults - * to `none`. - * - * @param toolChoice the openai-java {@link ToolChoiceMcp} to set, or null to clear. - * @return the VoiceAgentLlmGeneratedGreetingConfiguration object itself. - */ - public VoiceAgentLlmGeneratedGreetingConfiguration setToolChoice(ToolChoiceMcp toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceMcp}: The tool-selection policy for the opening - * response. Defaults to `none`. - * - * @return the toolChoice value as a ToolChoiceMcp, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceMcp getToolChoiceAsToolChoiceMcp() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isMcp()) { - return null; - } - return choice.asMcp(); - } - - private ResponseCreateParams.ToolChoice getOpenAIToolChoice() { - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!json.startsWith("{")) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ResponseCreateParams.ToolChoice.class); - } - - /** - * Get the toolChoice property: The tool-selection policy for the opening response. Defaults to `none`. - * - * @return the toolChoice value as a {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another - * variant. - */ - public ToolChoiceOptions getToolChoiceAsToolChoiceOptions() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ToolChoiceOptions.class); - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java index 9286bdbb5f4be..fdc35cc6067ea 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java @@ -24,7 +24,7 @@ public final class VoiceAgentLlmInterimResponseConfiguration extends VoiceAgentI * The interim-response implementation. */ @Generated - private String type = "llm_interim_response"; + private VoiceAgentInterimResponseType type = VoiceAgentInterimResponseType.LLM_INTERIM_RESPONSE; /* * The model used to generate interim responses. @@ -58,7 +58,7 @@ public VoiceAgentLlmInterimResponseConfiguration() { */ @Generated @Override - public String getType() { + public VoiceAgentInterimResponseType getType() { return this.type; } @@ -160,7 +160,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { if (getLatencyThresholdMs() != null) { jsonWriter.writeNumberField("latency_threshold_ms", getLatencyThresholdMs().toMillis()); } - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("model", this.model); jsonWriter.writeStringField("instructions", this.instructions); jsonWriter.writeNumberField("max_completion_tokens", this.maxCompletionTokens); @@ -194,7 +194,8 @@ public static VoiceAgentLlmInterimResponseConfiguration fromJson(JsonReader json .setLatencyThresholdMs(Duration.ofMillis(latencyThresholdMsHolder)); } } else if ("type".equals(fieldName)) { - deserializedVoiceAgentLlmInterimResponseConfiguration.type = reader.getString(); + deserializedVoiceAgentLlmInterimResponseConfiguration.type + = VoiceAgentInterimResponseType.fromString(reader.getString()); } else if ("model".equals(fieldName)) { deserializedVoiceAgentLlmInterimResponseConfiguration.model = reader.getString(); } else if ("instructions".equals(fieldName)) { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokens.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokens.java new file mode 100644 index 0000000000000..fee44faa9226c --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokens.java @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Immutable; +import com.azure.core.util.logging.ClientLogger; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonWriter; + +import java.io.IOException; + +/** + * An output-token limit for a voice agent, expressed as a token count or the model's maximum available output tokens. + * + *

Use {@code VoiceAgentMaxOutputTokens.of(1024)} for a numeric limit or {@link #MAXIMUM} for the {@code "inf"} variant. + * The same type can be used with {@code setMaxOutputTokens} and {@code setMaxResponseOutputTokens}. + * Pass {@code null} to a model's setter to clear the property.

+ * + *

Unrecognized string values read from JSON are preserved when serialized again. For those values, + * {@link #asInteger()} returns {@code null} and {@link #isMaximum()} returns {@code false}.

+ */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentMaxOutputTokens implements JsonSerializable { + private static final ClientLogger LOGGER = new ClientLogger(VoiceAgentMaxOutputTokens.class); + + /** + * Uses the model's maximum available output tokens, represented as {@code "inf"} in JSON. + */ + public static final VoiceAgentMaxOutputTokens MAXIMUM = new VoiceAgentMaxOutputTokens(null, "inf"); + + private final Integer count; + + private final String stringValue; + + private VoiceAgentMaxOutputTokens(Integer count, String stringValue) { + this.count = count; + this.stringValue = stringValue; + } + + /** + * Creates a numeric output-token limit. The service validates the count for the selected model and operation. + * + * @param count the maximum number of output tokens. + * @return the token limit. + */ + public static VoiceAgentMaxOutputTokens of(int count) { + return new VoiceAgentMaxOutputTokens(count, null); + } + + /** + * Gets the numeric output-token limit. + * + * @return the count, or {@code null} if this limit holds a string variant. + */ + public Integer asInteger() { + return count; + } + + /** + * Gets whether this limit uses the model's maximum available output tokens. + * + * @return {@code true} for the {@code "inf"} variant; otherwise, {@code false}. + */ + public boolean isMaximum() { + return "inf".equals(stringValue); + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + return count == null ? jsonWriter.writeString(stringValue) : jsonWriter.writeInt(count); + } + + /** + * Reads a token limit from a JSON integer or string. + * + * @param jsonReader the JSON reader. + * @return the token limit, or {@code null} for JSON null. + * @throws IOException if the JSON cannot be read. + * @throws IllegalStateException if the value is not an integer representable as an int or a string. + */ + public static VoiceAgentMaxOutputTokens fromJson(JsonReader jsonReader) throws IOException { + Object value = jsonReader.readUntyped(); + if (value == null) { + return null; + } + if (value instanceof Integer) { + return of((Integer) value); + } + if (value instanceof String) { + return "inf".equals(value) ? MAXIMUM : new VoiceAgentMaxOutputTokens(null, (String) value); + } + throw LOGGER.logExceptionAsError(new IllegalStateException("Token limit must be a JSON integer or string.")); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java index d1bdce48b860e..a9ce5f68be8a6 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java @@ -27,7 +27,7 @@ public final class VoiceAgentMcpTool extends VoiceAgentTool { * The tool kind. */ @Generated - private String type = "mcp"; + private VoiceAgentToolType type = VoiceAgentToolType.MCP; /* * A label for this MCP server, used to identify it in tool calls. @@ -122,7 +122,7 @@ public VoiceAgentMcpTool(String serverLabel) { */ @Generated @Override - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -396,7 +396,7 @@ public VoiceAgentMcpTool setResponseScheduling(VoiceAgentToolResponseScheduling public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("server_label", this.serverLabel); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("server_url", this.serverUrl); jsonWriter.writeStringField("authorization", this.authorization); jsonWriter.writeStringField("server_description", this.serverDescription); @@ -432,7 +432,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static VoiceAgentMcpTool fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String serverLabel = null; - String type = "mcp"; + VoiceAgentToolType type = VoiceAgentToolType.MCP; String serverUrl = null; String authorization = null; String serverDescription = null; @@ -450,7 +450,7 @@ public static VoiceAgentMcpTool fromJson(JsonReader jsonReader) throws IOExcepti if ("server_label".equals(fieldName)) { serverLabel = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentToolType.fromString(reader.getString()); } else if ("server_url".equals(fieldName)) { serverUrl = reader.getString(); } else if ("authorization".equals(fieldName)) { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallConfiguration.java new file mode 100644 index 0000000000000..d8fd25fca6ae7 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallConfiguration.java @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Post-call delivery configuration. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentPostCallConfiguration implements JsonSerializable { + + /* + * The destinations to notify. + */ + @Generated + private final List destinations; + + /* + * Additional content to include in each delivery. The transcript is always delivered. `audio` is not supported in + * this preview; the service rejects it when the agent version is saved. + */ + @Generated + private List include; + + /** + * Creates an instance of VoiceAgentPostCallConfiguration class. + * + * @param destinations the destinations value to set. + */ + @Generated + public VoiceAgentPostCallConfiguration(List destinations) { + this.destinations = destinations; + } + + /** + * Get the destinations property: The destinations to notify. + * + * @return the destinations value. + */ + @Generated + public List getDestinations() { + return this.destinations; + } + + /** + * Get the include property: Additional content to include in each delivery. The transcript is always delivered. + * `audio` is not supported in this preview; the service rejects it when the agent version is saved. + * + * @return the include value. + */ + @Generated + public List getInclude() { + return this.include; + } + + /** + * Set the include property: Additional content to include in each delivery. The transcript is always delivered. + * `audio` is not supported in this preview; the service rejects it when the agent version is saved. + * + * @param include the include value to set. + * @return the VoiceAgentPostCallConfiguration object itself. + */ + @Generated + public VoiceAgentPostCallConfiguration setInclude(List include) { + this.include = include; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeArrayField("destinations", this.destinations, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeArrayField("include", this.include, + (writer, element) -> writer.writeString(element == null ? null : element.toString())); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentPostCallConfiguration from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentPostCallConfiguration if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentPostCallConfiguration. + */ + @Generated + public static VoiceAgentPostCallConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + List destinations = null; + List include = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("destinations".equals(fieldName)) { + destinations = reader.readArray(reader1 -> VoiceAgentPostCallDestination.fromJson(reader1)); + } else if ("include".equals(fieldName)) { + include + = reader.readArray(reader1 -> VoiceAgentPostCallIncludeOption.fromString(reader1.getString())); + } else { + reader.skipChildren(); + } + } + VoiceAgentPostCallConfiguration deserializedVoiceAgentPostCallConfiguration + = new VoiceAgentPostCallConfiguration(destinations); + deserializedVoiceAgentPostCallConfiguration.include = include; + return deserializedVoiceAgentPostCallConfiguration; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpError.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestination.java similarity index 60% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpError.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestination.java index c65c8857aaac3..6acd910df374c 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/RealtimeMcpError.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestination.java @@ -13,32 +13,33 @@ import java.io.IOException; /** - * The RealtimeMcpError model. + * A post-call destination. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public class RealtimeMcpError implements JsonSerializable { +public class VoiceAgentPostCallDestination implements JsonSerializable { /* - * The type property. + * The destination type. */ @Generated - private RealtimeMcpErrorType type = RealtimeMcpErrorType.fromString("RealtimeMcpError"); + private VoiceAgentPostCallDestinationType type + = VoiceAgentPostCallDestinationType.fromString("VoiceAgentPostCallDestination"); /** - * Creates an instance of RealtimeMcpError class. + * Creates an instance of VoiceAgentPostCallDestination class. */ @Generated - protected RealtimeMcpError() { + protected VoiceAgentPostCallDestination() { } /** - * Get the type property: The type property. + * Get the type property: The destination type. * * @return the type value. */ @Generated - public RealtimeMcpErrorType getType() { + public VoiceAgentPostCallDestinationType getType() { return this.type; } @@ -54,15 +55,15 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } /** - * Reads an instance of RealtimeMcpError from the JsonReader. + * Reads an instance of VoiceAgentPostCallDestination from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of RealtimeMcpError if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IOException If an error occurs while reading the RealtimeMcpError. + * @return An instance of VoiceAgentPostCallDestination if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentPostCallDestination. */ @Generated - public static RealtimeMcpError fromJson(JsonReader jsonReader) throws IOException { + public static VoiceAgentPostCallDestination fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String discriminatorValue = null; try (JsonReader readerToUse = reader.bufferObject()) { @@ -79,12 +80,10 @@ public static RealtimeMcpError fromJson(JsonReader jsonReader) throws IOExceptio } } // Use the discriminator value to determine which subtype should be deserialized. - if ("protocol_error".equals(discriminatorValue)) { - return RealtimeMcpProtocolError.fromJson(readerToUse.reset()); - } else if ("tool_execution_error".equals(discriminatorValue)) { - return RealtimeMcpToolExecutionError.fromJson(readerToUse.reset()); - } else if ("http_error".equals(discriminatorValue)) { - return RealtimeMcpHttpError.fromJson(readerToUse.reset()); + if ("event_grid".equals(discriminatorValue)) { + return VoiceAgentEventGridPostCallDestination.fromJson(readerToUse.reset()); + } else if ("routine".equals(discriminatorValue)) { + return VoiceAgentRoutinePostCallDestination.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } @@ -93,19 +92,21 @@ public static RealtimeMcpError fromJson(JsonReader jsonReader) throws IOExceptio } @Generated - static RealtimeMcpError fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + static VoiceAgentPostCallDestination fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - RealtimeMcpError deserializedRealtimeMcpError = new RealtimeMcpError(); + VoiceAgentPostCallDestination deserializedVoiceAgentPostCallDestination + = new VoiceAgentPostCallDestination(); while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - deserializedRealtimeMcpError.type = RealtimeMcpErrorType.fromString(reader.getString()); + deserializedVoiceAgentPostCallDestination.type + = VoiceAgentPostCallDestinationType.fromString(reader.getString()); } else { reader.skipChildren(); } } - return deserializedRealtimeMcpError; + return deserializedVoiceAgentPostCallDestination; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestinationType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestinationType.java new file mode 100644 index 0000000000000..2785dc9cb326a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestinationType.java @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The type of a post-call destination. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentPostCallDestinationType extends ExpandableStringEnum { + + /** + * An Event Grid connection. + */ + @Generated + public static final VoiceAgentPostCallDestinationType EVENT_GRID = fromString("event_grid"); + + /** + * A routine. + */ + @Generated + public static final VoiceAgentPostCallDestinationType ROUTINE = fromString("routine"); + + /** + * Creates a new instance of VoiceAgentPostCallDestinationType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentPostCallDestinationType() { + } + + /** + * Creates or finds a VoiceAgentPostCallDestinationType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentPostCallDestinationType. + */ + @Generated + public static VoiceAgentPostCallDestinationType fromString(String name) { + return fromString(name, VoiceAgentPostCallDestinationType.class); + } + + /** + * Gets known VoiceAgentPostCallDestinationType values. + * + * @return known VoiceAgentPostCallDestinationType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentPostCallDestinationType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallIncludeOption.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallIncludeOption.java new file mode 100644 index 0000000000000..b8728264818e2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallIncludeOption.java @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Content that can be included in a post-call delivery. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentPostCallIncludeOption extends ExpandableStringEnum { + + /** + * A URL to the merged call recording. Not supported in this preview: the service rejects `audio` when the agent + * version is saved. + */ + @Generated + public static final VoiceAgentPostCallIncludeOption AUDIO = fromString("audio"); + + /** + * Creates a new instance of VoiceAgentPostCallIncludeOption value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentPostCallIncludeOption() { + } + + /** + * Creates or finds a VoiceAgentPostCallIncludeOption from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentPostCallIncludeOption. + */ + @Generated + public static VoiceAgentPostCallIncludeOption fromString(String name) { + return fromString(name, VoiceAgentPostCallIncludeOption.class); + } + + /** + * Gets known VoiceAgentPostCallIncludeOption values. + * + * @return known VoiceAgentPostCallIncludeOption values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentPostCallIncludeOption.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java index 1ca6dc1ac4134..2408f60f335ee 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java @@ -134,9 +134,9 @@ public List getOutput() { * * @return the maxOutputTokens value. */ - BinaryData getMaxOutputTokens() { + public VoiceAgentMaxOutputTokens getMaxOutputTokens() { // AI Tooling: union type - return this.maxOutputTokens; + return this.maxOutputTokens == null ? null : this.maxOutputTokens.toObject(VoiceAgentMaxOutputTokens.class); } /** @@ -243,9 +243,9 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("conversation_id", getConversationId()); jsonWriter.writeArrayField("output_modalities", getOutputModalities(), (writer, element) -> writer.writeString(element == null ? null : element.toString())); - if (getMaxOutputTokens() != null) { + if (this.maxOutputTokens != null) { jsonWriter.writeFieldName("max_output_tokens"); - getMaxOutputTokens().writeTo(jsonWriter); + this.maxOutputTokens.writeTo(jsonWriter); } jsonWriter.writeJsonField("audio", this.audio); jsonWriter.writeArrayField("output", this.output, (writer, element) -> writer.writeJson(element)); @@ -326,40 +326,4 @@ public static VoiceAgentRealtimeResponse fromJson(JsonReader jsonReader) throws public VoiceResponseObjectType getObjectType() { return this.objectType; } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response, inclusive of - * tool calls, that was used in this response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response, inclusive of - * tool calls, that was used in this response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java index e69a57a7ca84f..390d8c2e424af 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java @@ -77,7 +77,7 @@ public final class VoiceAgentResponseAudioTimestampDeltaEvent extends RealtimeSe * The timestamp_type property. */ @Generated - private final String timestampType = "word"; + private final VoiceAgentAudioTimestampType timestampType = VoiceAgentAudioTimestampType.WORD; /** * Creates an instance of VoiceAgentResponseAudioTimestampDeltaEvent class. @@ -209,7 +209,7 @@ public String getText() { * @return the timestampType value. */ @Generated - public String getTimestampType() { + public VoiceAgentAudioTimestampType getTimestampType() { return this.timestampType; } @@ -228,7 +228,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeLongField("audio_offset_ms", this.audioOffset); jsonWriter.writeLongField("audio_duration_ms", this.audioDuration); jsonWriter.writeStringField("text", this.text); - jsonWriter.writeStringField("timestamp_type", this.timestampType); + jsonWriter.writeStringField("timestamp_type", + this.timestampType == null ? null : this.timestampType.toString()); jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java index 972329ebd593a..d393abde73e4c 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java @@ -15,10 +15,6 @@ import com.openai.models.realtime.RealtimeReasoning; import com.openai.models.realtime.RealtimeResponseCreateParams; import com.openai.models.realtime.RealtimeResponseCreateParams.Conversation; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import java.io.IOException; import java.util.List; import java.util.Map; @@ -219,23 +215,21 @@ public VoiceAgentResponseCreateOptions setToolsAsOpenAITools(List { + String name = null; + VoiceAgentPostCallDestinationType type = VoiceAgentPostCallDestinationType.ROUTINE; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("name".equals(fieldName)) { + name = reader.getString(); + } else if ("type".equals(fieldName)) { + type = VoiceAgentPostCallDestinationType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentRoutinePostCallDestination deserializedVoiceAgentRoutinePostCallDestination + = new VoiceAgentRoutinePostCallDestination(name); + deserializedVoiceAgentRoutinePostCallDestination.type = type; + return deserializedVoiceAgentRoutinePostCallDestination; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java index 3ccea9e7956a3..1cde6a835c9ef 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java @@ -25,7 +25,7 @@ public final class VoiceAgentRtcCallErrorDetails implements JsonSerializable { - String type = null; + VoiceAgentRtcCallErrorType type = null; String message = null; String code = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentRtcCallErrorType.fromString(reader.getString()); } else if ("message".equals(fieldName)) { message = reader.getString(); } else if ("code".equals(fieldName)) { @@ -130,4 +118,16 @@ public static VoiceAgentRtcCallErrorDetails fromJson(JsonReader jsonReader) thro return deserializedVoiceAgentRtcCallErrorDetails; }); } + + /** + * Creates an instance of VoiceAgentRtcCallErrorDetails class. + * + * @param type the type value to set. + * @param message the message value to set. + */ + @Generated + private VoiceAgentRtcCallErrorDetails(VoiceAgentRtcCallErrorType type, String message) { + this.type = type; + this.message = message; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorType.java new file mode 100644 index 0000000000000..21ffd4e221ed3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorType.java @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The error categories reported for WebRTC signaling failures. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentRtcCallErrorType extends ExpandableStringEnum { + + /** + * A client-side signaling fault, such as a malformed SDP offer. + */ + @Generated + public static final VoiceAgentRtcCallErrorType INVALID_REQUEST_ERROR = fromString("invalid_request_error"); + + /** + * A service-side signaling failure. + */ + @Generated + public static final VoiceAgentRtcCallErrorType SERVER_ERROR = fromString("server_error"); + + /** + * Creates a new instance of VoiceAgentRtcCallErrorType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentRtcCallErrorType() { + } + + /** + * Creates or finds a VoiceAgentRtcCallErrorType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentRtcCallErrorType. + */ + @Generated + public static VoiceAgentRtcCallErrorType fromString(String name) { + return fromString(name, VoiceAgentRtcCallErrorType.class); + } + + /** + * Gets known VoiceAgentRtcCallErrorType values. + * + * @return known VoiceAgentRtcCallErrorType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentRtcCallErrorType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendDtmfSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendDtmfSystemTool.java new file mode 100644 index 0000000000000..989492e45cec8 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendDtmfSystemTool.java @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Sends literal or templated keypad digits. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSendDtmfSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.SEND_DTMF; + + /** + * Creates an instance of VoiceAgentSendDtmfSystemTool class. + */ + @Generated + public VoiceAgentSendDtmfSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentSendDtmfSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSendDtmfSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSendDtmfSystemTool if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentSendDtmfSystemTool. + */ + @Generated + public static VoiceAgentSendDtmfSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentSendDtmfSystemTool deserializedVoiceAgentSendDtmfSystemTool = new VoiceAgentSendDtmfSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentSendDtmfSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentSendDtmfSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentSendDtmfSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentSendDtmfSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentSendDtmfSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendSmsSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendSmsSystemTool.java new file mode 100644 index 0000000000000..3da469a3a2d67 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSendSmsSystemTool.java @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * Sends a text message from the Agent's SMS-capable number. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSendSmsSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.SEND_SMS; + + /** + * Creates an instance of VoiceAgentSendSmsSystemTool class. + */ + @Generated + public VoiceAgentSendSmsSystemTool() { + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentSendSmsSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSendSmsSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSendSmsSystemTool if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentSendSmsSystemTool. + */ + @Generated + public static VoiceAgentSendSmsSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentSendSmsSystemTool deserializedVoiceAgentSendSmsSystemTool = new VoiceAgentSendSmsSystemTool(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + deserializedVoiceAgentSendSmsSystemTool.setDescription(reader.getString()); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + deserializedVoiceAgentSendSmsSystemTool.setTimeout(Duration.ofSeconds(timeoutHolder)); + } + } else if ("name".equals(fieldName)) { + deserializedVoiceAgentSendSmsSystemTool.name + = VoiceAgentSystemToolName.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentSendSmsSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentSendSmsSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffAbortedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffAbortedEvent.java new file mode 100644 index 0000000000000..7a09ffafbe5dd --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffAbortedEvent.java @@ -0,0 +1,337 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.core.util.BinaryData; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeError; +import java.io.IOException; + +/** + * The `session.handoff.aborted` server event. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSessionHandoffAbortedEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_ABORTED; + + /* + * The server-generated event identifier. + */ + @Generated + private final String eventId; + + /* + * The server-generated handoff attempt identifier. + */ + @Generated + private final String handoffId; + + /* + * The configured edge selected for this handoff. + */ + @Generated + private final String edgeId; + + /* + * The source node identifier or `$entrypoint`. + */ + @Generated + private final String fromNodeId; + + /* + * The target node identifier or `$entrypoint`. + */ + @Generated + private final String toNodeId; + + /* + * The model active before the handoff. + */ + @Generated + private final String fromModel; + + /* + * The model prepared for the target behavior. + */ + @Generated + private final String toModel; + + /* + * The function-call identifier that initiated the handoff. + */ + @Generated + private final String toolCallId; + + /* + * The source generation for started or aborted events, and the committed target generation for completed events. + */ + @Generated + private final int nodeGeneration; + + /* + * Why the handoff ended before target commit. + */ + @Generated + private final VoiceAgentHandoffAbortReason reason; + + /* + * The handoff failure detail when `reason` is `error`. + */ + @Generated + private RealtimeError error; + + /** + * Creates an instance of VoiceAgentSessionHandoffAbortedEvent class. + * + * @param eventId the eventId value to set. + * @param handoffId the handoffId value to set. + * @param edgeId the edgeId value to set. + * @param fromNodeId the fromNodeId value to set. + * @param toNodeId the toNodeId value to set. + * @param fromModel the fromModel value to set. + * @param toModel the toModel value to set. + * @param toolCallId the toolCallId value to set. + * @param nodeGeneration the nodeGeneration value to set. + * @param reason the reason value to set. + */ + @Generated + private VoiceAgentSessionHandoffAbortedEvent(String eventId, String handoffId, String edgeId, String fromNodeId, + String toNodeId, String fromModel, String toModel, String toolCallId, int nodeGeneration, + VoiceAgentHandoffAbortReason reason) { + this.eventId = eventId; + this.handoffId = handoffId; + this.edgeId = edgeId; + this.fromNodeId = fromNodeId; + this.toNodeId = toNodeId; + this.fromModel = fromModel; + this.toModel = toModel; + this.toolCallId = toolCallId; + this.nodeGeneration = nodeGeneration; + this.reason = reason; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: The server-generated event identifier. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the handoffId property: The server-generated handoff attempt identifier. + * + * @return the handoffId value. + */ + @Generated + public String getHandoffId() { + return this.handoffId; + } + + /** + * Get the edgeId property: The configured edge selected for this handoff. + * + * @return the edgeId value. + */ + @Generated + public String getEdgeId() { + return this.edgeId; + } + + /** + * Get the fromNodeId property: The source node identifier or `$entrypoint`. + * + * @return the fromNodeId value. + */ + @Generated + public String getFromNodeId() { + return this.fromNodeId; + } + + /** + * Get the toNodeId property: The target node identifier or `$entrypoint`. + * + * @return the toNodeId value. + */ + @Generated + public String getToNodeId() { + return this.toNodeId; + } + + /** + * Get the fromModel property: The model active before the handoff. + * + * @return the fromModel value. + */ + @Generated + public String getFromModel() { + return this.fromModel; + } + + /** + * Get the toModel property: The model prepared for the target behavior. + * + * @return the toModel value. + */ + @Generated + public String getToModel() { + return this.toModel; + } + + /** + * Get the toolCallId property: The function-call identifier that initiated the handoff. + * + * @return the toolCallId value. + */ + @Generated + public String getToolCallId() { + return this.toolCallId; + } + + /** + * Get the nodeGeneration property: The source generation for started or aborted events, and the committed target + * generation for completed events. + * + * @return the nodeGeneration value. + */ + @Generated + public int getNodeGeneration() { + return this.nodeGeneration; + } + + /** + * Get the reason property: Why the handoff ended before target commit. + * + * @return the reason value. + */ + @Generated + public VoiceAgentHandoffAbortReason getReason() { + return this.reason; + } + + /** + * Get the error property: The handoff failure detail when `reason` is `error`. + * + * @return the error value. + */ + @Generated + public RealtimeError getError() { + return this.error; + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + // AI Tooling: openai-java de-dup + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("handoff_id", this.handoffId); + jsonWriter.writeStringField("edge_id", this.edgeId); + jsonWriter.writeStringField("from_node_id", this.fromNodeId); + jsonWriter.writeStringField("to_node_id", this.toNodeId); + jsonWriter.writeStringField("from_model", this.fromModel); + jsonWriter.writeStringField("to_model", this.toModel); + jsonWriter.writeStringField("tool_call_id", this.toolCallId); + jsonWriter.writeIntField("node_generation", this.nodeGeneration); + jsonWriter.writeStringField("reason", this.reason == null ? null : this.reason.toString()); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + if (this.error != null) { + jsonWriter.writeFieldName("error"); + OpenAIJsonHelper.toBinaryData(this.error).writeTo(jsonWriter); + } + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSessionHandoffAbortedEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSessionHandoffAbortedEvent if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSessionHandoffAbortedEvent. + */ + public static VoiceAgentSessionHandoffAbortedEvent fromJson(JsonReader jsonReader) throws IOException { + // AI Tooling: openai-java de-dup + return jsonReader.readObject(reader -> { + String eventId = null; + String handoffId = null; + String edgeId = null; + String fromNodeId = null; + String toNodeId = null; + String fromModel = null; + String toModel = null; + String toolCallId = null; + int nodeGeneration = 0; + VoiceAgentHandoffAbortReason reason = null; + RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_ABORTED; + RealtimeError error = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("handoff_id".equals(fieldName)) { + handoffId = reader.getString(); + } else if ("edge_id".equals(fieldName)) { + edgeId = reader.getString(); + } else if ("from_node_id".equals(fieldName)) { + fromNodeId = reader.getString(); + } else if ("to_node_id".equals(fieldName)) { + toNodeId = reader.getString(); + } else if ("from_model".equals(fieldName)) { + fromModel = reader.getString(); + } else if ("to_model".equals(fieldName)) { + toModel = reader.getString(); + } else if ("tool_call_id".equals(fieldName)) { + toolCallId = reader.getString(); + } else if ("node_generation".equals(fieldName)) { + nodeGeneration = reader.getInt(); + } else if ("reason".equals(fieldName)) { + reason = VoiceAgentHandoffAbortReason.fromString(reader.getString()); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else if ("error".equals(fieldName)) { + BinaryData errorData = reader.getNullable(r -> BinaryData.fromObject(r.readUntyped())); + error = OpenAIJsonHelper.fromBinaryData(errorData, RealtimeError.class); + } else { + reader.skipChildren(); + } + } + VoiceAgentSessionHandoffAbortedEvent deserializedVoiceAgentSessionHandoffAbortedEvent + = new VoiceAgentSessionHandoffAbortedEvent(eventId, handoffId, edgeId, fromNodeId, toNodeId, fromModel, + toModel, toolCallId, nodeGeneration, reason); + deserializedVoiceAgentSessionHandoffAbortedEvent.type = type; + deserializedVoiceAgentSessionHandoffAbortedEvent.error = error; + return deserializedVoiceAgentSessionHandoffAbortedEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffCompletedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffCompletedEvent.java new file mode 100644 index 0000000000000..2c8f0eff5822d --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffCompletedEvent.java @@ -0,0 +1,340 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * The `session.handoff.completed` server event. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSessionHandoffCompletedEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_COMPLETED; + + /* + * The server-generated event identifier. + */ + @Generated + private final String eventId; + + /* + * The server-generated handoff attempt identifier. + */ + @Generated + private final String handoffId; + + /* + * The configured edge selected for this handoff. + */ + @Generated + private final String edgeId; + + /* + * The source node identifier or `$entrypoint`. + */ + @Generated + private final String fromNodeId; + + /* + * The target node identifier or `$entrypoint`. + */ + @Generated + private final String toNodeId; + + /* + * The model active before the handoff. + */ + @Generated + private final String fromModel; + + /* + * The model prepared for the target behavior. + */ + @Generated + private final String toModel; + + /* + * The function-call identifier that initiated the handoff. + */ + @Generated + private final String toolCallId; + + /* + * The source generation for started or aborted events, and the committed target generation for completed events. + */ + @Generated + private final int nodeGeneration; + + /* + * The target-preparation duration. + */ + @Generated + private final long prepareDuration; + + /* + * The total handoff duration. + */ + @Generated + private final long duration; + + /** + * Creates an instance of VoiceAgentSessionHandoffCompletedEvent class. + * + * @param eventId the eventId value to set. + * @param handoffId the handoffId value to set. + * @param edgeId the edgeId value to set. + * @param fromNodeId the fromNodeId value to set. + * @param toNodeId the toNodeId value to set. + * @param fromModel the fromModel value to set. + * @param toModel the toModel value to set. + * @param toolCallId the toolCallId value to set. + * @param nodeGeneration the nodeGeneration value to set. + * @param prepareDuration the prepareDuration value to set. + * @param duration the duration value to set. + */ + @Generated + private VoiceAgentSessionHandoffCompletedEvent(String eventId, String handoffId, String edgeId, String fromNodeId, + String toNodeId, String fromModel, String toModel, String toolCallId, int nodeGeneration, + Duration prepareDuration, Duration duration) { + this.eventId = eventId; + this.handoffId = handoffId; + this.edgeId = edgeId; + this.fromNodeId = fromNodeId; + this.toNodeId = toNodeId; + this.fromModel = fromModel; + this.toModel = toModel; + this.toolCallId = toolCallId; + this.nodeGeneration = nodeGeneration; + if (prepareDuration == null) { + this.prepareDuration = 0L; + } else { + this.prepareDuration = prepareDuration.toMillis(); + } + if (duration == null) { + this.duration = 0L; + } else { + this.duration = duration.toMillis(); + } + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: The server-generated event identifier. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the handoffId property: The server-generated handoff attempt identifier. + * + * @return the handoffId value. + */ + @Generated + public String getHandoffId() { + return this.handoffId; + } + + /** + * Get the edgeId property: The configured edge selected for this handoff. + * + * @return the edgeId value. + */ + @Generated + public String getEdgeId() { + return this.edgeId; + } + + /** + * Get the fromNodeId property: The source node identifier or `$entrypoint`. + * + * @return the fromNodeId value. + */ + @Generated + public String getFromNodeId() { + return this.fromNodeId; + } + + /** + * Get the toNodeId property: The target node identifier or `$entrypoint`. + * + * @return the toNodeId value. + */ + @Generated + public String getToNodeId() { + return this.toNodeId; + } + + /** + * Get the fromModel property: The model active before the handoff. + * + * @return the fromModel value. + */ + @Generated + public String getFromModel() { + return this.fromModel; + } + + /** + * Get the toModel property: The model prepared for the target behavior. + * + * @return the toModel value. + */ + @Generated + public String getToModel() { + return this.toModel; + } + + /** + * Get the toolCallId property: The function-call identifier that initiated the handoff. + * + * @return the toolCallId value. + */ + @Generated + public String getToolCallId() { + return this.toolCallId; + } + + /** + * Get the nodeGeneration property: The source generation for started or aborted events, and the committed target + * generation for completed events. + * + * @return the nodeGeneration value. + */ + @Generated + public int getNodeGeneration() { + return this.nodeGeneration; + } + + /** + * Get the prepareDuration property: The target-preparation duration. + * + * @return the prepareDuration value. + */ + @Generated + public Duration getPrepareDuration() { + return Duration.ofMillis(this.prepareDuration); + } + + /** + * Get the duration property: The total handoff duration. + * + * @return the duration value. + */ + @Generated + public Duration getDuration() { + return Duration.ofMillis(this.duration); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("handoff_id", this.handoffId); + jsonWriter.writeStringField("edge_id", this.edgeId); + jsonWriter.writeStringField("from_node_id", this.fromNodeId); + jsonWriter.writeStringField("to_node_id", this.toNodeId); + jsonWriter.writeStringField("from_model", this.fromModel); + jsonWriter.writeStringField("to_model", this.toModel); + jsonWriter.writeStringField("tool_call_id", this.toolCallId); + jsonWriter.writeIntField("node_generation", this.nodeGeneration); + jsonWriter.writeLongField("prepare_duration_ms", this.prepareDuration); + jsonWriter.writeLongField("duration_ms", this.duration); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSessionHandoffCompletedEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSessionHandoffCompletedEvent if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSessionHandoffCompletedEvent. + */ + @Generated + public static VoiceAgentSessionHandoffCompletedEvent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String eventId = null; + String handoffId = null; + String edgeId = null; + String fromNodeId = null; + String toNodeId = null; + String fromModel = null; + String toModel = null; + String toolCallId = null; + int nodeGeneration = 0; + Duration prepareDuration = null; + Duration duration = null; + RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_COMPLETED; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("handoff_id".equals(fieldName)) { + handoffId = reader.getString(); + } else if ("edge_id".equals(fieldName)) { + edgeId = reader.getString(); + } else if ("from_node_id".equals(fieldName)) { + fromNodeId = reader.getString(); + } else if ("to_node_id".equals(fieldName)) { + toNodeId = reader.getString(); + } else if ("from_model".equals(fieldName)) { + fromModel = reader.getString(); + } else if ("to_model".equals(fieldName)) { + toModel = reader.getString(); + } else if ("tool_call_id".equals(fieldName)) { + toolCallId = reader.getString(); + } else if ("node_generation".equals(fieldName)) { + nodeGeneration = reader.getInt(); + } else if ("prepare_duration_ms".equals(fieldName)) { + prepareDuration = Duration.ofMillis(reader.getLong()); + } else if ("duration_ms".equals(fieldName)) { + duration = Duration.ofMillis(reader.getLong()); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentSessionHandoffCompletedEvent deserializedVoiceAgentSessionHandoffCompletedEvent + = new VoiceAgentSessionHandoffCompletedEvent(eventId, handoffId, edgeId, fromNodeId, toNodeId, + fromModel, toModel, toolCallId, nodeGeneration, prepareDuration, duration); + deserializedVoiceAgentSessionHandoffCompletedEvent.type = type; + return deserializedVoiceAgentSessionHandoffCompletedEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffStartedEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffStartedEvent.java new file mode 100644 index 0000000000000..3e998a499c70f --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffStartedEvent.java @@ -0,0 +1,286 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The `session.handoff.started` server event. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSessionHandoffStartedEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_STARTED; + + /* + * The server-generated event identifier. + */ + @Generated + private final String eventId; + + /* + * The server-generated handoff attempt identifier. + */ + @Generated + private final String handoffId; + + /* + * The configured edge selected for this handoff. + */ + @Generated + private final String edgeId; + + /* + * The source node identifier or `$entrypoint`. + */ + @Generated + private final String fromNodeId; + + /* + * The target node identifier or `$entrypoint`. + */ + @Generated + private final String toNodeId; + + /* + * The model active before the handoff. + */ + @Generated + private final String fromModel; + + /* + * The model prepared for the target behavior. + */ + @Generated + private final String toModel; + + /* + * The function-call identifier that initiated the handoff. + */ + @Generated + private final String toolCallId; + + /* + * The source generation for started or aborted events, and the committed target generation for completed events. + */ + @Generated + private final int nodeGeneration; + + /** + * Creates an instance of VoiceAgentSessionHandoffStartedEvent class. + * + * @param eventId the eventId value to set. + * @param handoffId the handoffId value to set. + * @param edgeId the edgeId value to set. + * @param fromNodeId the fromNodeId value to set. + * @param toNodeId the toNodeId value to set. + * @param fromModel the fromModel value to set. + * @param toModel the toModel value to set. + * @param toolCallId the toolCallId value to set. + * @param nodeGeneration the nodeGeneration value to set. + */ + @Generated + private VoiceAgentSessionHandoffStartedEvent(String eventId, String handoffId, String edgeId, String fromNodeId, + String toNodeId, String fromModel, String toModel, String toolCallId, int nodeGeneration) { + this.eventId = eventId; + this.handoffId = handoffId; + this.edgeId = edgeId; + this.fromNodeId = fromNodeId; + this.toNodeId = toNodeId; + this.fromModel = fromModel; + this.toModel = toModel; + this.toolCallId = toolCallId; + this.nodeGeneration = nodeGeneration; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: The server-generated event identifier. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the handoffId property: The server-generated handoff attempt identifier. + * + * @return the handoffId value. + */ + @Generated + public String getHandoffId() { + return this.handoffId; + } + + /** + * Get the edgeId property: The configured edge selected for this handoff. + * + * @return the edgeId value. + */ + @Generated + public String getEdgeId() { + return this.edgeId; + } + + /** + * Get the fromNodeId property: The source node identifier or `$entrypoint`. + * + * @return the fromNodeId value. + */ + @Generated + public String getFromNodeId() { + return this.fromNodeId; + } + + /** + * Get the toNodeId property: The target node identifier or `$entrypoint`. + * + * @return the toNodeId value. + */ + @Generated + public String getToNodeId() { + return this.toNodeId; + } + + /** + * Get the fromModel property: The model active before the handoff. + * + * @return the fromModel value. + */ + @Generated + public String getFromModel() { + return this.fromModel; + } + + /** + * Get the toModel property: The model prepared for the target behavior. + * + * @return the toModel value. + */ + @Generated + public String getToModel() { + return this.toModel; + } + + /** + * Get the toolCallId property: The function-call identifier that initiated the handoff. + * + * @return the toolCallId value. + */ + @Generated + public String getToolCallId() { + return this.toolCallId; + } + + /** + * Get the nodeGeneration property: The source generation for started or aborted events, and the committed target + * generation for completed events. + * + * @return the nodeGeneration value. + */ + @Generated + public int getNodeGeneration() { + return this.nodeGeneration; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("handoff_id", this.handoffId); + jsonWriter.writeStringField("edge_id", this.edgeId); + jsonWriter.writeStringField("from_node_id", this.fromNodeId); + jsonWriter.writeStringField("to_node_id", this.toNodeId); + jsonWriter.writeStringField("from_model", this.fromModel); + jsonWriter.writeStringField("to_model", this.toModel); + jsonWriter.writeStringField("tool_call_id", this.toolCallId); + jsonWriter.writeIntField("node_generation", this.nodeGeneration); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSessionHandoffStartedEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSessionHandoffStartedEvent if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSessionHandoffStartedEvent. + */ + @Generated + public static VoiceAgentSessionHandoffStartedEvent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String eventId = null; + String handoffId = null; + String edgeId = null; + String fromNodeId = null; + String toNodeId = null; + String fromModel = null; + String toModel = null; + String toolCallId = null; + int nodeGeneration = 0; + RealtimeServerEventType type = RealtimeServerEventType.SESSION_HANDOFF_STARTED; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("handoff_id".equals(fieldName)) { + handoffId = reader.getString(); + } else if ("edge_id".equals(fieldName)) { + edgeId = reader.getString(); + } else if ("from_node_id".equals(fieldName)) { + fromNodeId = reader.getString(); + } else if ("to_node_id".equals(fieldName)) { + toNodeId = reader.getString(); + } else if ("from_model".equals(fieldName)) { + fromModel = reader.getString(); + } else if ("to_model".equals(fieldName)) { + toModel = reader.getString(); + } else if ("tool_call_id".equals(fieldName)) { + toolCallId = reader.getString(); + } else if ("node_generation".equals(fieldName)) { + nodeGeneration = reader.getInt(); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentSessionHandoffStartedEvent deserializedVoiceAgentSessionHandoffStartedEvent + = new VoiceAgentSessionHandoffStartedEvent(eventId, handoffId, edgeId, fromNodeId, toNodeId, fromModel, + toModel, toolCallId, nodeGeneration); + deserializedVoiceAgentSessionHandoffStartedEvent.type = type; + return deserializedVoiceAgentSessionHandoffStartedEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java index e45301cb7d821..be3a9d82f9689 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java @@ -13,10 +13,6 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import com.openai.models.realtime.RealtimeReasoning; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import java.io.IOException; import java.time.Instant; import java.time.OffsetDateTime; @@ -199,9 +195,9 @@ public Double getTemperature() { * * @return the maxOutputTokens value. */ - BinaryData getMaxOutputTokens() { + public VoiceAgentMaxOutputTokens getMaxOutputTokens() { // AI Tooling: union type - return this.maxOutputTokens; + return this.maxOutputTokens == null ? null : this.maxOutputTokens.toObject(VoiceAgentMaxOutputTokens.class); } /** @@ -257,11 +253,10 @@ public List getTools() { /** * Get the toolChoice property: Tool-selection behavior for the session. * - * @return the toolChoice value. + * @return the tool choice, or {@code null} when absent or JSON null. */ - BinaryData getToolChoice() { - // AI Tooling: union type - return this.toolChoice; + public VoiceAgentToolChoice getToolChoice() { + return this.toolChoice == null ? null : this.toolChoice.toObject(VoiceAgentToolChoice.class); } /** @@ -404,6 +399,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeMapField("metadata", this.metadata, (writer, element) -> writer.writeString(element)); jsonWriter.writeJsonField("interim_response", this.interimResponse); jsonWriter.writeJsonField("greeting", this.greeting); + jsonWriter.writeJsonField("handoff", this.handoff); jsonWriter.writeNumberField("expires_at", this.expiresAt); return jsonWriter.writeEndObject(); } @@ -437,6 +433,7 @@ public static VoiceAgentSessionResponseConfiguration fromJson(JsonReader jsonRea Map metadata = null; VoiceAgentInterimResponseConfiguration interimResponse = null; VoiceAgentGreetingConfiguration greeting = null; + VoiceAgentHandoffState handoff = null; Long expiresAt = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); @@ -481,6 +478,8 @@ public static VoiceAgentSessionResponseConfiguration fromJson(JsonReader jsonRea interimResponse = VoiceAgentInterimResponseConfiguration.fromJson(reader); } else if ("greeting".equals(fieldName)) { greeting = VoiceAgentGreetingConfiguration.fromJson(reader); + } else if ("handoff".equals(fieldName)) { + handoff = VoiceAgentHandoffState.fromJson(reader); } else if ("expires_at".equals(fieldName)) { expiresAt = reader.getNullable(JsonReader::getLong); } else { @@ -504,106 +503,25 @@ public static VoiceAgentSessionResponseConfiguration fromJson(JsonReader jsonRea deserializedVoiceAgentSessionResponseConfiguration.metadata = metadata; deserializedVoiceAgentSessionResponseConfiguration.interimResponse = interimResponse; deserializedVoiceAgentSessionResponseConfiguration.greeting = greeting; + deserializedVoiceAgentSessionResponseConfiguration.handoff = handoff; deserializedVoiceAgentSessionResponseConfiguration.expiresAt = expiresAt; return deserializedVoiceAgentSessionResponseConfiguration; }); } - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceFunction}: Tool-selection behavior for the - * session. - * - * @return the toolChoice value as a ToolChoiceFunction, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceFunction getToolChoiceAsToolChoiceFunction() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isFunction()) { - return null; - } - return choice.asFunction(); - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceMcp}: Tool-selection behavior for the session. - * - * @return the toolChoice value as a ToolChoiceMcp, or {@code null} if it is not set or holds another variant. + /* + * The effective handoff topology and runtime state, when handoff is configured. */ - public ToolChoiceMcp getToolChoiceAsToolChoiceMcp() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isMcp()) { - return null; - } - return choice.asMcp(); - } - - private ResponseCreateParams.ToolChoice getOpenAIToolChoice() { - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!json.startsWith("{")) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ResponseCreateParams.ToolChoice.class); - } + @Generated + private VoiceAgentHandoffState handoff; /** - * Get the toolChoice property: Tool-selection behavior for the session. + * Get the handoff property: The effective handoff topology and runtime state, when handoff is configured. * - * @return the toolChoice value as a {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another - * variant. + * @return the handoff value. */ - public ToolChoiceOptions getToolChoiceAsToolChoiceOptions() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ToolChoiceOptions.class); + @Generated + public VoiceAgentHandoffState getHandoff() { + return this.handoff; } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java index 985dbfdb31402..bb584a47582f1 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java @@ -13,10 +13,6 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import com.openai.models.realtime.RealtimeReasoning; -import com.openai.models.responses.ResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import java.io.IOException; import java.util.List; import java.util.Map; @@ -191,9 +187,9 @@ public VoiceAgentSessionUpdateConfiguration setTemperature(Double temperature) { * * @return the maxOutputTokens value. */ - BinaryData getMaxOutputTokens() { + public VoiceAgentMaxOutputTokens getMaxOutputTokens() { // AI Tooling: union type - return this.maxOutputTokens; + return this.maxOutputTokens == null ? null : this.maxOutputTokens.toObject(VoiceAgentMaxOutputTokens.class); } /** @@ -202,9 +198,9 @@ BinaryData getMaxOutputTokens() { * @param maxOutputTokens the maxOutputTokens value to set. * @return the VoiceAgentSessionUpdateConfiguration object itself. */ - VoiceAgentSessionUpdateConfiguration setMaxOutputTokens(BinaryData maxOutputTokens) { + public VoiceAgentSessionUpdateConfiguration setMaxOutputTokens(VoiceAgentMaxOutputTokens maxOutputTokens) { // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens; + this.maxOutputTokens = maxOutputTokens == null ? null : BinaryData.fromObject(maxOutputTokens); return this; } @@ -321,22 +317,20 @@ public VoiceAgentSessionUpdateConfiguration setTools(List tools) /** * Get the toolChoice property: Tool-selection behavior for the session. * - * @return the toolChoice value. + * @return the tool choice, or {@code null} when absent or JSON null. */ - BinaryData getToolChoice() { - // AI Tooling: union type - return this.toolChoice; + public VoiceAgentToolChoice getToolChoice() { + return this.toolChoice == null ? null : this.toolChoice.toObject(VoiceAgentToolChoice.class); } /** * Set the toolChoice property: Tool-selection behavior for the session. * - * @param toolChoice the toolChoice value to set. + * @param toolChoice the tool choice, or {@code null} to clear the property. * @return the VoiceAgentSessionUpdateConfiguration object itself. */ - VoiceAgentSessionUpdateConfiguration setToolChoice(BinaryData toolChoice) { - // AI Tooling: union type - this.toolChoice = toolChoice; + public VoiceAgentSessionUpdateConfiguration setToolChoice(VoiceAgentToolChoice toolChoice) { + this.toolChoice = toolChoice == null ? null : BinaryData.fromObject(toolChoice); return this; } @@ -583,165 +577,4 @@ public static VoiceAgentSessionUpdateConfiguration fromJson(JsonReader jsonReade return deserializedVoiceAgentSessionUpdateConfiguration; }); } - - /** - * Set the maxOutputTokens property: The maximum output-token count for one response. - * - * @param maxOutputTokens the maximum number of output tokens to set. - * @return the VoiceAgentSessionUpdateConfiguration object itself. - */ - public VoiceAgentSessionUpdateConfiguration setMaxOutputTokens(long maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Set the maxOutputTokens property: The maximum output-token count for one response. - * - * @param maxOutputTokens the token-limit string to set, for example {@code "inf"} for an unlimited count. - * @return the VoiceAgentSessionUpdateConfiguration object itself. - */ - public VoiceAgentSessionUpdateConfiguration setMaxOutputTokens(String maxOutputTokens) { - // AI Tooling: union type - this.maxOutputTokens = maxOutputTokens == null ? null : BinaryData.fromObject(maxOutputTokens); - return this; - } - - /** - * Get the maxOutputTokens property: The maximum output-token count for one response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } - - /** - * Set the toolChoice property: Tool-selection behavior for the session. - * - * @param toolChoice the {@link ToolChoiceOptions} mode to set ({@code NONE}, {@code AUTO} or {@code REQUIRED}). - * @return the VoiceAgentSessionUpdateConfiguration object itself. - */ - public VoiceAgentSessionUpdateConfiguration setToolChoice(ToolChoiceOptions toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Set the toolChoice property to a specific function tool: Tool-selection behavior for the session. - * - * @param toolChoice the openai-java {@link ToolChoiceFunction} to set, or null to clear. - * @return the VoiceAgentSessionUpdateConfiguration object itself. - */ - public VoiceAgentSessionUpdateConfiguration setToolChoice(ToolChoiceFunction toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceFunction}: Tool-selection behavior for the - * session. - * - * @return the toolChoice value as a ToolChoiceFunction, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceFunction getToolChoiceAsToolChoiceFunction() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isFunction()) { - return null; - } - return choice.asFunction(); - } - - /** - * Set the toolChoice property to a specific MCP tool: Tool-selection behavior for the session. - * - * @param toolChoice the openai-java {@link ToolChoiceMcp} to set, or null to clear. - * @return the VoiceAgentSessionUpdateConfiguration object itself. - */ - public VoiceAgentSessionUpdateConfiguration setToolChoice(ToolChoiceMcp toolChoice) { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - this.toolChoice = com.azure.ai.agents.implementation.OpenAIJsonHelper.toBinaryData(toolChoice); - return this; - } - - /** - * Get the toolChoice property as an openai-java {@link ToolChoiceMcp}: Tool-selection behavior for the session. - * - * @return the toolChoice value as a ToolChoiceMcp, or {@code null} if it is not set or holds another variant. - */ - public ToolChoiceMcp getToolChoiceAsToolChoiceMcp() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - ResponseCreateParams.ToolChoice choice = getOpenAIToolChoice(); - if (choice == null || !choice.isMcp()) { - return null; - } - return choice.asMcp(); - } - - private ResponseCreateParams.ToolChoice getOpenAIToolChoice() { - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!json.startsWith("{")) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ResponseCreateParams.ToolChoice.class); - } - - /** - * Get the toolChoice property: Tool-selection behavior for the session. - * - * @return the toolChoice value as a {@link ToolChoiceOptions}, or {@code null} when it is not set or holds another - * variant. - */ - public ToolChoiceOptions getToolChoiceAsToolChoiceOptions() { - // AI Tooling: union type - // AI Tooling: openai-java de-dup - if (this.toolChoice == null) { - return null; - } - String json = this.toolChoice.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return com.azure.ai.agents.implementation.OpenAIJsonHelper.fromBinaryData(this.toolChoice, - ToolChoiceOptions.class); - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java index 2e082524727b5..07d90651d2ce0 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java @@ -24,7 +24,7 @@ public final class VoiceAgentStaticInterimResponseConfiguration extends VoiceAge * The interim-response implementation. */ @Generated - private String type = "static_interim_response"; + private VoiceAgentInterimResponseType type = VoiceAgentInterimResponseType.STATIC_INTERIM_RESPONSE; /* * Candidate text values for the interim response. @@ -46,7 +46,7 @@ public VoiceAgentStaticInterimResponseConfiguration() { */ @Generated @Override - public String getType() { + public VoiceAgentInterimResponseType getType() { return this.type; } @@ -104,7 +104,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { if (getLatencyThresholdMs() != null) { jsonWriter.writeNumberField("latency_threshold_ms", getLatencyThresholdMs().toMillis()); } - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeArrayField("texts", this.texts, (writer, element) -> writer.writeString(element)); return jsonWriter.writeEndObject(); } @@ -136,7 +136,8 @@ public static VoiceAgentStaticInterimResponseConfiguration fromJson(JsonReader j .setLatencyThresholdMs(Duration.ofMillis(latencyThresholdMsHolder)); } } else if ("type".equals(fieldName)) { - deserializedVoiceAgentStaticInterimResponseConfiguration.type = reader.getString(); + deserializedVoiceAgentStaticInterimResponseConfiguration.type + = VoiceAgentInterimResponseType.fromString(reader.getString()); } else if ("texts".equals(fieldName)) { List texts = reader.readArray(reader1 -> reader1.getString()); deserializedVoiceAgentStaticInterimResponseConfiguration.texts = texts; diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubProtocol.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubProtocol.java new file mode 100644 index 0000000000000..a9a34b4c11ba1 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubProtocol.java @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Voice protocol; realtime includes cascaded models. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentSubProtocol { + + /** + * Enum value realtime. + */ + REALTIME("realtime"), + /** + * Enum value live. + */ + LIVE("live"); + + /** + * The actual serialized value for a VoiceAgentSubProtocol instance. + */ + private final String value; + + VoiceAgentSubProtocol(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentSubProtocol instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentSubProtocol object, or null if unable to parse. + */ + public static VoiceAgentSubProtocol fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentSubProtocol[] items = VoiceAgentSubProtocol.values(); + for (VoiceAgentSubProtocol item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java index 31fe251b63d48..c8411982c6f02 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java @@ -11,76 +11,102 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import java.io.IOException; -import java.util.List; /** - * Configuration for sibling Foundry text agents that a voice agent may consult. + * Configuration for delegated background specialists or inline voice subagents. For compatibility with existing + * delegate configurations, the service treats an omitted `subagent_type` as `delegate`. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class VoiceAgentSubagentConfiguration implements JsonSerializable { +public class VoiceAgentSubagentConfiguration implements JsonSerializable { - /* - * The sibling Foundry text agents, in the same project, that this voice agent may consult. + /** + * {@inheritDoc} */ @Generated - private final List subagents; + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("subagent_type", this.subagentType == null ? null : this.subagentType.toString()); + return jsonWriter.writeEndObject(); + } /** - * Creates an instance of VoiceAgentSubagentConfiguration class. + * Reads an instance of VoiceAgentSubagentConfiguration from the JsonReader. * - * @param subagents the subagents value to set. + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSubagentConfiguration if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentSubagentConfiguration. */ @Generated - public VoiceAgentSubagentConfiguration(List subagents) { - this.subagents = subagents; + public static VoiceAgentSubagentConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + // Prepare for reading + readerToUse.nextToken(); + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("subagent_type".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("delegate".equals(discriminatorValue)) { + return VoiceAgentDelegateSubagentConfiguration.fromJson(readerToUse.reset()); + } else if ("inline".equals(discriminatorValue)) { + return VoiceAgentInlineSubagentConfiguration.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); } - /** - * Get the subagents property: The sibling Foundry text agents, in the same project, that this voice agent may - * consult. - * - * @return the subagents value. + /* + * The subagent mode. */ @Generated - public List getSubagents() { - return this.subagents; - } + private VoiceAgentSubagentType subagentType = VoiceAgentSubagentType.fromString("VoiceAgentSubagentConfiguration"); /** - * {@inheritDoc} + * Creates an instance of VoiceAgentSubagentConfiguration class. */ @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeArrayField("subagents", this.subagents, (writer, element) -> writer.writeJson(element)); - return jsonWriter.writeEndObject(); + protected VoiceAgentSubagentConfiguration() { } /** - * Reads an instance of VoiceAgentSubagentConfiguration from the JsonReader. + * Get the subagentType property: The subagent mode. * - * @param jsonReader The JsonReader being read. - * @return An instance of VoiceAgentSubagentConfiguration if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the VoiceAgentSubagentConfiguration. + * @return the subagentType value. */ @Generated - public static VoiceAgentSubagentConfiguration fromJson(JsonReader jsonReader) throws IOException { + public VoiceAgentSubagentType getSubagentType() { + return this.subagentType; + } + + @Generated + static VoiceAgentSubagentConfiguration fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - List subagents = null; + VoiceAgentSubagentConfiguration deserializedVoiceAgentSubagentConfiguration + = new VoiceAgentSubagentConfiguration(); while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("subagents".equals(fieldName)) { - subagents = reader.readArray(reader1 -> VoiceAgentSubagent.fromJson(reader1)); + if ("subagent_type".equals(fieldName)) { + deserializedVoiceAgentSubagentConfiguration.subagentType + = VoiceAgentSubagentType.fromString(reader.getString()); } else { reader.skipChildren(); } } - return new VoiceAgentSubagentConfiguration(subagents); + return deserializedVoiceAgentSubagentConfiguration; }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentType.java new file mode 100644 index 0000000000000..a6f5779a78f3a --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentType.java @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The subagent configuration mode. Additional modes may be added over time. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSubagentType extends ExpandableStringEnum { + + /** + * Referenced Foundry agents invoked as delegated background specialists. + */ + @Generated + public static final VoiceAgentSubagentType DELEGATE = fromString("delegate"); + + /** + * Inline voice behaviors that may become active through Handoff. + */ + @Generated + public static final VoiceAgentSubagentType INLINE = fromString("inline"); + + /** + * Creates a new instance of VoiceAgentSubagentType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentSubagentType() { + } + + /** + * Creates or finds a VoiceAgentSubagentType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentSubagentType. + */ + @Generated + public static VoiceAgentSubagentType fromString(String name) { + return fromString(name, VoiceAgentSubagentType.class); + } + + /** + * Gets known VoiceAgentSubagentType values. + * + * @return known VoiceAgentSubagentType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentSubagentType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java index f1ca846d3bc3c..6f6aaaf2090f7 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java @@ -10,6 +10,7 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import java.io.IOException; +import java.time.Duration; /** * A service-managed control that acts on the active voice session without customer code or external authentication. @@ -22,7 +23,7 @@ public class VoiceAgentSystemTool extends VoiceAgentTool { * The tool kind. */ @Generated - private final String type = "system"; + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; /* * The service-managed control action. Known values are stable; additional values may be added over time. @@ -50,7 +51,7 @@ protected VoiceAgentSystemTool() { */ @Generated @Override - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -94,9 +95,10 @@ public VoiceAgentSystemTool setDescription(String description) { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); jsonWriter.writeStringField("description", this.description); + jsonWriter.writeNumberField("timeout_seconds", this.timeout); return jsonWriter.writeEndObject(); } @@ -128,6 +130,20 @@ public static VoiceAgentSystemTool fromJson(JsonReader jsonReader) throws IOExce // Use the discriminator value to determine which subtype should be deserialized. if ("end_conversation".equals(discriminatorValue)) { return VoiceAgentEndConversationSystemTool.fromJson(readerToUse.reset()); + } else if ("language_detection".equals(discriminatorValue)) { + return VoiceAgentLanguageDetectionSystemTool.fromJson(readerToUse.reset()); + } else if ("digit_recognition".equals(discriminatorValue)) { + return VoiceAgentDigitRecognitionSystemTool.fromJson(readerToUse.reset()); + } else if ("collect_sms".equals(discriminatorValue)) { + return VoiceAgentCollectSmsSystemTool.fromJson(readerToUse.reset()); + } else if ("collect_dtmf".equals(discriminatorValue)) { + return VoiceAgentCollectDtmfSystemTool.fromJson(readerToUse.reset()); + } else if ("transfer".equals(discriminatorValue)) { + return VoiceAgentTransferSystemTool.fromJson(readerToUse.reset()); + } else if ("send_dtmf".equals(discriminatorValue)) { + return VoiceAgentSendDtmfSystemTool.fromJson(readerToUse.reset()); + } else if ("send_sms".equals(discriminatorValue)) { + return VoiceAgentSendSmsSystemTool.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } @@ -146,6 +162,8 @@ static VoiceAgentSystemTool fromJsonKnownDiscriminator(JsonReader jsonReader) th deserializedVoiceAgentSystemTool.name = VoiceAgentSystemToolName.fromString(reader.getString()); } else if ("description".equals(fieldName)) { deserializedVoiceAgentSystemTool.description = reader.getString(); + } else if ("timeout_seconds".equals(fieldName)) { + deserializedVoiceAgentSystemTool.timeout = reader.getNullable(JsonReader::getLong); } else { reader.skipChildren(); } @@ -153,4 +171,41 @@ static VoiceAgentSystemTool fromJsonKnownDiscriminator(JsonReader jsonReader) th return deserializedVoiceAgentSystemTool; }); } + + /* + * Execution timeout, from 1 to 300 seconds. If omitted, the service defaults to 60 seconds. + */ + @Generated + private Long timeout; + + /** + * Get the timeout property: Execution timeout, from 1 to 300 seconds. If omitted, the service defaults to 60 + * seconds. + * + * @return the timeout value. + */ + @Generated + public Duration getTimeout() { + if (this.timeout == null) { + return null; + } + return Duration.ofSeconds(this.timeout); + } + + /** + * Set the timeout property: Execution timeout, from 1 to 300 seconds. If omitted, the service defaults to 60 + * seconds. + * + * @param timeout the timeout value to set. + * @return the VoiceAgentSystemTool object itself. + */ + @Generated + public VoiceAgentSystemTool setTimeout(Duration timeout) { + if (timeout == null) { + this.timeout = null; + } else { + this.timeout = timeout.getSeconds(); + } + return this; + } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDeltaEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDeltaEvent.java new file mode 100644 index 0000000000000..1fc27481c140f --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDeltaEvent.java @@ -0,0 +1,239 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * An incremental model-argument fragment for a service-managed system tool. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSystemToolArgumentsDeltaEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.RESPONSE_SYSTEM_TOOL_ARGUMENTS_DELTA; + + /* + * The unique identifier of this server event. + */ + @Generated + private final String eventId; + + /* + * The response containing the tool invocation. + */ + @Generated + private final String responseId; + + /* + * The generated tool item's identifier. + */ + @Generated + private final String itemId; + + /* + * The item's zero-based position in the response output. + */ + @Generated + private final int outputIndex; + + /* + * The invocation identifier. + */ + @Generated + private final String callId; + + /* + * An incremental JSON fragment of the intent arguments. + */ + @Generated + private final String delta; + + /* + * Optional padding metadata with no application semantics. + */ + @Generated + private String obfuscation; + + /** + * Creates an instance of VoiceAgentSystemToolArgumentsDeltaEvent class. + * + * @param eventId the eventId value to set. + * @param responseId the responseId value to set. + * @param itemId the itemId value to set. + * @param outputIndex the outputIndex value to set. + * @param callId the callId value to set. + * @param delta the delta value to set. + */ + @Generated + private VoiceAgentSystemToolArgumentsDeltaEvent(String eventId, String responseId, String itemId, int outputIndex, + String callId, String delta) { + this.eventId = eventId; + this.responseId = responseId; + this.itemId = itemId; + this.outputIndex = outputIndex; + this.callId = callId; + this.delta = delta; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: The unique identifier of this server event. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the responseId property: The response containing the tool invocation. + * + * @return the responseId value. + */ + @Generated + public String getResponseId() { + return this.responseId; + } + + /** + * Get the itemId property: The generated tool item's identifier. + * + * @return the itemId value. + */ + @Generated + public String getItemId() { + return this.itemId; + } + + /** + * Get the outputIndex property: The item's zero-based position in the response output. + * + * @return the outputIndex value. + */ + @Generated + public int getOutputIndex() { + return this.outputIndex; + } + + /** + * Get the callId property: The invocation identifier. + * + * @return the callId value. + */ + @Generated + public String getCallId() { + return this.callId; + } + + /** + * Get the delta property: An incremental JSON fragment of the intent arguments. + * + * @return the delta value. + */ + @Generated + public String getDelta() { + return this.delta; + } + + /** + * Get the obfuscation property: Optional padding metadata with no application semantics. + * + * @return the obfuscation value. + */ + @Generated + public String getObfuscation() { + return this.obfuscation; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("response_id", this.responseId); + jsonWriter.writeStringField("item_id", this.itemId); + jsonWriter.writeIntField("output_index", this.outputIndex); + jsonWriter.writeStringField("call_id", this.callId); + jsonWriter.writeStringField("delta", this.delta); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("obfuscation", this.obfuscation); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSystemToolArgumentsDeltaEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSystemToolArgumentsDeltaEvent if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSystemToolArgumentsDeltaEvent. + */ + @Generated + public static VoiceAgentSystemToolArgumentsDeltaEvent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String eventId = null; + String responseId = null; + String itemId = null; + int outputIndex = 0; + String callId = null; + String delta = null; + RealtimeServerEventType type = RealtimeServerEventType.RESPONSE_SYSTEM_TOOL_ARGUMENTS_DELTA; + String obfuscation = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else if ("item_id".equals(fieldName)) { + itemId = reader.getString(); + } else if ("output_index".equals(fieldName)) { + outputIndex = reader.getInt(); + } else if ("call_id".equals(fieldName)) { + callId = reader.getString(); + } else if ("delta".equals(fieldName)) { + delta = reader.getString(); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else if ("obfuscation".equals(fieldName)) { + obfuscation = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentSystemToolArgumentsDeltaEvent deserializedVoiceAgentSystemToolArgumentsDeltaEvent + = new VoiceAgentSystemToolArgumentsDeltaEvent(eventId, responseId, itemId, outputIndex, callId, delta); + deserializedVoiceAgentSystemToolArgumentsDeltaEvent.type = type; + deserializedVoiceAgentSystemToolArgumentsDeltaEvent.obfuscation = obfuscation; + return deserializedVoiceAgentSystemToolArgumentsDeltaEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDoneEvent.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDoneEvent.java new file mode 100644 index 0000000000000..fdd3fe29c6b10 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDoneEvent.java @@ -0,0 +1,241 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The completed intent arguments for a system tool, not provider success or a request for a customer function result. + */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSystemToolArgumentsDoneEvent extends RealtimeServerEvent { + + /* + * The type property. + */ + @Generated + private RealtimeServerEventType type = RealtimeServerEventType.RESPONSE_SYSTEM_TOOL_ARGUMENTS_DONE; + + /* + * The unique identifier of this server event. + */ + @Generated + private final String eventId; + + /* + * The response containing the tool invocation. + */ + @Generated + private final String responseId; + + /* + * The generated tool item's identifier. + */ + @Generated + private final String itemId; + + /* + * The item's zero-based position in the response output. + */ + @Generated + private final int outputIndex; + + /* + * The invocation identifier. + */ + @Generated + private final String callId; + + /* + * The invoked built-in capability. + */ + @Generated + private final VoiceAgentSystemToolName name; + + /* + * The complete, unexpanded model arguments as a JSON string. + */ + @Generated + private final String arguments; + + /** + * Creates an instance of VoiceAgentSystemToolArgumentsDoneEvent class. + * + * @param eventId the eventId value to set. + * @param responseId the responseId value to set. + * @param itemId the itemId value to set. + * @param outputIndex the outputIndex value to set. + * @param callId the callId value to set. + * @param name the name value to set. + * @param arguments the arguments value to set. + */ + @Generated + private VoiceAgentSystemToolArgumentsDoneEvent(String eventId, String responseId, String itemId, int outputIndex, + String callId, VoiceAgentSystemToolName name, String arguments) { + this.eventId = eventId; + this.responseId = responseId; + this.itemId = itemId; + this.outputIndex = outputIndex; + this.callId = callId; + this.name = name; + this.arguments = arguments; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeServerEventType getType() { + return this.type; + } + + /** + * Get the eventId property: The unique identifier of this server event. + * + * @return the eventId value. + */ + @Generated + public String getEventId() { + return this.eventId; + } + + /** + * Get the responseId property: The response containing the tool invocation. + * + * @return the responseId value. + */ + @Generated + public String getResponseId() { + return this.responseId; + } + + /** + * Get the itemId property: The generated tool item's identifier. + * + * @return the itemId value. + */ + @Generated + public String getItemId() { + return this.itemId; + } + + /** + * Get the outputIndex property: The item's zero-based position in the response output. + * + * @return the outputIndex value. + */ + @Generated + public int getOutputIndex() { + return this.outputIndex; + } + + /** + * Get the callId property: The invocation identifier. + * + * @return the callId value. + */ + @Generated + public String getCallId() { + return this.callId; + } + + /** + * Get the name property: The invoked built-in capability. + * + * @return the name value. + */ + @Generated + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * Get the arguments property: The complete, unexpanded model arguments as a JSON string. + * + * @return the arguments value. + */ + @Generated + public String getArguments() { + return this.arguments; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("event_id", this.eventId); + jsonWriter.writeStringField("response_id", this.responseId); + jsonWriter.writeStringField("item_id", this.itemId); + jsonWriter.writeIntField("output_index", this.outputIndex); + jsonWriter.writeStringField("call_id", this.callId); + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + jsonWriter.writeStringField("arguments", this.arguments); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSystemToolArgumentsDoneEvent from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSystemToolArgumentsDoneEvent if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSystemToolArgumentsDoneEvent. + */ + @Generated + public static VoiceAgentSystemToolArgumentsDoneEvent fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String eventId = null; + String responseId = null; + String itemId = null; + int outputIndex = 0; + String callId = null; + VoiceAgentSystemToolName name = null; + String arguments = null; + RealtimeServerEventType type = RealtimeServerEventType.RESPONSE_SYSTEM_TOOL_ARGUMENTS_DONE; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("event_id".equals(fieldName)) { + eventId = reader.getString(); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else if ("item_id".equals(fieldName)) { + itemId = reader.getString(); + } else if ("output_index".equals(fieldName)) { + outputIndex = reader.getInt(); + } else if ("call_id".equals(fieldName)) { + callId = reader.getString(); + } else if ("name".equals(fieldName)) { + name = VoiceAgentSystemToolName.fromString(reader.getString()); + } else if ("arguments".equals(fieldName)) { + arguments = reader.getString(); + } else if ("type".equals(fieldName)) { + type = RealtimeServerEventType.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + VoiceAgentSystemToolArgumentsDoneEvent deserializedVoiceAgentSystemToolArgumentsDoneEvent + = new VoiceAgentSystemToolArgumentsDoneEvent(eventId, responseId, itemId, outputIndex, callId, name, + arguments); + deserializedVoiceAgentSystemToolArgumentsDoneEvent.type = type; + return deserializedVoiceAgentSystemToolArgumentsDoneEvent; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItem.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItem.java new file mode 100644 index 0000000000000..9f3c2b26b49de --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItem.java @@ -0,0 +1,286 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Service-generated system-tool intent, not a provider result. Clients cannot create it or complete it with + * `function_call_output`. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSystemToolItem extends RealtimeConversationItem { + + /* + * The type property. + */ + @Generated + private RealtimeConversationItemType type = RealtimeConversationItemType.SYSTEM_TOOL; + + /* + * The identifier of the generated item. + */ + @Generated + private String id; + + /* + * The generation status of the item, not the provider execution outcome. + */ + @Generated + private final VoiceAgentSystemToolItemStatus status; + + /* + * The built-in capability invoked by the model. + */ + @Generated + private final VoiceAgentSystemToolName name; + + /* + * The invocation identifier used for correlation and duplicate suppression. + */ + @Generated + private final String callId; + + /* + * Original JSON-encoded intent: literals remain visible and references stay unexpanded. Excludes private values, + * resolved arguments and executor-only settings. + */ + @Generated + private final String arguments; + + /* + * The Unix timestamp (in seconds) for when the item was persisted. + */ + @Generated + private Long createdAt; + + /* + * The id of the response that produced this item, when applicable. + */ + @Generated + private String responseId; + + /** + * Creates an instance of VoiceAgentSystemToolItem class. + * + * @param status the status value to set. + * @param name the name value to set. + * @param callId the callId value to set. + * @param arguments the arguments value to set. + */ + private VoiceAgentSystemToolItem(VoiceAgentSystemToolItemStatus status, VoiceAgentSystemToolName name, + String callId, String arguments) { + this.status = status; + this.name = name; + this.callId = callId; + this.arguments = arguments; + } + + /** + * Get the type property: The type property. + * + * @return the type value. + */ + @Generated + @Override + public RealtimeConversationItemType getType() { + return this.type; + } + + /** + * Get the id property: The identifier of the generated item. + * + * @return the id value. + */ + @Generated + public String getId() { + return this.id; + } + + /** + * Set the id property: The identifier of the generated item. + * + * @param id the id value to set. + * @return the VoiceAgentSystemToolItem object itself. + */ + private VoiceAgentSystemToolItem setId(String id) { + this.id = id; + return this; + } + + /** + * Set the objectType property: The realtime item marker. + * + * @param objectType the objectType value to set. + * @return the VoiceAgentSystemToolItem object itself. + */ + private VoiceAgentSystemToolItem setObjectType(VoiceAgentSystemToolItemObjectType objectType) { + this.objectType = objectType; + return this; + } + + /** + * Get the status property: The generation status of the item, not the provider execution outcome. + * + * @return the status value. + */ + @Generated + public VoiceAgentSystemToolItemStatus getStatus() { + return this.status; + } + + /** + * Get the name property: The built-in capability invoked by the model. + * + * @return the name value. + */ + @Generated + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * Get the callId property: The invocation identifier used for correlation and duplicate suppression. + * + * @return the callId value. + */ + @Generated + public String getCallId() { + return this.callId; + } + + /** + * Get the arguments property: Original JSON-encoded intent: literals remain visible and references stay unexpanded. + * Excludes private values, resolved arguments and executor-only settings. + * + * @return the arguments value. + */ + @Generated + public String getArguments() { + return this.arguments; + } + + /** + * Get the createdAt property: The Unix timestamp (in seconds) for when the item was persisted. + * + * @return the createdAt value. + */ + @Generated + public OffsetDateTime getCreatedAt() { + if (this.createdAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.createdAt), ZoneOffset.UTC); + } + + /** + * Get the responseId property: The id of the response that produced this item, when applicable. + * + * @return the responseId value. + */ + @Generated + public String getResponseId() { + return this.responseId; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("status", this.status == null ? null : this.status.toString()); + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + jsonWriter.writeStringField("call_id", this.callId); + jsonWriter.writeStringField("arguments", this.arguments); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("id", this.id); + jsonWriter.writeStringField("object", this.objectType == null ? null : this.objectType.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentSystemToolItem from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentSystemToolItem if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentSystemToolItem. + */ + @Generated + public static VoiceAgentSystemToolItem fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentSystemToolItemStatus status = null; + VoiceAgentSystemToolName name = null; + String callId = null; + String arguments = null; + RealtimeConversationItemType type = RealtimeConversationItemType.SYSTEM_TOOL; + String id = null; + VoiceAgentSystemToolItemObjectType objectType = null; + Long createdAt = null; + String responseId = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("status".equals(fieldName)) { + status = VoiceAgentSystemToolItemStatus.fromString(reader.getString()); + } else if ("name".equals(fieldName)) { + name = VoiceAgentSystemToolName.fromString(reader.getString()); + } else if ("call_id".equals(fieldName)) { + callId = reader.getString(); + } else if ("arguments".equals(fieldName)) { + arguments = reader.getString(); + } else if ("type".equals(fieldName)) { + type = RealtimeConversationItemType.fromString(reader.getString()); + } else if ("id".equals(fieldName)) { + id = reader.getString(); + } else if ("object".equals(fieldName)) { + objectType = VoiceAgentSystemToolItemObjectType.fromString(reader.getString()); + } else if ("created_at".equals(fieldName)) { + createdAt = reader.getNullable(JsonReader::getLong); + } else if ("response_id".equals(fieldName)) { + responseId = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentSystemToolItem deserializedVoiceAgentSystemToolItem + = new VoiceAgentSystemToolItem(status, name, callId, arguments); + deserializedVoiceAgentSystemToolItem.type = type; + deserializedVoiceAgentSystemToolItem.id = id; + deserializedVoiceAgentSystemToolItem.objectType = objectType; + deserializedVoiceAgentSystemToolItem.createdAt = createdAt; + deserializedVoiceAgentSystemToolItem.responseId = responseId; + return deserializedVoiceAgentSystemToolItem; + }); + } + + /* + * The realtime item marker. + */ + @Generated + private VoiceAgentSystemToolItemObjectType objectType; + + /** + * Get the objectType property: The realtime item marker. + * + * @return the objectType value. + */ + @Generated + public VoiceAgentSystemToolItemObjectType getObjectType() { + return this.objectType; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemObjectType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemObjectType.java new file mode 100644 index 0000000000000..b776ac795dfa7 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemObjectType.java @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * Defines values for VoiceAgentSystemToolItemObjectType. + */ +@Beta(warningText = "Preview API.") +public enum VoiceAgentSystemToolItemObjectType { + + /** + * Enum value realtime.item. + */ + REALTIME_ITEM("realtime.item"); + + /** + * The actual serialized value for a VoiceAgentSystemToolItemObjectType instance. + */ + private final String value; + + VoiceAgentSystemToolItemObjectType(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentSystemToolItemObjectType instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentSystemToolItemObjectType object, or null if unable to parse. + */ + public static VoiceAgentSystemToolItemObjectType fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentSystemToolItemObjectType[] items = VoiceAgentSystemToolItemObjectType.values(); + for (VoiceAgentSystemToolItemObjectType item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemStatus.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemStatus.java new file mode 100644 index 0000000000000..be784957d8498 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemStatus.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The generation status of a system-tool item. It does not indicate provider success. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentSystemToolItemStatus extends ExpandableStringEnum { + + /** + * The item is still being generated. + */ + @Generated + public static final VoiceAgentSystemToolItemStatus IN_PROGRESS = fromString("in_progress"); + + /** + * The item finished generation. + */ + @Generated + public static final VoiceAgentSystemToolItemStatus COMPLETED = fromString("completed"); + + /** + * The item did not finish generation. + */ + @Generated + public static final VoiceAgentSystemToolItemStatus INCOMPLETE = fromString("incomplete"); + + /** + * Creates a new instance of VoiceAgentSystemToolItemStatus value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentSystemToolItemStatus() { + } + + /** + * Creates or finds a VoiceAgentSystemToolItemStatus from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentSystemToolItemStatus. + */ + @Generated + public static VoiceAgentSystemToolItemStatus fromString(String name) { + return fromString(name, VoiceAgentSystemToolItemStatus.class); + } + + /** + * Gets known VoiceAgentSystemToolItemStatus values. + * + * @return known VoiceAgentSystemToolItemStatus values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentSystemToolItemStatus.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java index d14ab7dfe49e5..01150cdc78aae 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java @@ -50,4 +50,46 @@ public static VoiceAgentSystemToolName fromString(String name) { public static Collection values() { return values(VoiceAgentSystemToolName.class); } + + /** + * Switches supported conversation language settings. + */ + @Generated + public static final VoiceAgentSystemToolName LANGUAGE_DETECTION = fromString("language_detection"); + + /** + * Retrieves the unchanged transcript of the last user audio turn. + */ + @Generated + public static final VoiceAgentSystemToolName DIGIT_RECOGNITION = fromString("digit_recognition"); + + /** + * Requests a transfer to an explicitly configured logical target. + */ + @Generated + public static final VoiceAgentSystemToolName TRANSFER = fromString("transfer"); + + /** + * Collects one complete SMS from an explicitly selected sender. + */ + @Generated + public static final VoiceAgentSystemToolName COLLECT_SMS = fromString("collect_sms"); + + /** + * Collects keypad digits on the current call. + */ + @Generated + public static final VoiceAgentSystemToolName COLLECT_DTMF = fromString("collect_dtmf"); + + /** + * Sends literal or templated keypad digits. + */ + @Generated + public static final VoiceAgentSystemToolName SEND_DTMF = fromString("send_dtmf"); + + /** + * Sends a text message from the Agent's SMS-capable number. + */ + @Generated + public static final VoiceAgentSystemToolName SEND_SMS = fromString("send_sms"); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java index ac1a9a4c94a1b..dd8e35f99adb7 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java @@ -23,7 +23,7 @@ public final class VoiceAgentTemplateGreetingConfiguration extends VoiceAgentGre * The greeting mode. */ @Generated - private String type = "template"; + private VoiceAgentGreetingMode type = VoiceAgentGreetingMode.TEMPLATE; /* * The Handlebars text template spoken at session start. @@ -48,7 +48,7 @@ public VoiceAgentTemplateGreetingConfiguration(String text) { */ @Generated @Override - public String getType() { + public VoiceAgentGreetingMode getType() { return this.type; } @@ -70,7 +70,7 @@ public String getText() { public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("text", this.text); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } @@ -87,14 +87,14 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static VoiceAgentTemplateGreetingConfiguration fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String text = null; - String type = "template"; + VoiceAgentGreetingMode type = VoiceAgentGreetingMode.TEMPLATE; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("text".equals(fieldName)) { text = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentGreetingMode.fromString(reader.getString()); } else { reader.skipChildren(); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java index 6cf5f9bad5ff1..69e13d1a8c85b 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java @@ -23,7 +23,7 @@ public class VoiceAgentTool implements JsonSerializable { * The tool kind. */ @Generated - private String type = "VoiceAgentTool"; + private VoiceAgentToolType type = VoiceAgentToolType.fromString("VoiceAgentTool"); /** * Creates an instance of VoiceAgentTool class. @@ -38,7 +38,7 @@ protected VoiceAgentTool() { * @return the type value. */ @Generated - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -49,7 +49,7 @@ public String getType() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); return jsonWriter.writeEndObject(); } @@ -102,7 +102,7 @@ static VoiceAgentTool fromJsonKnownDiscriminator(JsonReader jsonReader) throws I String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - deserializedVoiceAgentTool.type = reader.getString(); + deserializedVoiceAgentTool.type = VoiceAgentToolType.fromString(reader.getString()); } else { reader.skipChildren(); } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolChoice.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolChoice.java new file mode 100644 index 0000000000000..f04f137aedb49 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolChoice.java @@ -0,0 +1,157 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Immutable; +import com.azure.core.util.BinaryData; +import com.azure.core.util.logging.ClientLogger; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonWriter; +import com.openai.models.responses.ResponseCreateParams; +import com.openai.models.responses.ToolChoiceFunction; +import com.openai.models.responses.ToolChoiceMcp; +import com.openai.models.responses.ToolChoiceOptions; + +import java.io.IOException; +import java.util.Map; +import java.util.Objects; + +/** + * Tool-selection behavior for a voice agent: a mode, a specific function, or a specific MCP tool. + * + *

Create a choice using {@link #ofMode(ToolChoiceOptions)}, {@link #ofFunction(ToolChoiceFunction)}, or + * {@link #ofMcp(ToolChoiceMcp)}. Pass {@code null} to a model's {@code setToolChoice} method to clear the property; + * the factories do not accept {@code null}.

+ * + *

Use {@link #getMode()}, {@link #getFunction()}, or {@link #getMcp()} to read the selected variant. Getters for + * other variants return {@code null}. Unrecognized choices read from JSON are preserved when serialized again; + * all three getters return {@code null} for an unrecognized choice.

+ */ +@Immutable +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentToolChoice implements JsonSerializable { + private static final ClientLogger LOGGER = new ClientLogger(VoiceAgentToolChoice.class); + + private final ResponseCreateParams.ToolChoice value; + + private final BinaryData unknownValue; + + private VoiceAgentToolChoice(ResponseCreateParams.ToolChoice value) { + this.value = value; + this.unknownValue = null; + } + + private VoiceAgentToolChoice(BinaryData unknownValue) { + this.value = null; + this.unknownValue = unknownValue; + } + + /** + * Creates a choice using a tool-selection mode, such as {@link ToolChoiceOptions#AUTO}. + * + * @param mode the tool-selection mode. + * @return the tool choice. + * @throws NullPointerException if {@code mode} is null. + */ + public static VoiceAgentToolChoice ofMode(ToolChoiceOptions mode) { + return new VoiceAgentToolChoice( + ResponseCreateParams.ToolChoice.ofOptions(Objects.requireNonNull(mode, "'mode' cannot be null."))); + } + + /** + * Creates a choice that selects a specific function tool. + * + * @param function the function tool to select. + * @return the tool choice. + * @throws NullPointerException if {@code function} is null. + */ + public static VoiceAgentToolChoice ofFunction(ToolChoiceFunction function) { + return new VoiceAgentToolChoice( + ResponseCreateParams.ToolChoice.ofFunction(Objects.requireNonNull(function, "'function' cannot be null."))); + } + + /** + * Creates a choice that selects a specific MCP tool. + * + * @param mcp the MCP tool to select. + * @return the tool choice. + * @throws NullPointerException if {@code mcp} is null. + */ + public static VoiceAgentToolChoice ofMcp(ToolChoiceMcp mcp) { + return new VoiceAgentToolChoice( + ResponseCreateParams.ToolChoice.ofMcp(Objects.requireNonNull(mcp, "'mcp' cannot be null."))); + } + + /** + * Gets the tool-selection mode. + * + * @return the mode, or {@code null} if this choice holds another variant. + */ + public ToolChoiceOptions getMode() { + return value == null ? null : value.options().orElse(null); + } + + /** + * Gets the specific function tool selected by this choice. + * + * @return the function tool, or {@code null} if this choice holds another variant. + */ + public ToolChoiceFunction getFunction() { + return value == null ? null : value.function().orElse(null); + } + + /** + * Gets the specific MCP tool selected by this choice. + * + * @return the MCP tool, or {@code null} if this choice holds another variant. + */ + public ToolChoiceMcp getMcp() { + return value == null ? null : value.mcp().orElse(null); + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + if (unknownValue != null) { + unknownValue.writeTo(jsonWriter); + } else { + OpenAIJsonHelper.toBinaryData(value).writeTo(jsonWriter); + } + return jsonWriter; + } + + /** + * Reads a tool choice from a JSON string or object. + * + * @param jsonReader the JSON reader. + * @return the tool choice, or null for JSON null. + * @throws IOException if the JSON cannot be read. + */ + public static VoiceAgentToolChoice fromJson(JsonReader jsonReader) throws IOException { + Object payload = jsonReader.readUntyped(); + if (payload == null) { + return null; + } + BinaryData data = BinaryData.fromObject(payload); + if (payload instanceof String) { + return ofMode(OpenAIJsonHelper.fromBinaryData(data, ToolChoiceOptions.class)); + } + if (payload instanceof Map) { + Object type = ((Map) payload).get("type"); + if ("function".equals(type)) { + return ofFunction(OpenAIJsonHelper.fromBinaryData(data, ToolChoiceFunction.class)); + } + if ("mcp".equals(type)) { + return ofMcp(OpenAIJsonHelper.fromBinaryData(data, ToolChoiceMcp.class)); + } + return new VoiceAgentToolChoice(data); + } + throw LOGGER.logExceptionAsError(new IllegalStateException("Tool choice must be a JSON string or object.")); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolType.java new file mode 100644 index 0000000000000..fbafc89b3b963 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolType.java @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The tool kinds supported by a voice agent. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentToolType extends ExpandableStringEnum { + + /** + * A native function tool executed by the client. + */ + @Generated + public static final VoiceAgentToolType FUNCTION = fromString("function"); + + /** + * A tool exposed by an MCP server. + */ + @Generated + public static final VoiceAgentToolType MCP = fromString("mcp"); + + /** + * A service-managed control that acts on the active voice session. + */ + @Generated + public static final VoiceAgentToolType SYSTEM = fromString("system"); + + /** + * A reference to a Foundry toolbox. + */ + @Generated + public static final VoiceAgentToolType TOOLBOX = fromString("toolbox"); + + /** + * Creates a new instance of VoiceAgentToolType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentToolType() { + } + + /** + * Creates or finds a VoiceAgentToolType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentToolType. + */ + @Generated + public static VoiceAgentToolType fromString(String name) { + return fromString(name, VoiceAgentToolType.class); + } + + /** + * Gets known VoiceAgentToolType values. + * + * @return known VoiceAgentToolType values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentToolType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java index 475a5b854c55d..34ae72329b874 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java @@ -22,7 +22,7 @@ public final class VoiceAgentToolboxTool extends VoiceAgentTool { * The tool kind. */ @Generated - private String type = "toolbox"; + private VoiceAgentToolType type = VoiceAgentToolType.TOOLBOX; /* * The name of the toolbox to attach. @@ -61,7 +61,7 @@ public VoiceAgentToolboxTool(String toolboxName, String toolboxVersion) { */ @Generated @Override - public String getType() { + public VoiceAgentToolType getType() { return this.type; } @@ -118,7 +118,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("toolbox_name", this.toolboxName); jsonWriter.writeStringField("toolbox_version", this.toolboxVersion); - jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); jsonWriter.writeStringField("response_scheduling", this.responseScheduling == null ? null : this.responseScheduling.toString()); return jsonWriter.writeEndObject(); @@ -138,7 +138,7 @@ public static VoiceAgentToolboxTool fromJson(JsonReader jsonReader) throws IOExc return jsonReader.readObject(reader -> { String toolboxName = null; String toolboxVersion = null; - String type = "toolbox"; + VoiceAgentToolType type = VoiceAgentToolType.TOOLBOX; VoiceAgentToolResponseScheduling responseScheduling = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); @@ -148,7 +148,7 @@ public static VoiceAgentToolboxTool fromJson(JsonReader jsonReader) throws IOExc } else if ("toolbox_version".equals(fieldName)) { toolboxVersion = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceAgentToolType.fromString(reader.getString()); } else if ("response_scheduling".equals(fieldName)) { responseScheduling = VoiceAgentToolResponseScheduling.fromString(reader.getString()); } else { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestination.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestination.java similarity index 59% rename from sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestination.java rename to sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestination.java index 3ba5e7e350e36..81476e78268ff 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestination.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestination.java @@ -13,48 +13,51 @@ import java.io.IOException; /** - * The destination of an outbound call. + * The canonical system-tool transfer destination. */ @Immutable @Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class TelephonyOutboundDestination implements JsonSerializable { +public final class VoiceAgentTransferDestination implements JsonSerializable { /* - * The destination type. Only E.164 phone numbers are currently supported. + * The destination format: phone_number for an E.164 number, teams for a Teams identifier, or sip for a SIP URI. */ @Generated - private final TelephonyOutboundDestinationType type; + private final VoiceAgentTransferDestinationType type; /* - * The destination E.164 phone number. + * The concrete address. Phone numbers use E.164; Teams and SIP identifiers are validated against the selected + * provider's capabilities. */ @Generated private final String value; /** - * Creates an instance of TelephonyOutboundDestination class. + * Creates an instance of VoiceAgentTransferDestination class. * * @param type the type value to set. * @param value the value value to set. */ @Generated - public TelephonyOutboundDestination(TelephonyOutboundDestinationType type, String value) { + public VoiceAgentTransferDestination(VoiceAgentTransferDestinationType type, String value) { this.type = type; this.value = value; } /** - * Get the type property: The destination type. Only E.164 phone numbers are currently supported. + * Get the type property: The destination format: phone_number for an E.164 number, teams for a Teams identifier, or + * sip for a SIP URI. * * @return the type value. */ @Generated - public TelephonyOutboundDestinationType getType() { + public VoiceAgentTransferDestinationType getType() { return this.type; } /** - * Get the value property: The destination E.164 phone number. + * Get the value property: The concrete address. Phone numbers use E.164; Teams and SIP identifiers are validated + * against the selected provider's capabilities. * * @return the value value. */ @@ -76,31 +79,31 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { } /** - * Reads an instance of TelephonyOutboundDestination from the JsonReader. + * Reads an instance of VoiceAgentTransferDestination from the JsonReader. * * @param jsonReader The JsonReader being read. - * @return An instance of TelephonyOutboundDestination if the JsonReader was pointing to an instance of it, or null + * @return An instance of VoiceAgentTransferDestination if the JsonReader was pointing to an instance of it, or null * if it was pointing to JSON null. * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the TelephonyOutboundDestination. + * @throws IOException If an error occurs while reading the VoiceAgentTransferDestination. */ @Generated - public static TelephonyOutboundDestination fromJson(JsonReader jsonReader) throws IOException { + public static VoiceAgentTransferDestination fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - TelephonyOutboundDestinationType type = null; + VoiceAgentTransferDestinationType type = null; String value = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); if ("type".equals(fieldName)) { - type = TelephonyOutboundDestinationType.fromString(reader.getString()); + type = VoiceAgentTransferDestinationType.fromString(reader.getString()); } else if ("value".equals(fieldName)) { value = reader.getString(); } else { reader.skipChildren(); } } - return new TelephonyOutboundDestination(type, value); + return new VoiceAgentTransferDestination(type, value); }); } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestinationType.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestinationType.java new file mode 100644 index 0000000000000..55f848165c5e3 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestinationType.java @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; + +/** + * The supported address formats for a system-tool transfer destination. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public enum VoiceAgentTransferDestinationType { + + /** + * An E.164 telephone number. + */ + PHONE_NUMBER("phone_number"), + /** + * A Microsoft Teams user or resource-account identifier. + */ + TEAMS("teams"), + /** + * A SIP or SIPS URI. + */ + SIP("sip"); + + /** + * The actual serialized value for a VoiceAgentTransferDestinationType instance. + */ + private final String value; + + VoiceAgentTransferDestinationType(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a VoiceAgentTransferDestinationType instance. + * + * @param value the serialized value to parse. + * @return the parsed VoiceAgentTransferDestinationType object, or null if unable to parse. + */ + public static VoiceAgentTransferDestinationType fromString(String value) { + if (value == null) { + return null; + } + VoiceAgentTransferDestinationType[] items = VoiceAgentTransferDestinationType.values(); + for (VoiceAgentTransferDestinationType item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return this.value; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferRouting.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferRouting.java new file mode 100644 index 0000000000000..302d6ea9435a0 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferRouting.java @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; + +/** + * The configured transfer routing policy. The model selects a target name, not destinations or routing settings. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentTransferRouting implements JsonSerializable { + + /* + * The routing strategy. Current native Telephony transfer supports ACS sequential and random routing only. + */ + @Generated + private final VoiceAgentTransferStrategy strategy; + + /** + * Creates an instance of VoiceAgentTransferRouting class. + * + * @param strategy the strategy value to set. + */ + @Generated + public VoiceAgentTransferRouting(VoiceAgentTransferStrategy strategy) { + this.strategy = strategy; + } + + /** + * Get the strategy property: The routing strategy. Current native Telephony transfer supports ACS sequential and + * random routing only. + * + * @return the strategy value. + */ + @Generated + public VoiceAgentTransferStrategy getStrategy() { + return this.strategy; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("strategy", this.strategy == null ? null : this.strategy.toString()); + jsonWriter.writeNumberField("ring_timeout_seconds", this.ringTimeout); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentTransferRouting from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentTransferRouting if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentTransferRouting. + */ + @Generated + public static VoiceAgentTransferRouting fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentTransferStrategy strategy = null; + Long ringTimeout = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("strategy".equals(fieldName)) { + strategy = VoiceAgentTransferStrategy.fromString(reader.getString()); + } else if ("ring_timeout_seconds".equals(fieldName)) { + ringTimeout = reader.getNullable(JsonReader::getLong); + } else { + reader.skipChildren(); + } + } + VoiceAgentTransferRouting deserializedVoiceAgentTransferRouting = new VoiceAgentTransferRouting(strategy); + deserializedVoiceAgentTransferRouting.ringTimeout = ringTimeout; + return deserializedVoiceAgentTransferRouting; + }); + } + + /* + * Per-destination ring timeout in seconds, from 1 to 300. If omitted, the service defaults to 20 seconds. Must not + * exceed the tool's timeout_seconds. ACS allows at most 180 seconds. + */ + @Generated + private Long ringTimeout; + + /** + * Get the ringTimeout property: Per-destination ring timeout in seconds, from 1 to 300. If omitted, the service + * defaults to 20 seconds. Must not exceed the tool's timeout_seconds. ACS allows at most 180 seconds. + * + * @return the ringTimeout value. + */ + @Generated + public Duration getRingTimeout() { + if (this.ringTimeout == null) { + return null; + } + return Duration.ofSeconds(this.ringTimeout); + } + + /** + * Set the ringTimeout property: Per-destination ring timeout in seconds, from 1 to 300. If omitted, the service + * defaults to 20 seconds. Must not exceed the tool's timeout_seconds. ACS allows at most 180 seconds. + * + * @param ringTimeout the ringTimeout value to set. + * @return the VoiceAgentTransferRouting object itself. + */ + @Generated + public VoiceAgentTransferRouting setRingTimeout(Duration ringTimeout) { + if (ringTimeout == null) { + this.ringTimeout = null; + } else { + this.ringTimeout = ringTimeout.getSeconds(); + } + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferStrategy.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferStrategy.java new file mode 100644 index 0000000000000..1ced9ff374098 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferStrategy.java @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Per-invocation transfer routing. Unsupported strategies are rejected before provider execution; schema membership + * does not imply support by every provider. + */ +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentTransferStrategy extends ExpandableStringEnum { + + /** + * Try destinations in configured order while the total budget remains. + */ + @Generated + public static final VoiceAgentTransferStrategy SEQUENTIAL = fromString("sequential"); + + /** + * Randomize destination order for this invocation, then try each within the total budget. + */ + @Generated + public static final VoiceAgentTransferStrategy RANDOM = fromString("random"); + + /** + * Ring destinations concurrently and select the first answer when the executor supports this strategy. + */ + @Generated + public static final VoiceAgentTransferStrategy PARALLEL = fromString("parallel"); + + /** + * Creates a new instance of VoiceAgentTransferStrategy value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceAgentTransferStrategy() { + } + + /** + * Creates or finds a VoiceAgentTransferStrategy from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceAgentTransferStrategy. + */ + @Generated + public static VoiceAgentTransferStrategy fromString(String name) { + return fromString(name, VoiceAgentTransferStrategy.class); + } + + /** + * Gets known VoiceAgentTransferStrategy values. + * + * @return known VoiceAgentTransferStrategy values. + */ + @Generated + public static Collection values() { + return values(VoiceAgentTransferStrategy.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferSystemTool.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferSystemTool.java new file mode 100644 index 0000000000000..2c5fa595f5405 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferSystemTool.java @@ -0,0 +1,199 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.Duration; +import java.util.List; + +/** + * Requests a transfer to an explicitly configured logical target. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentTransferSystemTool extends VoiceAgentSystemTool { + + /* + * The tool kind. + */ + @Generated + private final VoiceAgentToolType type = VoiceAgentToolType.SYSTEM; + + /* + * The service-managed control action. Known values are stable; additional values may be added over time. + */ + @Generated + private VoiceAgentSystemToolName name = VoiceAgentSystemToolName.TRANSFER; + + /* + * Require a non-blank handoff summary in each model-generated transfer call. Defaults to false; does not guarantee + * delivery to the recipient. + */ + @Generated + private Boolean requireHandoff; + + /* + * The non-empty set of logical targets that the model may select. + */ + @Generated + private final List targets; + + /** + * Creates an instance of VoiceAgentTransferSystemTool class. + * + * @param targets the targets value to set. + */ + @Generated + public VoiceAgentTransferSystemTool(List targets) { + this.targets = targets; + } + + /** + * Get the type property: The tool kind. + * + * @return the type value. + */ + @Generated + @Override + public VoiceAgentToolType getType() { + return this.type; + } + + /** + * Get the name property: The service-managed control action. Known values are stable; additional values may be + * added over time. + * + * @return the name value. + */ + @Generated + @Override + public VoiceAgentSystemToolName getName() { + return this.name; + } + + /** + * Get the requireHandoff property: Require a non-blank handoff summary in each model-generated transfer call. + * Defaults to false; does not guarantee delivery to the recipient. + * + * @return the requireHandoff value. + */ + @Generated + public Boolean isRequireHandoff() { + return this.requireHandoff; + } + + /** + * Set the requireHandoff property: Require a non-blank handoff summary in each model-generated transfer call. + * Defaults to false; does not guarantee delivery to the recipient. + * + * @param requireHandoff the requireHandoff value to set. + * @return the VoiceAgentTransferSystemTool object itself. + */ + @Generated + public VoiceAgentTransferSystemTool setRequireHandoff(Boolean requireHandoff) { + this.requireHandoff = requireHandoff; + return this; + } + + /** + * Get the targets property: The non-empty set of logical targets that the model may select. + * + * @return the targets value. + */ + @Generated + public List getTargets() { + return this.targets; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentTransferSystemTool setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); + jsonWriter.writeStringField("description", getDescription()); + if (getTimeout() != null) { + jsonWriter.writeNumberField("timeout_seconds", getTimeout().getSeconds()); + } + jsonWriter.writeArrayField("targets", this.targets, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeStringField("name", this.name == null ? null : this.name.toString()); + jsonWriter.writeBooleanField("require_handoff", this.requireHandoff); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentTransferSystemTool from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentTransferSystemTool if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentTransferSystemTool. + */ + @Generated + public static VoiceAgentTransferSystemTool fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String description = null; + Duration timeout = null; + List targets = null; + VoiceAgentSystemToolName name = VoiceAgentSystemToolName.TRANSFER; + Boolean requireHandoff = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("description".equals(fieldName)) { + description = reader.getString(); + } else if ("timeout_seconds".equals(fieldName)) { + Long timeoutHolder = reader.getNullable(JsonReader::getLong); + if (timeoutHolder != null) { + timeout = Duration.ofSeconds(timeoutHolder); + } + } else if ("targets".equals(fieldName)) { + targets = reader.readArray(reader1 -> VoiceAgentTransferTarget.fromJson(reader1)); + } else if ("name".equals(fieldName)) { + name = VoiceAgentSystemToolName.fromString(reader.getString()); + } else if ("require_handoff".equals(fieldName)) { + requireHandoff = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + VoiceAgentTransferSystemTool deserializedVoiceAgentTransferSystemTool + = new VoiceAgentTransferSystemTool(targets); + deserializedVoiceAgentTransferSystemTool.setDescription(description); + deserializedVoiceAgentTransferSystemTool.setTimeout(timeout); + deserializedVoiceAgentTransferSystemTool.name = name; + deserializedVoiceAgentTransferSystemTool.requireHandoff = requireHandoff; + return deserializedVoiceAgentTransferSystemTool; + }); + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public VoiceAgentTransferSystemTool setTimeout(Duration timeout) { + super.setTimeout(timeout); + return this; + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferTarget.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferTarget.java new file mode 100644 index 0000000000000..285c7986e0fea --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentTransferTarget.java @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * A configured logical transfer target. Only its name and description are model-visible; destinations and routing are + * executor settings. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public final class VoiceAgentTransferTarget implements JsonSerializable { + + /* + * The non-blank logical target name. Names must be unique after trimming within the transfer tool. + */ + @Generated + private final String name; + + /* + * A description that helps the model select this target. + */ + @Generated + private String description; + + /* + * The concrete destinations for this transfer target. + */ + @Generated + private final List destinations; + + /* + * The trusted routing policy for this target. + */ + @Generated + private final VoiceAgentTransferRouting routing; + + /** + * Creates an instance of VoiceAgentTransferTarget class. + * + * @param name the name value to set. + * @param destinations the destinations value to set. + * @param routing the routing value to set. + */ + @Generated + public VoiceAgentTransferTarget(String name, List destinations, + VoiceAgentTransferRouting routing) { + this.name = name; + this.destinations = destinations; + this.routing = routing; + } + + /** + * Get the name property: The non-blank logical target name. Names must be unique after trimming within the transfer + * tool. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + + /** + * Get the description property: A description that helps the model select this target. + * + * @return the description value. + */ + @Generated + public String getDescription() { + return this.description; + } + + /** + * Set the description property: A description that helps the model select this target. + * + * @param description the description value to set. + * @return the VoiceAgentTransferTarget object itself. + */ + @Generated + public VoiceAgentTransferTarget setDescription(String description) { + this.description = description; + return this; + } + + /** + * Get the destinations property: The concrete destinations for this transfer target. + * + * @return the destinations value. + */ + @Generated + public List getDestinations() { + return this.destinations; + } + + /** + * Get the routing property: The trusted routing policy for this target. + * + * @return the routing value. + */ + @Generated + public VoiceAgentTransferRouting getRouting() { + return this.routing; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", this.name); + jsonWriter.writeArrayField("destinations", this.destinations, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeJsonField("routing", this.routing); + jsonWriter.writeStringField("description", this.description); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentTransferTarget from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentTransferTarget if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the VoiceAgentTransferTarget. + */ + @Generated + public static VoiceAgentTransferTarget fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String name = null; + List destinations = null; + VoiceAgentTransferRouting routing = null; + String description = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("name".equals(fieldName)) { + name = reader.getString(); + } else if ("destinations".equals(fieldName)) { + destinations = reader.readArray(reader1 -> VoiceAgentTransferDestination.fromJson(reader1)); + } else if ("routing".equals(fieldName)) { + routing = VoiceAgentTransferRouting.fromJson(reader); + } else if ("description".equals(fieldName)) { + description = reader.getString(); + } else { + reader.skipChildren(); + } + } + VoiceAgentTransferTarget deserializedVoiceAgentTransferTarget + = new VoiceAgentTransferTarget(name, destinations, routing); + deserializedVoiceAgentTransferTarget.description = description; + return deserializedVoiceAgentTransferTarget; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentVoiceConfiguration.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentVoiceConfiguration.java new file mode 100644 index 0000000000000..01eb3f105cf7c --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentVoiceConfiguration.java @@ -0,0 +1,511 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. +package com.azure.ai.agents.models; + +import com.azure.ai.agents.implementation.utils.Beta; +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Voice output configuration. Inline subagents use it directly as their voice override, and the session-level + * output audio configuration extends it. + * Provider-specific fields are selected by `voice_type`: + * - `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`. + */ +@Fluent +@Beta(warningText = "Preview API. VoiceAgents=V1Preview") +public class VoiceAgentVoiceConfiguration implements JsonSerializable { + + /* + * 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. + */ + @Generated + private String voice; + + /* + * The voice implementation. + */ + @Generated + private VoiceType voiceType; + + /* + * The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and + * `avatar-voice-sync`. + */ + @Generated + private String voiceLocale; + + /* + * The numeric output speed multiplier. Applies to all known `voice_type` values and defaults to 1. + */ + @Generated + private Double speed; + + /* + * The voice variation temperature. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and + * `avatar-voice-sync`. + */ + @Generated + private Double voiceTemperature; + + /* + * The URL of a custom pronunciation lexicon. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and + * `avatar-voice-sync`. + */ + @Generated + private String customLexiconUrl; + + /* + * The URL of a custom text-normalization configuration. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + */ + @Generated + private String customTextNormalizationUrl; + + /* + * Preferred BCP-47 locales for multilingual synthesis. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + */ + @Generated + private List preferredLocales; + + /* + * The voice speaking style. Applies only when `voice_type` is `azure-standard`. + */ + @Generated + private String style; + + /* + * The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and + * `avatar-voice-sync`. + */ + @Generated + private String pitch; + + /* + * The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, `azure-personal`, and + * `avatar-voice-sync`. + */ + @Generated + private String volume; + + /* + * The Azure custom-voice deployment endpoint identifier. Applies only when `voice_type` is `azure-custom`. + */ + @Generated + private String customVoiceEndpointId; + + /* + * The Azure personal or avatar voice model. Applies only when `voice_type` is `azure-personal` or + * `avatar-voice-sync`. + */ + @Generated + private String personalVoiceModel; + + /** + * Creates an instance of VoiceAgentVoiceConfiguration class. + */ + @Generated + public VoiceAgentVoiceConfiguration() { + } + + /** + * Get the voice property: 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. + * + * @return the voice value. + */ + @Generated + public String getVoice() { + return this.voice; + } + + /** + * Set the voice property: 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. + * + * @param voice the voice value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setVoice(String voice) { + this.voice = voice; + return this; + } + + /** + * Get the voiceType property: The voice implementation. + * + * @return the voiceType value. + */ + @Generated + public VoiceType getVoiceType() { + return this.voiceType; + } + + /** + * Set the voiceType property: The voice implementation. + * + * @param voiceType the voiceType value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setVoiceType(VoiceType voiceType) { + this.voiceType = voiceType; + return this; + } + + /** + * Get the voiceLocale property: The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @return the voiceLocale value. + */ + @Generated + public String getVoiceLocale() { + return this.voiceLocale; + } + + /** + * Set the voiceLocale property: The enforced BCP-47 output locale. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @param voiceLocale the voiceLocale value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setVoiceLocale(String voiceLocale) { + this.voiceLocale = voiceLocale; + return this; + } + + /** + * Get the speed property: The numeric output speed multiplier. Applies to all known `voice_type` values and + * defaults to 1. + * + * @return the speed value. + */ + @Generated + public Double getSpeed() { + return this.speed; + } + + /** + * Set the speed property: The numeric output speed multiplier. Applies to all known `voice_type` values and + * defaults to 1. + * + * @param speed the speed value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setSpeed(Double speed) { + this.speed = speed; + return this; + } + + /** + * Get the voiceTemperature property: The voice variation temperature. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @return the voiceTemperature value. + */ + @Generated + public Double getVoiceTemperature() { + return this.voiceTemperature; + } + + /** + * Set the voiceTemperature property: The voice variation temperature. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @param voiceTemperature the voiceTemperature value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setVoiceTemperature(Double voiceTemperature) { + this.voiceTemperature = voiceTemperature; + return this; + } + + /** + * Get the customLexiconUrl property: The URL of a custom pronunciation lexicon. Applies to `azure-standard`, + * `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @return the customLexiconUrl value. + */ + @Generated + public String getCustomLexiconUrl() { + return this.customLexiconUrl; + } + + /** + * Set the customLexiconUrl property: The URL of a custom pronunciation lexicon. Applies to `azure-standard`, + * `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @param customLexiconUrl the customLexiconUrl value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setCustomLexiconUrl(String customLexiconUrl) { + this.customLexiconUrl = customLexiconUrl; + return this; + } + + /** + * Get the customTextNormalizationUrl property: The URL of a custom text-normalization configuration. Applies to + * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @return the customTextNormalizationUrl value. + */ + @Generated + public String getCustomTextNormalizationUrl() { + return this.customTextNormalizationUrl; + } + + /** + * Set the customTextNormalizationUrl property: The URL of a custom text-normalization configuration. Applies to + * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @param customTextNormalizationUrl the customTextNormalizationUrl value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setCustomTextNormalizationUrl(String customTextNormalizationUrl) { + this.customTextNormalizationUrl = customTextNormalizationUrl; + return this; + } + + /** + * Get the preferredLocales property: Preferred BCP-47 locales for multilingual synthesis. Applies to + * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @return the preferredLocales value. + */ + @Generated + public List getPreferredLocales() { + return this.preferredLocales; + } + + /** + * Set the preferredLocales property: Preferred BCP-47 locales for multilingual synthesis. Applies to + * `azure-standard`, `azure-custom`, `azure-personal`, and `avatar-voice-sync`. + * + * @param preferredLocales the preferredLocales value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setPreferredLocales(List preferredLocales) { + this.preferredLocales = preferredLocales; + return this; + } + + /** + * Get the style property: The voice speaking style. Applies only when `voice_type` is `azure-standard`. + * + * @return the style value. + */ + @Generated + public String getStyle() { + return this.style; + } + + /** + * Set the style property: The voice speaking style. Applies only when `voice_type` is `azure-standard`. + * + * @param style the style value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setStyle(String style) { + this.style = style; + return this; + } + + /** + * Get the pitch property: The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @return the pitch value. + */ + @Generated + public String getPitch() { + return this.pitch; + } + + /** + * Set the pitch property: The voice pitch adjustment. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @param pitch the pitch value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setPitch(String pitch) { + this.pitch = pitch; + return this; + } + + /** + * Get the volume property: The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @return the volume value. + */ + @Generated + public String getVolume() { + return this.volume; + } + + /** + * Set the volume property: The voice volume adjustment. Applies to `azure-standard`, `azure-custom`, + * `azure-personal`, and `avatar-voice-sync`. + * + * @param volume the volume value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setVolume(String volume) { + this.volume = volume; + return this; + } + + /** + * Get the customVoiceEndpointId property: The Azure custom-voice deployment endpoint identifier. Applies only when + * `voice_type` is `azure-custom`. + * + * @return the customVoiceEndpointId value. + */ + @Generated + public String getCustomVoiceEndpointId() { + return this.customVoiceEndpointId; + } + + /** + * Set the customVoiceEndpointId property: The Azure custom-voice deployment endpoint identifier. Applies only when + * `voice_type` is `azure-custom`. + * + * @param customVoiceEndpointId the customVoiceEndpointId value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setCustomVoiceEndpointId(String customVoiceEndpointId) { + this.customVoiceEndpointId = customVoiceEndpointId; + return this; + } + + /** + * Get the personalVoiceModel property: The Azure personal or avatar voice model. Applies only when `voice_type` is + * `azure-personal` or `avatar-voice-sync`. + * + * @return the personalVoiceModel value. + */ + @Generated + public String getPersonalVoiceModel() { + return this.personalVoiceModel; + } + + /** + * Set the personalVoiceModel property: The Azure personal or avatar voice model. Applies only when `voice_type` is + * `azure-personal` or `avatar-voice-sync`. + * + * @param personalVoiceModel the personalVoiceModel value to set. + * @return the VoiceAgentVoiceConfiguration object itself. + */ + @Generated + public VoiceAgentVoiceConfiguration setPersonalVoiceModel(String personalVoiceModel) { + this.personalVoiceModel = personalVoiceModel; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("voice", this.voice); + jsonWriter.writeStringField("voice_type", this.voiceType == null ? null : this.voiceType.toString()); + jsonWriter.writeStringField("voice_locale", this.voiceLocale); + jsonWriter.writeNumberField("speed", this.speed); + jsonWriter.writeNumberField("voice_temperature", this.voiceTemperature); + jsonWriter.writeStringField("custom_lexicon_url", this.customLexiconUrl); + jsonWriter.writeStringField("custom_text_normalization_url", this.customTextNormalizationUrl); + jsonWriter.writeArrayField("prefer_locales", this.preferredLocales, + (writer, element) -> writer.writeString(element)); + jsonWriter.writeStringField("style", this.style); + jsonWriter.writeStringField("pitch", this.pitch); + jsonWriter.writeStringField("volume", this.volume); + jsonWriter.writeStringField("custom_voice_endpoint_id", this.customVoiceEndpointId); + jsonWriter.writeStringField("personal_voice_model", this.personalVoiceModel); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of VoiceAgentVoiceConfiguration from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of VoiceAgentVoiceConfiguration if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the VoiceAgentVoiceConfiguration. + */ + @Generated + public static VoiceAgentVoiceConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + VoiceAgentVoiceConfiguration deserializedVoiceAgentVoiceConfiguration = new VoiceAgentVoiceConfiguration(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if ("voice".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.voice = reader.getString(); + } else if ("voice_type".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.voiceType = VoiceType.fromString(reader.getString()); + } else if ("voice_locale".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.voiceLocale = reader.getString(); + } else if ("speed".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.speed = reader.getNullable(JsonReader::getDouble); + } else if ("voice_temperature".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.voiceTemperature + = reader.getNullable(JsonReader::getDouble); + } else if ("custom_lexicon_url".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.customLexiconUrl = reader.getString(); + } else if ("custom_text_normalization_url".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.customTextNormalizationUrl = reader.getString(); + } else if ("prefer_locales".equals(fieldName)) { + List preferredLocales = reader.readArray(reader1 -> reader1.getString()); + deserializedVoiceAgentVoiceConfiguration.preferredLocales = preferredLocales; + } else if ("style".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.style = reader.getString(); + } else if ("pitch".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.pitch = reader.getString(); + } else if ("volume".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.volume = reader.getString(); + } else if ("custom_voice_endpoint_id".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.customVoiceEndpointId = reader.getString(); + } else if ("personal_voice_model".equals(fieldName)) { + deserializedVoiceAgentVoiceConfiguration.personalVoiceModel = reader.getString(); + } else { + reader.skipChildren(); + } + } + return deserializedVoiceAgentVoiceConfiguration; + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentWebSocketConnectionOptions.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentWebSocketConnectionOptions.java index 8b392338f9a1b..bebc3591e569f 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentWebSocketConnectionOptions.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceAgentWebSocketConnectionOptions.java @@ -6,6 +6,7 @@ import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Fluent; import com.azure.core.util.logging.ClientLogger; + import java.time.Duration; import java.util.Objects; import java.util.function.Consumer; @@ -24,6 +25,7 @@ public final class VoiceAgentWebSocketConnectionOptions { /** * Gets the maximum number of queued events. + * * @return the capacity, default 256. */ public int getReceiveBufferCapacity() { @@ -32,9 +34,10 @@ public int getReceiveBufferCapacity() { /** * Sets the bounded receive queue capacity. Configure before connecting. + * * @param capacity number of events, between 1 and 65536. * @return this options instance. - * @throws IllegalArgumentException if capacity is outside the supported range. + * @throws IllegalArgumentException if capacity is outside the supported range. */ public VoiceAgentWebSocketConnectionOptions setReceiveBufferCapacity(int capacity) { if (capacity < 1 || capacity > 65536) { @@ -47,6 +50,7 @@ public VoiceAgentWebSocketConnectionOptions setReceiveBufferCapacity(int capacit /** * Gets the maximum accepted JSON message size. + * * @return the size in bytes, default 32 MiB. */ public int getMaxMessageSize() { @@ -55,9 +59,10 @@ public int getMaxMessageSize() { /** * Sets the maximum accepted JSON message size. Oversized messages terminate the connection. + * * @param bytes positive size in bytes. * @return this options instance. - * @throws IllegalArgumentException if bytes is not positive. + * @throws IllegalArgumentException if bytes is not positive. */ public VoiceAgentWebSocketConnectionOptions setMaxMessageSize(int bytes) { if (bytes <= 0) { @@ -69,6 +74,7 @@ public VoiceAgentWebSocketConnectionOptions setMaxMessageSize(int bytes) { /** * Gets the receive queue overflow action. + * * @return the strategy, default ERROR. */ public VoiceAgentWebSocketOverflowStrategy getOverflowStrategy() { @@ -77,6 +83,7 @@ public VoiceAgentWebSocketOverflowStrategy getOverflowStrategy() { /** * Sets the receive queue overflow action. Drop strategies explicitly permit data loss. + * * @param strategy the non-null strategy. * @return this options instance. */ @@ -87,6 +94,7 @@ public VoiceAgentWebSocketConnectionOptions setOverflowStrategy(VoiceAgentWebSoc /** * Gets the callback for skipping malformed events. + * * @return the callback, or null to terminate on malformed events. */ public Consumer getMalformedEventHandler() { @@ -97,6 +105,7 @@ public Consumer getMalformedEventHandler() { * Sets a callback that reports and skips malformed events without terminating reception. * The callback runs on the receive thread and must not block. If it throws, the session terminates. * This does not recover from transport errors or oversized messages. + * * @param handler callback, or null to terminate on malformed events (the default). * @return this options instance. */ @@ -107,7 +116,7 @@ public VoiceAgentWebSocketConnectionOptions setMalformedEventHandler(Consumer { + + /** + * Use a hosted Foundry agent to handle the conversation. + */ + @Generated + public static final VoiceConversationEngineType HOSTED_AGENT = fromString("hosted_agent"); + + /** + * Creates a new instance of VoiceConversationEngineType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public VoiceConversationEngineType() { + } + + /** + * Creates or finds a VoiceConversationEngineType from its string representation. + * + * @param name a name to look for. + * @return the corresponding VoiceConversationEngineType. + */ + @Generated + public static VoiceConversationEngineType fromString(String name) { + return fromString(name, VoiceConversationEngineType.class); + } + + /** + * Gets known VoiceConversationEngineType values. + * + * @return known VoiceConversationEngineType values. + */ + @Generated + public static Collection values() { + return values(VoiceConversationEngineType.class); + } +} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java index 49cdb469011cb..4c46c2dd347b7 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java @@ -29,7 +29,7 @@ public final class VoiceHostedAgentConversationEngine extends VoiceConversationE * The conversation engine type. */ @Generated - private String type = "hosted_agent"; + private VoiceConversationEngineType type = VoiceConversationEngineType.HOSTED_AGENT; /* * The non-empty DNS-like name of the target hosted text agent in the same project. @@ -72,7 +72,7 @@ public VoiceHostedAgentConversationEngine(String name) { */ @Generated @Override - public String getType() { + public VoiceConversationEngineType getType() { return this.type; } @@ -152,7 +152,7 @@ public VoiceHostedAgentConversationEngine setAdditionalProperties(Map additionalProperty : additionalProperties.entrySet()) { @@ -180,7 +180,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { public static VoiceHostedAgentConversationEngine fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { String name = null; - String type = "hosted_agent"; + VoiceConversationEngineType type = VoiceConversationEngineType.HOSTED_AGENT; String version = null; Map additionalProperties = null; while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -189,7 +189,7 @@ public static VoiceHostedAgentConversationEngine fromJson(JsonReader jsonReader) if ("name".equals(fieldName)) { name = reader.getString(); } else if ("type".equals(fieldName)) { - type = reader.getString(); + type = VoiceConversationEngineType.fromString(reader.getString()); } else if ("version".equals(fieldName)) { version = reader.getString(); } else { diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceIds.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceIds.java deleted file mode 100644 index 663e47e7cb959..0000000000000 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceIds.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.agents.models; - -import com.azure.ai.agents.implementation.utils.Beta; -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Defines values for VoiceIds. - */ -@Beta(warningText = "Preview API. VoiceAgents=V1Preview") -public final class VoiceIds extends ExpandableStringEnum { - - /** - * Static value alloy for VoiceIds. - */ - @Generated - public static final VoiceIds ALLOY = fromString("alloy"); - - /** - * Static value ash for VoiceIds. - */ - @Generated - public static final VoiceIds ASH = fromString("ash"); - - /** - * Static value ballad for VoiceIds. - */ - @Generated - public static final VoiceIds BALLAD = fromString("ballad"); - - /** - * Static value coral for VoiceIds. - */ - @Generated - public static final VoiceIds CORAL = fromString("coral"); - - /** - * Static value echo for VoiceIds. - */ - @Generated - public static final VoiceIds ECHO = fromString("echo"); - - /** - * Static value sage for VoiceIds. - */ - @Generated - public static final VoiceIds SAGE = fromString("sage"); - - /** - * Static value shimmer for VoiceIds. - */ - @Generated - public static final VoiceIds SHIMMER = fromString("shimmer"); - - /** - * Static value verse for VoiceIds. - */ - @Generated - public static final VoiceIds VERSE = fromString("verse"); - - /** - * Static value marin for VoiceIds. - */ - @Generated - public static final VoiceIds MARIN = fromString("marin"); - - /** - * Static value cedar for VoiceIds. - */ - @Generated - public static final VoiceIds CEDAR = fromString("cedar"); - - /** - * Creates a new instance of VoiceIds value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public VoiceIds() { - } - - /** - * Creates or finds a VoiceIds from its string representation. - * - * @param name a name to look for. - * @return the corresponding VoiceIds. - */ - @Generated - public static VoiceIds fromString(String name) { - return fromString(name, VoiceIds.class); - } - - /** - * Gets known VoiceIds values. - * - * @return known VoiceIds values. - */ - @Generated - public static Collection values() { - return values(VoiceIds.class); - } -} diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java index 079a44d8ea867..2f4b750b2d8ca 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java @@ -23,13 +23,13 @@ public final class VoiceRecordingChannelLayout implements JsonSerializable writer.writeString(element == null ? null : element.toString())); - if (getMaxOutputTokens() != null) { + if (this.maxOutputTokens != null) { jsonWriter.writeFieldName("max_output_tokens"); - getMaxOutputTokens().writeTo(jsonWriter); + this.maxOutputTokens.writeTo(jsonWriter); } jsonWriter.writeStringField("id", this.id); jsonWriter.writeStringField("conversation_id", this.conversationId); @@ -416,40 +416,4 @@ private VoiceResponse() { public VoiceResponseObjectType getObjectType() { return this.objectType; } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response, inclusive of - * tool calls, that was used in this response. - * - * @return the maxOutputTokens value as a Long, or {@code null} when it is not set or holds another variant. - */ - public Long getMaxOutputTokensAsLong() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(!json.isEmpty() && (Character.isDigit(json.charAt(0)) || json.charAt(0) == '-'))) { - return null; - } - return this.maxOutputTokens.toObject(Long.class); - } - - /** - * Get the maxOutputTokens property: Maximum number of output tokens for a single assistant response, inclusive of - * tool calls, that was used in this response. - * - * @return the maxOutputTokens value as a String, or {@code null} when it is not set or holds another variant. - */ - public String getMaxOutputTokensAsString() { - // AI Tooling: union type - if (this.maxOutputTokens == null) { - return null; - } - String json = this.maxOutputTokens.toString().trim(); - if (!(json.startsWith("\""))) { - return null; - } - return this.maxOutputTokens.toObject(String.class); - } } diff --git a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java index 9a697449b88c9..a5348677eb462 100644 --- a/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java +++ b/sdk/ai/azure-ai-agents/src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java @@ -3,13 +3,16 @@ // Code generated by Microsoft (R) TypeSpec Code Generator. package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; import com.azure.ai.agents.implementation.utils.Beta; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; +import com.azure.core.util.BinaryData; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeAudioFormats; import java.io.IOException; /** @@ -41,7 +44,7 @@ public final class VoiceResponseAudioOutput implements JsonSerializable { VoiceResponseAudioOutput deserializedVoiceResponseAudioOutput = new VoiceResponseAudioOutput(); while (reader.nextToken() != JsonToken.END_OBJECT) { @@ -126,7 +132,10 @@ public static VoiceResponseAudioOutput fromJson(JsonReader jsonReader) throws IO } else if ("voice_locale".equals(fieldName)) { deserializedVoiceResponseAudioOutput.voiceLocale = reader.getString(); } else if ("format".equals(fieldName)) { - deserializedVoiceResponseAudioOutput.format = RealtimeAudioFormat.fromJson(reader); + BinaryData formatData + = reader.getNullable(nonNullReader -> BinaryData.fromObject(nonNullReader.readUntyped())); + deserializedVoiceResponseAudioOutput.format + = OpenAIJsonHelper.fromBinaryData(formatData, RealtimeAudioFormats.class); } else { reader.skipChildren(); } diff --git a/sdk/ai/azure-ai-agents/src/main/resources/META-INF/azure-ai-agents_metadata.json b/sdk/ai/azure-ai-agents/src/main/resources/META-INF/azure-ai-agents_metadata.json index 149b14dc062fb..ac634af86ee7d 100644 --- a/sdk/ai/azure-ai-agents/src/main/resources/META-INF/azure-ai-agents_metadata.json +++ b/sdk/ai/azure-ai-agents/src/main/resources/META-INF/azure-ai-agents_metadata.json @@ -1 +1 @@ -{"flavor":"azure","apiVersions":{"Azure.AI.Projects":"v1"},"crossLanguagePackageId":"Azure.AI.Projects","crossLanguageVersion":"6ec1ef50c53b","crossLanguageDefinitions":{"com.azure.ai.agents.AgentsAsyncClient":"Azure.AI.Projects.Agents","com.azure.ai.agents.AgentsAsyncClient.beginCreateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsAsyncClient.beginCreateOptimizationJobWithModel":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsAsyncClient.cancelOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsAsyncClient.cancelOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsAsyncClient.createAgent":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsAsyncClient.createAgentFromCode":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentFromManifest":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersion":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromCode":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromManifest":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionWithResponse":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsAsyncClient.createAgentWithResponse":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsAsyncClient.createSession":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsAsyncClient.createSessionWithResponse":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsAsyncClient.deleteOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsAsyncClient.deleteOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsAsyncClient.deleteSession":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsAsyncClient.deleteSessionFile":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsAsyncClient.deleteSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsAsyncClient.deleteSessionWithResponse":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsAsyncClient.disableAgent":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsAsyncClient.disableAgentWithResponse":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsAsyncClient.downloadAgentCode":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsAsyncClient.downloadAgentCodeWithResponse":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsAsyncClient.downloadSessionFile":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsAsyncClient.downloadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsAsyncClient.enableAgent":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsAsyncClient.enableAgentWithResponse":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsAsyncClient.estimateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsAsyncClient.estimateOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsAsyncClient.getAgent":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsAsyncClient.getAgentVersionDetails":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsAsyncClient.getAgentVersionDetailsWithResponse":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsAsyncClient.getAgentWithResponse":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365AppPackage":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365AppPackageWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365PublishDefaults":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365PublishDefaultsWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsAsyncClient.getOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsAsyncClient.getOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsAsyncClient.getOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsAsyncClient.getOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsAsyncClient.getSession":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsAsyncClient.getSessionWithResponse":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsAsyncClient.listAgentConversations":"Azure.AI.Projects.Conversations.listConversations","com.azure.ai.agents.AgentsAsyncClient.listAgentVersions":"Azure.AI.Projects.Agents.listAgentVersions","com.azure.ai.agents.AgentsAsyncClient.listAgents":"Azure.AI.Projects.Agents.listAgents","com.azure.ai.agents.AgentsAsyncClient.listOptimizationCandidates":"Azure.AI.Projects.AgentOptimizationJobCandidates.listCandidates","com.azure.ai.agents.AgentsAsyncClient.listOptimizationJobs":"Azure.AI.Projects.AgentOptimizationJobs.list","com.azure.ai.agents.AgentsAsyncClient.listSessionFiles":"Azure.AI.Projects.AgentSessionFiles.listSessionFiles","com.azure.ai.agents.AgentsAsyncClient.listSessions":"Azure.AI.Projects.Agents.listSessions","com.azure.ai.agents.AgentsAsyncClient.promoteOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsAsyncClient.promoteOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsAsyncClient.publishAgentToMicrosoft365":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsAsyncClient.publishAgentToMicrosoft365WithResponse":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsAsyncClient.stopSession":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsAsyncClient.stopSessionWithResponse":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsAsyncClient.updateAgent":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsAsyncClient.updateAgentDetails":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsAsyncClient.updateAgentDetailsWithResponse":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromCode":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromManifest":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.updateAgentWithResponse":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsAsyncClient.uploadSessionFile":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsAsyncClient.uploadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClient":"Azure.AI.Projects.Agents","com.azure.ai.agents.AgentsClient.beginCreateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsClient.beginCreateOptimizationJobWithModel":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsClient.cancelOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsClient.cancelOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsClient.createAgent":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsClient.createAgentFromCode":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsClient.createAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsClient.createAgentFromManifest":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsClient.createAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersion":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsClient.createAgentVersionFromCode":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsClient.createAgentVersionFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsClient.createAgentVersionFromManifest":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersionFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersionWithResponse":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsClient.createAgentWithResponse":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsClient.createSession":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsClient.createSessionWithResponse":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsClient.deleteOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsClient.deleteOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsClient.deleteSession":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsClient.deleteSessionFile":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsClient.deleteSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsClient.deleteSessionWithResponse":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsClient.disableAgent":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsClient.disableAgentWithResponse":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsClient.downloadAgentCode":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsClient.downloadAgentCodeWithResponse":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsClient.downloadSessionFile":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsClient.downloadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsClient.enableAgent":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsClient.enableAgentWithResponse":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsClient.estimateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsClient.estimateOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsClient.getAgent":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsClient.getAgentVersionDetails":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsClient.getAgentVersionDetailsWithResponse":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsClient.getAgentWithResponse":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsClient.getMicrosoft365AppPackage":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsClient.getMicrosoft365AppPackageWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsClient.getMicrosoft365PublishDefaults":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsClient.getMicrosoft365PublishDefaultsWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsClient.getOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsClient.getOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsClient.getOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsClient.getOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsClient.getSession":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsClient.getSessionWithResponse":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsClient.listAgentConversations":"Azure.AI.Projects.Conversations.listConversations","com.azure.ai.agents.AgentsClient.listAgentVersions":"Azure.AI.Projects.Agents.listAgentVersions","com.azure.ai.agents.AgentsClient.listAgents":"Azure.AI.Projects.Agents.listAgents","com.azure.ai.agents.AgentsClient.listOptimizationCandidates":"Azure.AI.Projects.AgentOptimizationJobCandidates.listCandidates","com.azure.ai.agents.AgentsClient.listOptimizationJobs":"Azure.AI.Projects.AgentOptimizationJobs.list","com.azure.ai.agents.AgentsClient.listSessionFiles":"Azure.AI.Projects.AgentSessionFiles.listSessionFiles","com.azure.ai.agents.AgentsClient.listSessions":"Azure.AI.Projects.Agents.listSessions","com.azure.ai.agents.AgentsClient.promoteOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsClient.promoteOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsClient.publishAgentToMicrosoft365":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsClient.publishAgentToMicrosoft365WithResponse":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsClient.stopSession":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsClient.stopSessionWithResponse":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsClient.updateAgent":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsClient.updateAgentDetails":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsClient.updateAgentDetailsWithResponse":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsClient.updateAgentFromCode":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsClient.updateAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsClient.updateAgentFromManifest":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsClient.updateAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsClient.updateAgentWithResponse":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsClient.uploadSessionFile":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClient.uploadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClientBuilder":"Azure.AI.Projects","com.azure.ai.agents.BetaAgentsAsyncClient":"Azure.AI.Projects.Beta.Agents","com.azure.ai.agents.BetaAgentsAsyncClient.createAgentFromPrompt":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsAsyncClient.createAgentFromPromptWithResponse":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsClient":"Azure.AI.Projects.Beta.Agents","com.azure.ai.agents.BetaAgentsClient.createAgentFromPrompt":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsClient.createAgentFromPromptWithResponse":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaMemoryStoresAsyncClient":"Azure.AI.Projects.Beta.MemoryStores","com.azure.ai.agents.BetaMemoryStoresAsyncClient.beginInternalUpdateMemories":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.beginInternalUpdateMemoriesWithModel":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemory":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryStore":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryWithResponse":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemory":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryStore":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryWithResponse":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getUpdateResult":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getUpdateResultWithResponse":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresAsyncClient.internalSearchMemories":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.internalSearchMemoriesWithResponse":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.listMemories":"Azure.AI.Projects.MemoryStores.listMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.listMemoryStores":"Azure.AI.Projects.MemoryStores.listMemoryStores","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemory":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryStore":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryWithResponse":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresClient":"Azure.AI.Projects.Beta.MemoryStores","com.azure.ai.agents.BetaMemoryStoresClient.beginInternalUpdateMemories":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresClient.beginInternalUpdateMemoriesWithModel":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresClient.createMemory":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryStore":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryWithResponse":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresClient.getMemory":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryStore":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryWithResponse":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresClient.getUpdateResult":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresClient.getUpdateResultWithResponse":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresClient.internalSearchMemories":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresClient.internalSearchMemoriesWithResponse":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresClient.listMemories":"Azure.AI.Projects.MemoryStores.listMemories","com.azure.ai.agents.BetaMemoryStoresClient.listMemoryStores":"Azure.AI.Projects.MemoryStores.listMemoryStores","com.azure.ai.agents.BetaMemoryStoresClient.updateMemory":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryStore":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryWithResponse":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient":"Azure.AI.Projects.Beta.VoiceAgents.Conversations","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationResponseWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationResponseItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationResponses":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversations","com.azure.ai.agents.BetaVoiceAgentsConversationsClient":"Azure.AI.Projects.Beta.VoiceAgents.Conversations","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationResponseWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationResponseItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationResponses":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversations","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient":"Azure.AI.Projects.Beta.VoiceAgents.Telephony","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.cancelTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.cancelTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyBinding":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyBinding":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.endTelephonyCall":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.endTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyBinding":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCall":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listTelephonyBindings":"Azure.AI.Projects.AgentTelephony.listTelephonyBindings","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listTelephonyCalls":"Azure.AI.Projects.AgentTelephony.listTelephonyCalls","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.replaceTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.replaceTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.transferTelephonyCall":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.transferTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.updateTelephonyBinding":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.updateTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient":"Azure.AI.Projects.Beta.VoiceAgents.Telephony","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.cancelTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.cancelTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyBinding":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyBinding":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.endTelephonyCall":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.endTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyBinding":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCall":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listTelephonyBindings":"Azure.AI.Projects.AgentTelephony.listTelephonyBindings","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listTelephonyCalls":"Azure.AI.Projects.AgentTelephony.listTelephonyCalls","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.replaceTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.replaceTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.transferTelephonyCall":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.transferTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.updateTelephonyBinding":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.updateTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.ToolboxesAsyncClient":"Azure.AI.Projects.Toolboxes","com.azure.ai.agents.ToolboxesAsyncClient.createToolboxVersion":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.createToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolbox":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxVersion":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesAsyncClient.getToolbox":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxVersion":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxWithResponse":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesAsyncClient.invokeLatestToolboxMcp":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesAsyncClient.invokeLatestToolboxMcpWithResponse":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesAsyncClient.listToolboxVersions":"Azure.AI.Projects.Toolboxes.listToolboxVersions","com.azure.ai.agents.ToolboxesAsyncClient.listToolboxes":"Azure.AI.Projects.Toolboxes.listToolboxes","com.azure.ai.agents.ToolboxesAsyncClient.updateToolbox":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesAsyncClient.updateToolboxWithResponse":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesClient":"Azure.AI.Projects.Toolboxes","com.azure.ai.agents.ToolboxesClient.createToolboxVersion":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesClient.createToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolbox":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesClient.deleteToolboxVersion":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolboxWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesClient.getToolbox":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesClient.getToolboxVersion":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesClient.getToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesClient.getToolboxWithResponse":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesClient.invokeLatestToolboxMcp":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesClient.invokeLatestToolboxMcpWithResponse":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesClient.listToolboxVersions":"Azure.AI.Projects.Toolboxes.listToolboxVersions","com.azure.ai.agents.ToolboxesClient.listToolboxes":"Azure.AI.Projects.Toolboxes.listToolboxes","com.azure.ai.agents.ToolboxesClient.updateToolbox":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesClient.updateToolboxWithResponse":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.implementation.models.AgentDefinitionOptInKeys":"Azure.AI.Projects.AgentDefinitionOptInKeys","com.azure.ai.agents.implementation.models.CreateAgentFromCodeContent":"Azure.AI.Projects.CreateAgentFromCodeContent","com.azure.ai.agents.implementation.models.CreateAgentFromManifestRequest":"Azure.AI.Projects.createAgentFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentOptions":null,"com.azure.ai.agents.implementation.models.CreateAgentRequest":"Azure.AI.Projects.createAgent.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentVersionFromManifestRequest":"Azure.AI.Projects.createAgentVersionFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentVersionRequest":"Azure.AI.Projects.createAgentVersion.Request.anonymous","com.azure.ai.agents.implementation.models.CreateMemoryRequest":"Azure.AI.Projects.createMemory.Request.anonymous","com.azure.ai.agents.implementation.models.CreateMemoryStoreRequest":"Azure.AI.Projects.createMemoryStore.Request.anonymous","com.azure.ai.agents.implementation.models.CreateSessionRequest":"Azure.AI.Projects.createSession.Request.anonymous","com.azure.ai.agents.implementation.models.CreateToolboxVersionRequest":"Azure.AI.Projects.createToolboxVersion.Request.anonymous","com.azure.ai.agents.implementation.models.FoundryFeaturesOptInKeys":"Azure.AI.Projects.FoundryFeaturesOptInKeys","com.azure.ai.agents.implementation.models.GetMicrosoft365AppPackageRequest":"Azure.AI.Projects.getMicrosoft365AppPackage.Request.anonymous","com.azure.ai.agents.implementation.models.ListMemoriesRequest":"Azure.AI.Projects.listMemories.Request.anonymous","com.azure.ai.agents.implementation.models.PublishAgentToMicrosoft365Request":"Azure.AI.Projects.publishAgentToMicrosoft365.Request.anonymous","com.azure.ai.agents.implementation.models.ReplaceTelephonyTransferTargetsRequest":"Azure.AI.Projects.replaceTelephonyTransferTargets.Request.anonymous","com.azure.ai.agents.implementation.models.SearchMemoriesRequest":"Azure.AI.Projects.searchMemories.Request.anonymous","com.azure.ai.agents.implementation.models.TransferTelephonyCallRequest":"Azure.AI.Projects.transferTelephonyCall.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateAgentFromManifestRequest":"Azure.AI.Projects.updateAgentFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateAgentRequest":"Azure.AI.Projects.updateAgent.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoriesRequest":"Azure.AI.Projects.updateMemories.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoryRequest":"Azure.AI.Projects.updateMemory.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoryStoreRequest":"Azure.AI.Projects.updateMemoryStore.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateToolboxInput":"Azure.AI.Projects.UpdateToolboxRequest","com.azure.ai.agents.implementation.models.UpdateToolboxRequest":"Azure.AI.Projects.updateToolbox.Request.anonymous","com.azure.ai.agents.models.A2APreviewTool":"Azure.AI.Projects.A2APreviewTool","com.azure.ai.agents.models.A2APreviewToolboxTool":"Azure.AI.Projects.A2APreviewToolboxTool","com.azure.ai.agents.models.A2AProtocolConfiguration":"Azure.AI.Projects.A2AProtocolConfiguration","com.azure.ai.agents.models.A2AProtocolVersion":"Azure.AI.Projects.A2AProtocolVersion","com.azure.ai.agents.models.A2ATool":"Azure.AI.Projects.A2ATool","com.azure.ai.agents.models.A2AToolCall":"Azure.AI.Projects.A2AToolCall","com.azure.ai.agents.models.A2AToolCallOutput":"Azure.AI.Projects.A2AToolCallOutput","com.azure.ai.agents.models.A2AToolboxTool":"Azure.AI.Projects.A2AToolboxTool","com.azure.ai.agents.models.AISearchIndexResource":"Azure.AI.Projects.AISearchIndexResource","com.azure.ai.agents.models.ActivityProtocolAccessBoundary":"Azure.AI.Projects.ActivityProtocolAccessBoundary","com.azure.ai.agents.models.ActivityProtocolConfiguration":"Azure.AI.Projects.ActivityProtocolConfiguration","com.azure.ai.agents.models.AgentBlueprintReference":"Azure.AI.Projects.AgentBlueprintReference","com.azure.ai.agents.models.AgentBlueprintReferenceType":"Azure.AI.Projects.AgentBlueprintReferenceType","com.azure.ai.agents.models.AgentCard":"Azure.AI.Projects.AgentCard","com.azure.ai.agents.models.AgentCardSkill":"Azure.AI.Projects.AgentCardSkill","com.azure.ai.agents.models.AgentDefinition":"Azure.AI.Projects.AgentDefinition","com.azure.ai.agents.models.AgentDetails":"Azure.AI.Projects.AgentObject","com.azure.ai.agents.models.AgentDetailsVersions":"Azure.AI.Projects.AgentObject.versions.anonymous","com.azure.ai.agents.models.AgentEndpointAuthorizationScheme":"Azure.AI.Projects.AgentEndpointAuthorizationScheme","com.azure.ai.agents.models.AgentEndpointAuthorizationSchemeType":"Azure.AI.Projects.AgentEndpointAuthorizationSchemeType","com.azure.ai.agents.models.AgentEndpointConfig":"Azure.AI.Projects.AgentEndpointConfig","com.azure.ai.agents.models.AgentEndpointProtocol":"Azure.AI.Projects.AgentEndpointProtocol","com.azure.ai.agents.models.AgentHarness":"Azure.AI.Projects.AgentHarness","com.azure.ai.agents.models.AgentIdentity":"Azure.AI.Projects.AgentIdentity","com.azure.ai.agents.models.AgentIdentityStatus":"Azure.AI.Projects.AgentIdentityStatus","com.azure.ai.agents.models.AgentKind":"Azure.AI.Projects.AgentKind","com.azure.ai.agents.models.AgentObjectType":"Azure.AI.Projects.AgentObjectType","com.azure.ai.agents.models.AgentOptimizationAgentCandidateOutput":"Azure.AI.Projects.AgentOptimizationAgentCandidateOutput","com.azure.ai.agents.models.AgentOptimizationBaselineAgentConfiguration":"Azure.AI.Projects.AgentOptimizationBaselineAgentConfiguration","com.azure.ai.agents.models.AgentOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationCandidate","com.azure.ai.agents.models.AgentOptimizationCandidateEvaluation":"Azure.AI.Projects.AgentOptimizationCandidateEvaluation","com.azure.ai.agents.models.AgentOptimizationCandidateExpand":"Azure.AI.Projects.AgentOptimizationCandidateExpand","com.azure.ai.agents.models.AgentOptimizationCandidateOutput":"Azure.AI.Projects.AgentOptimizationCandidateOutput","com.azure.ai.agents.models.AgentOptimizationCandidatePromotionInfo":"Azure.AI.Projects.AgentOptimizationCandidatePromotionInfo","com.azure.ai.agents.models.AgentOptimizationCandidateSearchConfiguration":"Azure.AI.Projects.AgentOptimizationCandidateSearchConfiguration","com.azure.ai.agents.models.AgentOptimizationCandidateStatus":"Azure.AI.Projects.AgentOptimizationCandidateStatus","com.azure.ai.agents.models.AgentOptimizationConfiguration":"Azure.AI.Projects.AgentOptimizationConfiguration","com.azure.ai.agents.models.AgentOptimizationConfigurationBase":"Azure.AI.Projects.AgentOptimizationConfigurationBase","com.azure.ai.agents.models.AgentOptimizationConfigurationType":"Azure.AI.Projects.AgentOptimizationConfigurationType","com.azure.ai.agents.models.AgentOptimizationCostEstimate":"Azure.AI.Projects.AgentOptimizationCostEstimate","com.azure.ai.agents.models.AgentOptimizationDataSourceType":"Azure.AI.Projects.AgentOptimizationDataSourceType","com.azure.ai.agents.models.AgentOptimizationEstimateBand":"Azure.AI.Projects.AgentOptimizationEstimateBand","com.azure.ai.agents.models.AgentOptimizationEstimateInputs":"Azure.AI.Projects.AgentOptimizationEstimateInputs","com.azure.ai.agents.models.AgentOptimizationEstimateResult":"Azure.AI.Projects.AgentOptimizationEstimateResult","com.azure.ai.agents.models.AgentOptimizationEvaluationConfiguration":"Azure.AI.Projects.AgentOptimizationEvaluationConfiguration","com.azure.ai.agents.models.AgentOptimizationEvaluationSet":"Azure.AI.Projects.AgentOptimizationEvaluationSet","com.azure.ai.agents.models.AgentOptimizationEvaluationSetType":"Azure.AI.Projects.AgentOptimizationEvaluationSetType","com.azure.ai.agents.models.AgentOptimizationEvaluatorReference":"Azure.AI.Projects.AgentOptimizationEvaluator","com.azure.ai.agents.models.AgentOptimizationFoundryAgentTargetConfiguration":"Azure.AI.Projects.AgentOptimizationFoundryAgentTargetConfiguration","com.azure.ai.agents.models.AgentOptimizationGoal":"Azure.AI.Projects.AgentOptimizationGoal","com.azure.ai.agents.models.AgentOptimizationInstructionsMutation":"Azure.AI.Projects.AgentOptimizationInstructionsMutation","com.azure.ai.agents.models.AgentOptimizationJob":"Azure.AI.Projects.AgentOptimizationJob","com.azure.ai.agents.models.AgentOptimizationJobLatency":"Azure.AI.Projects.AgentOptimizationJobLatency","com.azure.ai.agents.models.AgentOptimizationJobResult":"Azure.AI.Projects.AgentOptimizationJobResult","com.azure.ai.agents.models.AgentOptimizationJobTokenUsage":"Azure.AI.Projects.AgentOptimizationJobTokenUsage","com.azure.ai.agents.models.AgentOptimizationModelConfiguration":"Azure.AI.Projects.AgentOptimizationModelConfiguration","com.azure.ai.agents.models.AgentOptimizationModelMutation":"Azure.AI.Projects.AgentOptimizationModelMutation","com.azure.ai.agents.models.AgentOptimizationMutation":"Azure.AI.Projects.AgentOptimizationMutation","com.azure.ai.agents.models.AgentOptimizationPromptCandidateOutput":"Azure.AI.Projects.AgentOptimizationPromptCandidateOutput","com.azure.ai.agents.models.AgentOptimizationResultCandidateSummary":"Azure.AI.Projects.AgentOptimizationResultCandidateSummary","com.azure.ai.agents.models.AgentOptimizationSkill":"Azure.AI.Projects.AgentOptimizationSkill","com.azure.ai.agents.models.AgentOptimizationSkillsMutation":"Azure.AI.Projects.AgentOptimizationSkillsMutation","com.azure.ai.agents.models.AgentOptimizationSpace":"Azure.AI.Projects.AgentOptimizationSpace","com.azure.ai.agents.models.AgentOptimizationStage":"Azure.AI.Projects.AgentOptimizationStage","com.azure.ai.agents.models.AgentOptimizationStageEstimate":"Azure.AI.Projects.AgentOptimizationStageEstimate","com.azure.ai.agents.models.AgentOptimizationTargetCompletionDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionDatasetReferenceDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionDatasetReferenceDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionEvaluationSet":"Azure.AI.Projects.AgentOptimizationTargetCompletionEvaluationSet","com.azure.ai.agents.models.AgentOptimizationTargetCompletionInlineDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionInlineDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionTestCase":"Azure.AI.Projects.AgentOptimizationTargetCompletionTestCase","com.azure.ai.agents.models.AgentOptimizationTargetConfiguration":"Azure.AI.Projects.AgentOptimizationTargetConfiguration","com.azure.ai.agents.models.AgentOptimizationTargetConfigurationType":"Azure.AI.Projects.AgentOptimizationTargetConfigurationType","com.azure.ai.agents.models.AgentOptimizationTerminationReason":"Azure.AI.Projects.AgentOptimizationTerminationReason","com.azure.ai.agents.models.AgentOptimizationToolsMutation":"Azure.AI.Projects.AgentOptimizationToolsMutation","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationDataSource","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationDatasetReferenceDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationDatasetReferenceDataSource","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationEvaluationSet":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationEvaluationSet","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationInlineDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationInlineDataSource","com.azure.ai.agents.models.AgentReference":"Azure.AI.Projects.AgentReference","com.azure.ai.agents.models.AgentSessionResource":"Azure.AI.Projects.AgentSessionResource","com.azure.ai.agents.models.AgentSessionStatus":"Azure.AI.Projects.AgentSessionStatus","com.azure.ai.agents.models.AgentState":"Azure.AI.Projects.AgentState","com.azure.ai.agents.models.AgentStateSource":"Azure.AI.Projects.AgentStateSource","com.azure.ai.agents.models.AgentVersionDetails":"Azure.AI.Projects.AgentVersionObject","com.azure.ai.agents.models.AgentVersionStatus":"Azure.AI.Projects.AgentVersionStatus","com.azure.ai.agents.models.ApiError":"OpenAI.Error","com.azure.ai.agents.models.ApplyPatchToolParameter":"OpenAI.ToolApplyPatchToolParam","com.azure.ai.agents.models.ApproximateLocation":"OpenAI.ApproximateLocation","com.azure.ai.agents.models.AudioTranscription":"OpenAI.AudioTranscription","com.azure.ai.agents.models.AudioTranscriptionModel":"OpenAI.AudioTranscription.model.anonymous","com.azure.ai.agents.models.AutoCodeInterpreterToolParameter":"OpenAI.AutoCodeInterpreterToolParam","com.azure.ai.agents.models.AzureAISearchQueryType":"Azure.AI.Projects.AzureAISearchQueryType","com.azure.ai.agents.models.AzureAISearchTool":"Azure.AI.Projects.AzureAISearchTool","com.azure.ai.agents.models.AzureAISearchToolCall":"Azure.AI.Projects.AzureAISearchToolCall","com.azure.ai.agents.models.AzureAISearchToolCallOutput":"Azure.AI.Projects.AzureAISearchToolCallOutput","com.azure.ai.agents.models.AzureAISearchToolResource":"Azure.AI.Projects.AzureAISearchToolResource","com.azure.ai.agents.models.AzureAISearchToolboxTool":"Azure.AI.Projects.AzureAISearchToolboxTool","com.azure.ai.agents.models.AzureCreateResponseDetails":"Azure.AI.Projects.AzureCreateResponseDetails","com.azure.ai.agents.models.AzureCreateResponseOptions":"Azure.AI.Projects.AzureCreateResponseOptions","com.azure.ai.agents.models.AzureFunctionBinding":"Azure.AI.Projects.AzureFunctionBinding","com.azure.ai.agents.models.AzureFunctionDefinition":"Azure.AI.Projects.AzureFunctionDefinition","com.azure.ai.agents.models.AzureFunctionDefinitionDetails":"Azure.AI.Projects.AzureFunctionDefinition.function.anonymous","com.azure.ai.agents.models.AzureFunctionStorageQueue":"Azure.AI.Projects.AzureFunctionStorageQueue","com.azure.ai.agents.models.AzureFunctionTool":"Azure.AI.Projects.AzureFunctionTool","com.azure.ai.agents.models.AzureFunctionToolCall":"Azure.AI.Projects.AzureFunctionToolCall","com.azure.ai.agents.models.AzureFunctionToolCallOutput":"Azure.AI.Projects.AzureFunctionToolCallOutput","com.azure.ai.agents.models.AzureUserSecurityContext":"Azure.AI.Projects.AzureUserSecurityContext","com.azure.ai.agents.models.BingCustomSearchConfiguration":"Azure.AI.Projects.BingCustomSearchConfiguration","com.azure.ai.agents.models.BingCustomSearchPreviewTool":"Azure.AI.Projects.BingCustomSearchPreviewTool","com.azure.ai.agents.models.BingCustomSearchToolCall":"Azure.AI.Projects.BingCustomSearchToolCall","com.azure.ai.agents.models.BingCustomSearchToolCallOutput":"Azure.AI.Projects.BingCustomSearchToolCallOutput","com.azure.ai.agents.models.BingCustomSearchToolParameters":"Azure.AI.Projects.BingCustomSearchToolParameters","com.azure.ai.agents.models.BingGroundingSearchConfiguration":"Azure.AI.Projects.BingGroundingSearchConfiguration","com.azure.ai.agents.models.BingGroundingSearchToolParameters":"Azure.AI.Projects.BingGroundingSearchToolParameters","com.azure.ai.agents.models.BingGroundingTool":"Azure.AI.Projects.BingGroundingTool","com.azure.ai.agents.models.BingGroundingToolCall":"Azure.AI.Projects.BingGroundingToolCall","com.azure.ai.agents.models.BingGroundingToolCallOutput":"Azure.AI.Projects.BingGroundingToolCallOutput","com.azure.ai.agents.models.BotServiceAuthorizationScheme":"Azure.AI.Projects.BotServiceAuthorizationScheme","com.azure.ai.agents.models.BotServiceRbacAuthorizationScheme":"Azure.AI.Projects.BotServiceRbacAuthorizationScheme","com.azure.ai.agents.models.BotServiceTenantAuthorizationScheme":"Azure.AI.Projects.BotServiceTenantAuthorizationScheme","com.azure.ai.agents.models.BrowserAutomationPreviewTool":"Azure.AI.Projects.BrowserAutomationPreviewTool","com.azure.ai.agents.models.BrowserAutomationPreviewToolboxTool":"Azure.AI.Projects.BrowserAutomationPreviewToolboxTool","com.azure.ai.agents.models.BrowserAutomationTool":"Azure.AI.Projects.BrowserAutomationTool","com.azure.ai.agents.models.BrowserAutomationToolCall":"Azure.AI.Projects.BrowserAutomationToolCall","com.azure.ai.agents.models.BrowserAutomationToolCallOutput":"Azure.AI.Projects.BrowserAutomationToolCallOutput","com.azure.ai.agents.models.BrowserAutomationToolConnectionParameters":"Azure.AI.Projects.BrowserAutomationToolConnectionParameters","com.azure.ai.agents.models.BrowserAutomationToolParameters":"Azure.AI.Projects.BrowserAutomationToolParameters","com.azure.ai.agents.models.BrowserAutomationToolboxTool":"Azure.AI.Projects.BrowserAutomationToolboxTool","com.azure.ai.agents.models.CallableToolAllowedCaller":"OpenAI.CallableToolAllowedCaller","com.azure.ai.agents.models.CaptureStructuredOutputsTool":"Azure.AI.Projects.CaptureStructuredOutputsTool","com.azure.ai.agents.models.ChatSummaryMemoryItem":"Azure.AI.Projects.ChatSummaryMemoryItem","com.azure.ai.agents.models.CodeConfiguration":"Azure.AI.Projects.CodeConfiguration","com.azure.ai.agents.models.CodeDependencyResolution":"Azure.AI.Projects.CodeDependencyResolution","com.azure.ai.agents.models.CodeFileDetails":null,"com.azure.ai.agents.models.CodeInterpreterTool":"OpenAI.ToolCodeInterpreterTool","com.azure.ai.agents.models.CodeInterpreterToolboxTool":"Azure.AI.Projects.CodeInterpreterToolboxTool","com.azure.ai.agents.models.ComputerEnvironment":"ComputerEnvironmentExpandable","com.azure.ai.agents.models.ComputerTool":"OpenAI.ToolComputerTool","com.azure.ai.agents.models.ComputerUsePreviewTool":"OpenAI.ToolComputerUsePreviewTool","com.azure.ai.agents.models.ContainerAutoParameter":"OpenAI.ContainerAutoParam","com.azure.ai.agents.models.ContainerConfiguration":"Azure.AI.Projects.ContainerConfiguration","com.azure.ai.agents.models.ContainerMemoryLimit":"ContainerMemoryLimitExpandable","com.azure.ai.agents.models.ContainerNetworkPolicyAllowlistParameter":"OpenAI.ContainerNetworkPolicyAllowlistParam","com.azure.ai.agents.models.ContainerNetworkPolicyDisabledParameter":"OpenAI.ContainerNetworkPolicyDisabledParam","com.azure.ai.agents.models.ContainerNetworkPolicyDomainSecretParameter":"OpenAI.ContainerNetworkPolicyDomainSecretParam","com.azure.ai.agents.models.ContainerNetworkPolicyParamType":"OpenAI.ContainerNetworkPolicyParamType","com.azure.ai.agents.models.ContainerNetworkPolicyParameter":"OpenAI.ContainerNetworkPolicyParam","com.azure.ai.agents.models.ContainerSkill":"OpenAI.ContainerSkill","com.azure.ai.agents.models.ContainerSkillType":"OpenAI.ContainerSkillType","com.azure.ai.agents.models.CreateAgentVersionFromCodeContent":"Azure.AI.Projects.CreateAgentVersionFromCodeContent","com.azure.ai.agents.models.CreateAgentVersionFromCodeMetadata":"Azure.AI.Projects.CreateAgentVersionFromCodeMetadata","com.azure.ai.agents.models.CreateAgentVersionInput":"Azure.AI.Projects.CreateAgentVersionRequest","com.azure.ai.agents.models.CreateAgentVersionOptions":null,"com.azure.ai.agents.models.CreateTeamsPhoneExtensibilityTelephonyBindingInput":"Azure.AI.Projects.CreateTeamsPhoneExtensibilityTelephonyBindingRequest","com.azure.ai.agents.models.CreateTelephonyBindingInput":"Azure.AI.Projects.CreateTelephonyBindingRequest","com.azure.ai.agents.models.CreateTelephonyCallJobInput":"Azure.AI.Projects.CreateTelephonyCallJobRequest","com.azure.ai.agents.models.CreateTwilioTelephonyBindingInput":"Azure.AI.Projects.CreateTwilioTelephonyBindingRequest","com.azure.ai.agents.models.CustomGrammarFormatParameter":"OpenAI.CustomGrammarFormatParam","com.azure.ai.agents.models.CustomTextFormatParameter":"OpenAI.CustomTextFormatParam","com.azure.ai.agents.models.CustomToolParamFormat":"OpenAI.CustomToolParamFormat","com.azure.ai.agents.models.CustomToolParamFormatType":"OpenAI.CustomToolParamFormatType","com.azure.ai.agents.models.CustomToolParameter":"OpenAI.ToolCustomToolParam","com.azure.ai.agents.models.DigitalWorkerType":"Azure.AI.Projects.DigitalWorkerType","com.azure.ai.agents.models.EntraAuthorizationScheme":"Azure.AI.Projects.EntraAuthorizationScheme","com.azure.ai.agents.models.EvaluationAzureStandardVoiceModelConfiguration":"Azure.AI.Projects.EvaluationAzureStandardVoiceModelConfiguration","com.azure.ai.agents.models.EvaluationModelConfiguration":"Azure.AI.Projects.EvaluationModelConfiguration","com.azure.ai.agents.models.EvaluationVoiceModelConfiguration":"Azure.AI.Projects.EvaluationVoiceModelConfiguration","com.azure.ai.agents.models.ExternalAgentDefinition":"Azure.AI.Projects.ExternalAgentDefinition","com.azure.ai.agents.models.FabricDataAgentToolCall":"Azure.AI.Projects.FabricDataAgentToolCall","com.azure.ai.agents.models.FabricDataAgentToolCallOutput":"Azure.AI.Projects.FabricDataAgentToolCallOutput","com.azure.ai.agents.models.FabricDataAgentToolParameters":"Azure.AI.Projects.FabricDataAgentToolParameters","com.azure.ai.agents.models.FabricIqPreviewTool":"Azure.AI.Projects.FabricIQPreviewTool","com.azure.ai.agents.models.FabricIqPreviewToolboxTool":"Azure.AI.Projects.FabricIQPreviewToolboxTool","com.azure.ai.agents.models.FileSearchTool":"OpenAI.ToolFileSearchTool","com.azure.ai.agents.models.FileSearchToolboxTool":"Azure.AI.Projects.FileSearchToolboxTool","com.azure.ai.agents.models.FixedRatioVersionSelectionRule":"Azure.AI.Projects.FixedRatioVersionSelectionRule","com.azure.ai.agents.models.FunctionShellToolParamEnvironment":"OpenAI.FunctionShellToolParamEnvironment","com.azure.ai.agents.models.FunctionShellToolParamEnvironmentType":"OpenAI.FunctionShellToolParamEnvironmentType","com.azure.ai.agents.models.FunctionShellToolParameter":"OpenAI.ToolFunctionShellToolParam","com.azure.ai.agents.models.FunctionShellToolParameterEnvironmentContainerReferenceParameter":"OpenAI.FunctionShellToolParamEnvironmentContainerReferenceParam","com.azure.ai.agents.models.FunctionShellToolParameterEnvironmentLocalEnvironmentParameter":"OpenAI.FunctionShellToolParamEnvironmentLocalEnvironmentParam","com.azure.ai.agents.models.FunctionTool":"OpenAI.ToolFunctionTool","com.azure.ai.agents.models.GetMicrosoft365AppPackageOptions":null,"com.azure.ai.agents.models.GitHubCopilotBuiltInTool":"Azure.AI.Projects.GitHubCopilotBuiltInTool","com.azure.ai.agents.models.GitHubCopilotHarness":"Azure.AI.Projects.GitHubCopilotHarness","com.azure.ai.agents.models.GitHubCopilotToolsetConfig":"Azure.AI.Projects.GitHubCopilotToolsetConfig","com.azure.ai.agents.models.GitHubCopilotToolsetDefaultConfig":"Azure.AI.Projects.GitHubCopilotToolsetDefaultConfig","com.azure.ai.agents.models.GitHubCopilotToolsetPreview":"Azure.AI.Projects.GitHubCopilotToolsetPreview","com.azure.ai.agents.models.GrammarSyntax":"GrammarSyntaxExpandable","com.azure.ai.agents.models.HeaderTelemetryEndpointAuth":"Azure.AI.Projects.HeaderTelemetryEndpointAuth","com.azure.ai.agents.models.HostedAgentDefinition":"Azure.AI.Projects.HostedAgentDefinition","com.azure.ai.agents.models.HybridSearchOptions":"OpenAI.HybridSearchOptions","com.azure.ai.agents.models.ImageGenActionEnum":"ImageGenActionEnumExpandable","com.azure.ai.agents.models.ImageGenTool":"OpenAI.ToolImageGenTool","com.azure.ai.agents.models.ImageGenToolBackground":"ImageGenToolBackgroundExpandable","com.azure.ai.agents.models.ImageGenToolInputImageMask":"OpenAI.ImageGenToolInputImageMask","com.azure.ai.agents.models.ImageGenToolModel":"OpenAI.ToolImageGenTool.model.anonymous","com.azure.ai.agents.models.ImageGenToolModeration":"ImageGenToolModerationExpandable","com.azure.ai.agents.models.ImageGenToolOutputFormat":"ImageGenToolOutputFormatExpandable","com.azure.ai.agents.models.ImageGenToolQuality":"ImageGenToolQualityExpandable","com.azure.ai.agents.models.ImageGenToolSize":"ImageGenToolSizeExpandable","com.azure.ai.agents.models.IncludeEnum":"OpenAI.IncludeEnum","com.azure.ai.agents.models.InlineSkillParameter":"OpenAI.InlineSkillParam","com.azure.ai.agents.models.InlineSkillSourceParameter":"OpenAI.InlineSkillSourceParam","com.azure.ai.agents.models.InputFidelity":"InputFidelityExpandable","com.azure.ai.agents.models.InvocationsProtocolConfiguration":"Azure.AI.Projects.InvocationsProtocolConfiguration","com.azure.ai.agents.models.InvocationsWsProtocolConfiguration":"Azure.AI.Projects.InvocationsWsProtocolConfiguration","com.azure.ai.agents.models.JobStatus":"Azure.AI.Projects.JobStatus","com.azure.ai.agents.models.ListMemoriesOptions":null,"com.azure.ai.agents.models.LocalShellToolParameter":"OpenAI.ToolLocalShellToolParam","com.azure.ai.agents.models.LocalSkillParameter":"OpenAI.LocalSkillParam","com.azure.ai.agents.models.ManagedAgentIdentityBlueprintReference":"Azure.AI.Projects.ManagedAgentIdentityBlueprintReference","com.azure.ai.agents.models.McpListToolsTool":"OpenAI.MCPListToolsTool","com.azure.ai.agents.models.McpListToolsToolAnnotations":"OpenAI.MCPListToolsToolAnnotations","com.azure.ai.agents.models.McpListToolsToolInputSchema":"OpenAI.MCPListToolsToolInputSchema","com.azure.ai.agents.models.McpProtocolConfiguration":"Azure.AI.Projects.McpProtocolConfiguration","com.azure.ai.agents.models.McpTool":"OpenAI.ToolMcpTool","com.azure.ai.agents.models.McpToolConnectorId":"McpToolConnectorIdExpandable","com.azure.ai.agents.models.McpToolFilter":"OpenAI.MCPToolFilter","com.azure.ai.agents.models.McpToolRequireApproval":"OpenAI.MCPToolRequireApproval","com.azure.ai.agents.models.McpToolboxTool":"Azure.AI.Projects.MCPToolboxTool","com.azure.ai.agents.models.MemoryCommandToolCall":"Azure.AI.Projects.MemoryCommandToolCall","com.azure.ai.agents.models.MemoryCommandToolCallOutput":"Azure.AI.Projects.MemoryCommandToolCallOutput","com.azure.ai.agents.models.MemoryItem":"Azure.AI.Projects.MemoryItem","com.azure.ai.agents.models.MemoryItemKind":"Azure.AI.Projects.MemoryItemKind","com.azure.ai.agents.models.MemoryOperation":"Azure.AI.Projects.MemoryOperation","com.azure.ai.agents.models.MemoryOperationKind":"Azure.AI.Projects.MemoryOperationKind","com.azure.ai.agents.models.MemorySearchItem":"Azure.AI.Projects.MemorySearchItem","com.azure.ai.agents.models.MemorySearchOptions":"Azure.AI.Projects.MemorySearchOptions","com.azure.ai.agents.models.MemorySearchPreviewTool":"Azure.AI.Projects.MemorySearchPreviewTool","com.azure.ai.agents.models.MemorySearchToolCall":"Azure.AI.Projects.MemorySearchToolCall","com.azure.ai.agents.models.MemoryStoreDefaultDefinition":"Azure.AI.Projects.MemoryStoreDefaultDefinition","com.azure.ai.agents.models.MemoryStoreDefaultOptions":"Azure.AI.Projects.MemoryStoreDefaultOptions","com.azure.ai.agents.models.MemoryStoreDefinition":"Azure.AI.Projects.MemoryStoreDefinition","com.azure.ai.agents.models.MemoryStoreDetails":"Azure.AI.Projects.MemoryStoreObject","com.azure.ai.agents.models.MemoryStoreKind":"Azure.AI.Projects.MemoryStoreKind","com.azure.ai.agents.models.MemoryStoreObjectType":"Azure.AI.Projects.MemoryStoreObjectType","com.azure.ai.agents.models.MemoryStoreOperationUsage":"Azure.AI.Projects.MemoryStoreOperationUsage","com.azure.ai.agents.models.MemoryStoreSearchResponse":"Azure.AI.Projects.MemoryStoreSearchResponse","com.azure.ai.agents.models.MemoryStoreUpdateCompletedResult":"Azure.AI.Projects.MemoryStoreUpdateCompletedResult","com.azure.ai.agents.models.MemoryStoreUpdateResponse":"Azure.AI.Projects.MemoryStoreUpdateResponse","com.azure.ai.agents.models.MemoryStoreUpdateStatus":"Azure.AI.Projects.MemoryStoreUpdateStatus","com.azure.ai.agents.models.Microsoft365PermissionScopes":"Azure.AI.Projects.Microsoft365PermissionScopes","com.azure.ai.agents.models.Microsoft365PublishDefaults":"Azure.AI.Projects.Microsoft365PublishDefaults","com.azure.ai.agents.models.Microsoft365PublishResult":"Azure.AI.Projects.Microsoft365PublishResponse","com.azure.ai.agents.models.Microsoft365PublishScope":"Azure.AI.Projects.Microsoft365PublishScope","com.azure.ai.agents.models.MicrosoftCopilotBuiltInTool":"Azure.AI.Projects.MicrosoftCopilotBuiltInTool","com.azure.ai.agents.models.MicrosoftCopilotHarness":"Azure.AI.Projects.MicrosoftCopilotHarness","com.azure.ai.agents.models.MicrosoftCopilotToolsetConfiguration":"Azure.AI.Projects.MicrosoftCopilotToolsetConfig","com.azure.ai.agents.models.MicrosoftCopilotToolsetDefaultConfiguration":"Azure.AI.Projects.MicrosoftCopilotToolsetDefaultConfig","com.azure.ai.agents.models.MicrosoftCopilotToolsetPreview":"Azure.AI.Projects.MicrosoftCopilotToolsetPreview","com.azure.ai.agents.models.MicrosoftFabricPreviewTool":"Azure.AI.Projects.MicrosoftFabricPreviewTool","com.azure.ai.agents.models.ModelRouterAttempt":"Azure.AI.Projects.ModelRouterAttempt","com.azure.ai.agents.models.ModelRouterAttemptError":"Azure.AI.Projects.ModelRouterAttemptError","com.azure.ai.agents.models.ModelRouterAttemptResult":"Azure.AI.Projects.ModelRouterAttemptResult","com.azure.ai.agents.models.ModelRouterDetails":"Azure.AI.Projects.ModelRouterDetails","com.azure.ai.agents.models.ModelRouterMode":"Azure.AI.Projects.ModelRouterMode","com.azure.ai.agents.models.ModelSamplingParameters":"Azure.AI.Projects.ModelSamplingParams","com.azure.ai.agents.models.ModelSelectionDetails":"Azure.AI.Projects.ModelSelectionDetails","com.azure.ai.agents.models.NamespaceTool":"OpenAI.NamespaceToolParam","com.azure.ai.agents.models.OpenApiAnonymousAuthDetails":"Azure.AI.Projects.OpenApiAnonymousAuthDetails","com.azure.ai.agents.models.OpenApiAuthDetails":"Azure.AI.Projects.OpenApiAuthDetails","com.azure.ai.agents.models.OpenApiAuthType":"Azure.AI.Projects.OpenApiAuthType","com.azure.ai.agents.models.OpenApiFunctionDefinition":"Azure.AI.Projects.OpenApiFunctionDefinition","com.azure.ai.agents.models.OpenApiFunctionDefinitionFunction":"Azure.AI.Projects.OpenApiFunctionDefinition.function.anonymous","com.azure.ai.agents.models.OpenApiManagedAuthDetails":"Azure.AI.Projects.OpenApiManagedAuthDetails","com.azure.ai.agents.models.OpenApiManagedSecurityScheme":"Azure.AI.Projects.OpenApiManagedSecurityScheme","com.azure.ai.agents.models.OpenApiProjectConnectionAuthDetails":"Azure.AI.Projects.OpenApiProjectConnectionAuthDetails","com.azure.ai.agents.models.OpenApiProjectConnectionSecurityScheme":"Azure.AI.Projects.OpenApiProjectConnectionSecurityScheme","com.azure.ai.agents.models.OpenApiTool":"Azure.AI.Projects.OpenApiTool","com.azure.ai.agents.models.OpenApiToolCall":"Azure.AI.Projects.OpenApiToolCall","com.azure.ai.agents.models.OpenApiToolCallOutput":"Azure.AI.Projects.OpenApiToolCallOutput","com.azure.ai.agents.models.OpenApiToolboxTool":"Azure.AI.Projects.OpenApiToolboxTool","com.azure.ai.agents.models.OptimizationContext":"Azure.AI.Projects.OptimizationContext","com.azure.ai.agents.models.OptimizationContextType":"Azure.AI.Projects.OptimizationContextType","com.azure.ai.agents.models.OtlpTelemetryEndpoint":"Azure.AI.Projects.OtlpTelemetryEndpoint","com.azure.ai.agents.models.PageOrder":"Azure.AI.Projects.PageOrder","com.azure.ai.agents.models.ProceduralMemoryItem":"Azure.AI.Projects.ProceduralMemoryItem","com.azure.ai.agents.models.ProgrammaticToolCallingParameter":"OpenAI.ToolProgrammaticToolCallingParam","com.azure.ai.agents.models.PromptAgentDefinition":"Azure.AI.Projects.PromptAgentDefinition","com.azure.ai.agents.models.PromptAgentDefinitionTextOptions":"Azure.AI.Projects.PromptAgentDefinitionTextOptions","com.azure.ai.agents.models.PromptOptimizationConfiguration":"Azure.AI.Projects.PromptOptimizationConfiguration","com.azure.ai.agents.models.ProtocolConfiguration":"Azure.AI.Projects.ProtocolConfiguration","com.azure.ai.agents.models.ProtocolVersionRecord":"Azure.AI.Projects.ProtocolVersionRecord","com.azure.ai.agents.models.PstnTelephonyTransferDestination":"Azure.AI.Projects.PSTNTelephonyTransferDestination","com.azure.ai.agents.models.PublishAgentToMicrosoft365Options":null,"com.azure.ai.agents.models.PublishApprovalStatus":"Azure.AI.Projects.PublishApprovalStatus","com.azure.ai.agents.models.RaiConfig":"Azure.AI.Projects.RaiConfig","com.azure.ai.agents.models.RaiInvocationContentType":"Azure.AI.Projects.RaiInvocationContentType","com.azure.ai.agents.models.RaiInvocationModeration":"Azure.AI.Projects.RaiInvocationModeration","com.azure.ai.agents.models.RaiInvocationResponseMode":"Azure.AI.Projects.RaiInvocationMode","com.azure.ai.agents.models.RaiSseTextSelector":"Azure.AI.Projects.RaiSseTextSelector","com.azure.ai.agents.models.RankerVersionType":"RankerVersionTypeExpandable","com.azure.ai.agents.models.RankingOptions":"OpenAI.RankingOptions","com.azure.ai.agents.models.RealtimeAudioFormat":"OpenAI.RealtimeAudioFormats","com.azure.ai.agents.models.RealtimeAudioFormatType":"OpenAI.RealtimeAudioFormatsType","com.azure.ai.agents.models.RealtimeClientEvent":"OpenAI.RealtimeClientEvent","com.azure.ai.agents.models.RealtimeClientEventType":"OpenAI.RealtimeClientEventType","com.azure.ai.agents.models.RealtimeConversationCreatedEvent":"OpenAI.RealtimeServerEventConversationCreated","com.azure.ai.agents.models.RealtimeConversationItem":"OpenAI.RealtimeConversationItem","com.azure.ai.agents.models.RealtimeConversationItemAddedEvent":"OpenAI.RealtimeServerEventConversationItemAdded","com.azure.ai.agents.models.RealtimeConversationItemAssistantMessage":"OpenAI.RealtimeConversationItemMessageAssistant","com.azure.ai.agents.models.RealtimeConversationItemCreateEvent":"OpenAI.RealtimeClientEventConversationItemCreate","com.azure.ai.agents.models.RealtimeConversationItemCreatedEvent":"OpenAI.RealtimeServerEventConversationItemCreated","com.azure.ai.agents.models.RealtimeConversationItemDeleteEvent":"OpenAI.RealtimeClientEventConversationItemDelete","com.azure.ai.agents.models.RealtimeConversationItemDeletedEvent":"OpenAI.RealtimeServerEventConversationItemDeleted","com.azure.ai.agents.models.RealtimeConversationItemDoneEvent":"OpenAI.RealtimeServerEventConversationItemDone","com.azure.ai.agents.models.RealtimeConversationItemFunctionCall":"OpenAI.RealtimeConversationItemFunctionCall","com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput":"OpenAI.RealtimeConversationItemFunctionCallOutput","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionCompletedEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionDeltaEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionDelta","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionFailedEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailed","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionSegmentEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionSegment","com.azure.ai.agents.models.RealtimeConversationItemMessage":"OpenAI.RealtimeConversationItemMessage","com.azure.ai.agents.models.RealtimeConversationItemMessageType":"OpenAI.RealtimeConversationItemMessageType","com.azure.ai.agents.models.RealtimeConversationItemObjectType":"RealtimeConversationItemObject","com.azure.ai.agents.models.RealtimeConversationItemRetrieveEvent":"OpenAI.RealtimeClientEventConversationItemRetrieve","com.azure.ai.agents.models.RealtimeConversationItemRetrievedEvent":"OpenAI.RealtimeServerEventConversationItemRetrieved","com.azure.ai.agents.models.RealtimeConversationItemSystemMessage":"OpenAI.RealtimeConversationItemMessageSystem","com.azure.ai.agents.models.RealtimeConversationItemTruncateEvent":"OpenAI.RealtimeClientEventConversationItemTruncate","com.azure.ai.agents.models.RealtimeConversationItemTruncatedEvent":"OpenAI.RealtimeServerEventConversationItemTruncated","com.azure.ai.agents.models.RealtimeConversationItemType":"OpenAI.RealtimeConversationItemType","com.azure.ai.agents.models.RealtimeConversationItemUserMessage":"OpenAI.RealtimeConversationItemMessageUser","com.azure.ai.agents.models.RealtimeErrorEvent":"OpenAI.RealtimeServerEventRealtimeServerEventError","com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent":"OpenAI.RealtimeClientEventInputAudioBufferAppend","com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent":"OpenAI.RealtimeClientEventInputAudioBufferClear","com.azure.ai.agents.models.RealtimeInputAudioBufferClearedEvent":"OpenAI.RealtimeServerEventInputAudioBufferCleared","com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent":"OpenAI.RealtimeClientEventInputAudioBufferCommit","com.azure.ai.agents.models.RealtimeInputAudioBufferCommittedEvent":"OpenAI.RealtimeServerEventInputAudioBufferCommitted","com.azure.ai.agents.models.RealtimeInputAudioBufferDtmfReceivedEvent":"OpenAI.RealtimeServerEventInputAudioBufferDtmfEventReceived","com.azure.ai.agents.models.RealtimeInputAudioBufferSpeechStartedEvent":"OpenAI.RealtimeServerEventInputAudioBufferSpeechStarted","com.azure.ai.agents.models.RealtimeInputAudioBufferSpeechStoppedEvent":"OpenAI.RealtimeServerEventInputAudioBufferSpeechStopped","com.azure.ai.agents.models.RealtimeInputAudioBufferTimeoutTriggeredEvent":"OpenAI.RealtimeServerEventInputAudioBufferTimeoutTriggered","com.azure.ai.agents.models.RealtimeMcpApprovalInput":"OpenAI.RealtimeMCPApprovalRequest","com.azure.ai.agents.models.RealtimeMcpApprovalOutput":"OpenAI.RealtimeMCPApprovalResponse","com.azure.ai.agents.models.RealtimeMcpError":"OpenAI.RealtimeMCPError","com.azure.ai.agents.models.RealtimeMcpErrorType":"OpenAI.RealtimeMcpErrorType","com.azure.ai.agents.models.RealtimeMcpHttpError":"OpenAI.RealtimeMCPHTTPError","com.azure.ai.agents.models.RealtimeMcpListTools":"OpenAI.RealtimeMCPListTools","com.azure.ai.agents.models.RealtimeMcpListToolsCompletedEvent":"OpenAI.RealtimeServerEventMCPListToolsCompleted","com.azure.ai.agents.models.RealtimeMcpListToolsFailedEvent":"OpenAI.RealtimeServerEventMCPListToolsFailed","com.azure.ai.agents.models.RealtimeMcpListToolsInProgressEvent":"OpenAI.RealtimeServerEventMCPListToolsInProgress","com.azure.ai.agents.models.RealtimeMcpProtocolError":"OpenAI.RealtimeMCPProtocolError","com.azure.ai.agents.models.RealtimeMcpToolCall":"OpenAI.RealtimeMCPToolCall","com.azure.ai.agents.models.RealtimeMcpToolExecutionError":"OpenAI.RealtimeMCPToolExecutionError","com.azure.ai.agents.models.RealtimeOutputAudioBufferClearEvent":"OpenAI.RealtimeClientEventOutputAudioBufferClear","com.azure.ai.agents.models.RealtimeOutputAudioBufferClearedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferCleared","com.azure.ai.agents.models.RealtimeOutputAudioBufferStartedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferStarted","com.azure.ai.agents.models.RealtimeOutputAudioBufferStoppedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferStopped","com.azure.ai.agents.models.RealtimePcmAudioFormat":"OpenAI.RealtimeAudioFormatsAudioPcm","com.azure.ai.agents.models.RealtimePcmaAudioFormat":"OpenAI.RealtimeAudioFormatsAudioPcma","com.azure.ai.agents.models.RealtimePcmuAudioFormat":"OpenAI.RealtimeAudioFormatsAudioPcmu","com.azure.ai.agents.models.RealtimeRateLimitsUpdatedEvent":"OpenAI.RealtimeServerEventRateLimitsUpdated","com.azure.ai.agents.models.RealtimeResponseAudioDeltaEvent":"OpenAI.RealtimeServerEventResponseAudioDelta","com.azure.ai.agents.models.RealtimeResponseAudioDoneEvent":"OpenAI.RealtimeServerEventResponseAudioDone","com.azure.ai.agents.models.RealtimeResponseAudioTranscriptDeltaEvent":"OpenAI.RealtimeServerEventResponseAudioTranscriptDelta","com.azure.ai.agents.models.RealtimeResponseAudioTranscriptDoneEvent":"OpenAI.RealtimeServerEventResponseAudioTranscriptDone","com.azure.ai.agents.models.RealtimeResponseCancelEvent":"OpenAI.RealtimeClientEventResponseCancel","com.azure.ai.agents.models.RealtimeResponseContentPart":"OpenAI.RealtimeServerEventResponseContentPartDonePart","com.azure.ai.agents.models.RealtimeResponseContentPartAddedEvent":"OpenAI.RealtimeServerEventResponseContentPartAdded","com.azure.ai.agents.models.RealtimeResponseContentPartDoneEvent":"OpenAI.RealtimeServerEventResponseContentPartDone","com.azure.ai.agents.models.RealtimeResponseCreateEvent":"OpenAI.RealtimeClientEventResponseCreate","com.azure.ai.agents.models.RealtimeResponseCreatedEvent":"OpenAI.RealtimeServerEventResponseCreated","com.azure.ai.agents.models.RealtimeResponseDoneEvent":"OpenAI.RealtimeServerEventResponseDone","com.azure.ai.agents.models.RealtimeResponseFunctionCallArgumentsDeltaEvent":"OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDelta","com.azure.ai.agents.models.RealtimeResponseFunctionCallArgumentsDoneEvent":"OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDone","com.azure.ai.agents.models.RealtimeResponseInputAudio":"OpenAI.RealtimeResponseInputAudio","com.azure.ai.agents.models.RealtimeResponseInputFunctionCall":"OpenAI.RealtimeResponseInputFunctionCall","com.azure.ai.agents.models.RealtimeResponseInputFunctionCallOutput":"OpenAI.RealtimeResponseInputFunctionCallOutput","com.azure.ai.agents.models.RealtimeResponseInputImage":"OpenAI.RealtimeResponseInputImage","com.azure.ai.agents.models.RealtimeResponseInputItemStatus":"OpenAI.RealtimeResponseInputMessageSystem.status.anonymous","com.azure.ai.agents.models.RealtimeResponseInputMessage":"OpenAI.RealtimeResponseInputMessage","com.azure.ai.agents.models.RealtimeResponseInputMessageAssistant":"OpenAI.RealtimeResponseInputMessageAssistant","com.azure.ai.agents.models.RealtimeResponseInputMessageAssistantContent":"OpenAI.RealtimeResponseInputMessageAssistantContent","com.azure.ai.agents.models.RealtimeResponseInputMessageDeveloper":"OpenAI.RealtimeResponseInputMessageDeveloper","com.azure.ai.agents.models.RealtimeResponseInputMessageSystem":"OpenAI.RealtimeResponseInputMessageSystem","com.azure.ai.agents.models.RealtimeResponseInputMessageType":"OpenAI.RealtimeResponseInputMessageType","com.azure.ai.agents.models.RealtimeResponseInputMessageUser":"OpenAI.RealtimeResponseInputMessageUser","com.azure.ai.agents.models.RealtimeResponseInputText":"OpenAI.RealtimeResponseInputText","com.azure.ai.agents.models.RealtimeResponseItemReference":"OpenAI.RealtimeResponseItemReference","com.azure.ai.agents.models.RealtimeResponseMcpCallArgumentsDeltaEvent":"OpenAI.RealtimeServerEventResponseMCPCallArgumentsDelta","com.azure.ai.agents.models.RealtimeResponseMcpCallArgumentsDoneEvent":"OpenAI.RealtimeServerEventResponseMCPCallArgumentsDone","com.azure.ai.agents.models.RealtimeResponseMcpCallCompletedEvent":"OpenAI.RealtimeServerEventResponseMCPCallCompleted","com.azure.ai.agents.models.RealtimeResponseMcpCallFailedEvent":"OpenAI.RealtimeServerEventResponseMCPCallFailed","com.azure.ai.agents.models.RealtimeResponseMcpCallInProgressEvent":"OpenAI.RealtimeServerEventResponseMCPCallInProgress","com.azure.ai.agents.models.RealtimeResponseOutputItemAddedEvent":"OpenAI.RealtimeServerEventResponseOutputItemAdded","com.azure.ai.agents.models.RealtimeResponseOutputItemDoneEvent":"OpenAI.RealtimeServerEventResponseOutputItemDone","com.azure.ai.agents.models.RealtimeResponseTextDeltaEvent":"OpenAI.RealtimeServerEventResponseTextDelta","com.azure.ai.agents.models.RealtimeResponseTextDoneEvent":"OpenAI.RealtimeServerEventResponseTextDone","com.azure.ai.agents.models.RealtimeSemanticVadTurnDetection":"OpenAI.RealtimeTurnDetectionSemanticVad","com.azure.ai.agents.models.RealtimeServerEvent":"OpenAI.RealtimeServerEvent","com.azure.ai.agents.models.RealtimeServerEventType":"OpenAI.RealtimeServerEventType","com.azure.ai.agents.models.RealtimeServerVadTurnDetection":"OpenAI.RealtimeTurnDetectionServerVad","com.azure.ai.agents.models.RealtimeSessionAudioConfiguration":"OpenAI.RealtimeSessionCreateRequestGAAudio","com.azure.ai.agents.models.RealtimeSessionAudioInput":"OpenAI.RealtimeSessionCreateRequestGAAudioInput","com.azure.ai.agents.models.RealtimeSessionAudioOutput":"OpenAI.RealtimeSessionCreateRequestGAAudioOutput","com.azure.ai.agents.models.RealtimeSessionConfiguration":"OpenAI.RealtimeSessionCreateRequestGA","com.azure.ai.agents.models.RealtimeSessionConfigurationBase":"OpenAI.RealtimeSessionCreateRequestUnion","com.azure.ai.agents.models.RealtimeSessionCreateRequestGAAudioOutputVoice":"OpenAI.RealtimeSessionCreateRequestGAAudioOutput.voice.anonymous","com.azure.ai.agents.models.RealtimeSessionCreatedEvent":"OpenAI.RealtimeServerEventSessionCreated","com.azure.ai.agents.models.RealtimeSessionTracingConfiguration":"OpenAI.RealtimeSessionCreateRequestGATracing","com.azure.ai.agents.models.RealtimeSessionType":"OpenAI.RealtimeSessionCreateRequestUnionType","com.azure.ai.agents.models.RealtimeSessionUpdateEvent":"OpenAI.RealtimeClientEventSessionUpdate","com.azure.ai.agents.models.RealtimeSessionUpdatedEvent":"OpenAI.RealtimeServerEventSessionUpdated","com.azure.ai.agents.models.RealtimeTranscriptionSessionAudioConfiguration":"OpenAI.RealtimeTranscriptionSessionCreateRequestGAAudio","com.azure.ai.agents.models.RealtimeTranscriptionSessionAudioInput":"OpenAI.RealtimeTranscriptionSessionCreateRequestGAAudioInput","com.azure.ai.agents.models.RealtimeTranscriptionSessionConfiguration":"OpenAI.RealtimeTranscriptionSessionCreateRequestGA","com.azure.ai.agents.models.RealtimeTurnDetection":"OpenAI.RealtimeTurnDetection","com.azure.ai.agents.models.RealtimeTurnDetectionType":"OpenAI.RealtimeTurnDetectionType","com.azure.ai.agents.models.ReminderPreviewToolboxTool":"Azure.AI.Projects.ReminderPreviewToolboxTool","com.azure.ai.agents.models.ResponseFormatJsonSchemaInner":"OpenAI.ResponseFormatJsonSchemaSchema","com.azure.ai.agents.models.ResponseUsageInputTokensDetails":"OpenAI.ResponseUsageInputTokensDetails","com.azure.ai.agents.models.ResponseUsageOutputTokensDetails":"OpenAI.ResponseUsageOutputTokensDetails","com.azure.ai.agents.models.ResponsesProtocolConfiguration":"Azure.AI.Projects.ResponsesProtocolConfiguration","com.azure.ai.agents.models.RoutingConfiguration":"Azure.AI.Projects.RoutingConfiguration","com.azure.ai.agents.models.RoutingTraceEntry":"Azure.AI.Projects.RoutingTraceEntry","com.azure.ai.agents.models.SearchContentType":"OpenAI.SearchContentType","com.azure.ai.agents.models.SearchContextSize":"SearchContextSizeExpandable","com.azure.ai.agents.models.SessionAffinityConfiguration":"Azure.AI.Projects.SessionAffinityConfiguration","com.azure.ai.agents.models.SessionAffinityDecision":"Azure.AI.Projects.SessionAffinityDecision","com.azure.ai.agents.models.SessionAffinityDetails":"Azure.AI.Projects.SessionAffinityDetails","com.azure.ai.agents.models.SessionAffinityMode":"Azure.AI.Projects.SessionAffinityMode","com.azure.ai.agents.models.SessionAffinityRequestMode":"Azure.AI.Projects.SessionAffinityRequestMode","com.azure.ai.agents.models.SessionAffinitySource":"Azure.AI.Projects.SessionAffinitySource","com.azure.ai.agents.models.SessionConfiguration":"Azure.AI.Projects.SessionConfiguration","com.azure.ai.agents.models.SessionDirectoryEntry":"Azure.AI.Projects.SessionDirectoryEntry","com.azure.ai.agents.models.SessionFileWriteResult":"Azure.AI.Projects.SessionFileWriteResponse","com.azure.ai.agents.models.SessionLogEvent":"Azure.AI.Projects.SessionLogEvent","com.azure.ai.agents.models.SessionLogEventType":"Azure.AI.Projects.SessionLogEventType","com.azure.ai.agents.models.SharepointGroundingToolCall":"Azure.AI.Projects.SharepointGroundingToolCall","com.azure.ai.agents.models.SharepointGroundingToolCallOutput":"Azure.AI.Projects.SharepointGroundingToolCallOutput","com.azure.ai.agents.models.SharepointGroundingToolParameters":"Azure.AI.Projects.SharepointGroundingToolParameters","com.azure.ai.agents.models.SharepointPreviewTool":"Azure.AI.Projects.SharepointPreviewTool","com.azure.ai.agents.models.ShellToolboxTool":"Azure.AI.Projects.ShellToolboxTool","com.azure.ai.agents.models.SipTelephonyTransferDestination":"Azure.AI.Projects.SipTelephonyTransferDestination","com.azure.ai.agents.models.SkillReference":"Azure.AI.Projects.SkillReference","com.azure.ai.agents.models.SkillReferenceParameter":"OpenAI.SkillReferenceParam","com.azure.ai.agents.models.SteeringPromptOptimizationContext":"Azure.AI.Projects.SteeringPromptOptimizationContext","com.azure.ai.agents.models.StructuredInputDefinition":"Azure.AI.Projects.StructuredInputDefinition","com.azure.ai.agents.models.StructuredOutputDefinition":"Azure.AI.Projects.StructuredOutputDefinition","com.azure.ai.agents.models.TargetAttribute":"Azure.AI.Projects.TargetAttribute","com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBinding":"Azure.AI.Projects.TeamsPhoneExtensibilityTelephonyBinding","com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBindingListItem":"Azure.AI.Projects.TeamsPhoneExtensibilityTelephonyBindingListItem","com.azure.ai.agents.models.TeamsTelephonyTransferDestination":"Azure.AI.Projects.TeamsTelephonyTransferDestination","com.azure.ai.agents.models.TelemetryConfig":"Azure.AI.Projects.TelemetryConfig","com.azure.ai.agents.models.TelemetryDataKind":"Azure.AI.Projects.TelemetryDataKind","com.azure.ai.agents.models.TelemetryEndpoint":"Azure.AI.Projects.TelemetryEndpoint","com.azure.ai.agents.models.TelemetryEndpointAuth":"Azure.AI.Projects.TelemetryEndpointAuth","com.azure.ai.agents.models.TelemetryEndpointAuthType":"Azure.AI.Projects.TelemetryEndpointAuthType","com.azure.ai.agents.models.TelemetryEndpointKind":"Azure.AI.Projects.TelemetryEndpointKind","com.azure.ai.agents.models.TelemetryTransportProtocol":"Azure.AI.Projects.TelemetryTransportProtocol","com.azure.ai.agents.models.TelephonyBinding":"Azure.AI.Projects.TelephonyBinding","com.azure.ai.agents.models.TelephonyBindingListItem":"Azure.AI.Projects.TelephonyBindingListItem","com.azure.ai.agents.models.TelephonyBindingStatus":"Azure.AI.Projects.TelephonyBindingStatus","com.azure.ai.agents.models.TelephonyCallDurationBasis":"Azure.AI.Projects.TelephonyCallDurationBasis","com.azure.ai.agents.models.TelephonyCallEndReason":"Azure.AI.Projects.TelephonyCallEndReason","com.azure.ai.agents.models.TelephonyCallJob":"Azure.AI.Projects.TelephonyCallJob","com.azure.ai.agents.models.TelephonyCallJobCancellation":"Azure.AI.Projects.TelephonyCallJobCancellation","com.azure.ai.agents.models.TelephonyCallJobSchedule":"Azure.AI.Projects.TelephonyCallJobSchedule","com.azure.ai.agents.models.TelephonyCallJobStatus":"Azure.AI.Projects.TelephonyCallJobStatus","com.azure.ai.agents.models.TelephonyCallJobTerminalReason":"Azure.AI.Projects.TelephonyCallJobTerminalReason","com.azure.ai.agents.models.TelephonyCallLifecycleEvent":"Azure.AI.Projects.TelephonyCallLifecycleEvent","com.azure.ai.agents.models.TelephonyCallLifecycleEventName":"Azure.AI.Projects.TelephonyCallLifecycleEventName","com.azure.ai.agents.models.TelephonyCallLifecycleEventOutcome":"Azure.AI.Projects.TelephonyCallLifecycleEventOutcome","com.azure.ai.agents.models.TelephonyCallLifecycleEventReason":"Azure.AI.Projects.TelephonyCallLifecycleEventReason","com.azure.ai.agents.models.TelephonyCallLifecycleEventSource":"Azure.AI.Projects.TelephonyCallLifecycleEventSource","com.azure.ai.agents.models.TelephonyCallPhase":"Azure.AI.Projects.TelephonyCallPhase","com.azure.ai.agents.models.TelephonyCallRecord":"Azure.AI.Projects.TelephonyCallRecord","com.azure.ai.agents.models.TelephonyCallStatus":"Azure.AI.Projects.TelephonyCallStatus","com.azure.ai.agents.models.TelephonyCallSummary":"Azure.AI.Projects.TelephonyCallSummary","com.azure.ai.agents.models.TelephonyCallTimestampSource":"Azure.AI.Projects.TelephonyCallTimestampSource","com.azure.ai.agents.models.TelephonyCallTiming":"Azure.AI.Projects.TelephonyCallTiming","com.azure.ai.agents.models.TelephonyCallTrace":"Azure.AI.Projects.TelephonyCallTrace","com.azure.ai.agents.models.TelephonyCallTraceMode":"Azure.AI.Projects.TelephonyCallTraceMode","com.azure.ai.agents.models.TelephonyCallTraceStatus":"Azure.AI.Projects.TelephonyCallTraceStatus","com.azure.ai.agents.models.TelephonyOutboundDestination":"Azure.AI.Projects.TelephonyOutboundDestination","com.azure.ai.agents.models.TelephonyOutboundDestinationType":"Azure.AI.Projects.TelephonyOutboundDestinationType","com.azure.ai.agents.models.TelephonyOutboundFixedIntervalRetryPolicy":"Azure.AI.Projects.TelephonyOutboundFixedIntervalRetryPolicy","com.azure.ai.agents.models.TelephonyOutboundRetryPolicy":"Azure.AI.Projects.TelephonyOutboundRetryPolicy","com.azure.ai.agents.models.TelephonyOutboundRetryPolicyType":"Azure.AI.Projects.TelephonyOutboundRetryPolicyType","com.azure.ai.agents.models.TelephonyProvider":"Azure.AI.Projects.TelephonyProvider","com.azure.ai.agents.models.TelephonyTransferDestination":"Azure.AI.Projects.TelephonyTransferDestination","com.azure.ai.agents.models.TelephonyTransferDestinationKind":"Azure.AI.Projects.TelephonyTransferDestinationKind","com.azure.ai.agents.models.TelephonyTransferTarget":"Azure.AI.Projects.TelephonyTransferTarget","com.azure.ai.agents.models.TelephonyTransferTargets":"Azure.AI.Projects.TelephonyTransferTargets","com.azure.ai.agents.models.TextResponseFormatConfiguration":"OpenAI.TextResponseFormatConfiguration","com.azure.ai.agents.models.TextResponseFormatConfigurationResponseFormatJsonObject":"OpenAI.TextResponseFormatConfigurationResponseFormatJsonObject","com.azure.ai.agents.models.TextResponseFormatConfigurationResponseFormatText":"OpenAI.TextResponseFormatConfigurationResponseFormatText","com.azure.ai.agents.models.TextResponseFormatConfigurationType":"OpenAI.TextResponseFormatConfigurationType","com.azure.ai.agents.models.TextResponseFormatJsonSchema":"OpenAI.TextResponseFormatJsonSchema","com.azure.ai.agents.models.Tool":"OpenAI.Tool","com.azure.ai.agents.models.ToolCallStatus":"Azure.AI.Projects.ToolCallStatus","com.azure.ai.agents.models.ToolConfig":"Azure.AI.Projects.ToolConfig","com.azure.ai.agents.models.ToolFunctionToolType1":null,"com.azure.ai.agents.models.ToolProjectConnection":"Azure.AI.Projects.ToolProjectConnection","com.azure.ai.agents.models.ToolSearchExecutionType":"OpenAI.ToolSearchExecutionType","com.azure.ai.agents.models.ToolSearchTool":"OpenAI.ToolToolSearchToolParam","com.azure.ai.agents.models.ToolSearchToolboxTool":"Azure.AI.Projects.ToolSearchToolboxTool","com.azure.ai.agents.models.ToolType":"OpenAI.ToolType","com.azure.ai.agents.models.ToolboxDetails":"Azure.AI.Projects.ToolboxObject","com.azure.ai.agents.models.ToolboxPolicies":"Azure.AI.Projects.ToolboxPolicies","com.azure.ai.agents.models.ToolboxSearchPreviewToolboxTool":"Azure.AI.Projects.ToolboxSearchPreviewToolboxTool","com.azure.ai.agents.models.ToolboxShellContainerAutoEnvironment":"Azure.AI.Projects.ToolboxShellContainerAutoEnvironment","com.azure.ai.agents.models.ToolboxShellContainerReferenceEnvironment":"Azure.AI.Projects.ToolboxShellContainerReferenceEnvironment","com.azure.ai.agents.models.ToolboxShellEnvironment":"Azure.AI.Projects.ToolboxShellEnvironment","com.azure.ai.agents.models.ToolboxShellNetworkPolicy":"Azure.AI.Projects.ToolboxShellNetworkPolicy","com.azure.ai.agents.models.ToolboxShellNetworkPolicyDisabled":"Azure.AI.Projects.ToolboxShellNetworkPolicyDisabled","com.azure.ai.agents.models.ToolboxSkill":"Azure.AI.Projects.ToolboxSkill","com.azure.ai.agents.models.ToolboxSkillReference":"Azure.AI.Projects.ToolboxSkillReference","com.azure.ai.agents.models.ToolboxTool":"Azure.AI.Projects.ToolboxTool","com.azure.ai.agents.models.ToolboxToolType":"Azure.AI.Projects.ToolboxToolType","com.azure.ai.agents.models.ToolboxVersionDetails":"Azure.AI.Projects.ToolboxVersionObject","com.azure.ai.agents.models.ToolboxVersions":"Azure.AI.Projects.ToolboxVersions","com.azure.ai.agents.models.TranscriptTextInputTokenDetails":"OpenAI.TranscriptTextUsageTokensInputTokenDetails","com.azure.ai.agents.models.TranscriptTextUsage":"OpenAI.CreateTranscriptionResponseJsonUsage","com.azure.ai.agents.models.TranscriptTextUsageDuration":"OpenAI.TranscriptTextUsageDuration","com.azure.ai.agents.models.TranscriptTextUsageTokens":"OpenAI.TranscriptTextUsageTokens","com.azure.ai.agents.models.TranscriptTextUsageType":"OpenAI.CreateTranscriptionResponseJsonUsageType","com.azure.ai.agents.models.TranscriptionLanguage":"OpenAI.TranscriptionLanguage","com.azure.ai.agents.models.TwilioTelephonyBinding":"Azure.AI.Projects.TwilioTelephonyBinding","com.azure.ai.agents.models.TwilioTelephonyBindingListItem":"Azure.AI.Projects.TwilioTelephonyBindingListItem","com.azure.ai.agents.models.UpdateAgentDetailsOptions":"Azure.AI.Projects.patchAgentObject.Request.anonymous","com.azure.ai.agents.models.UpdateTelephonyBindingInput":"Azure.AI.Projects.UpdateTelephonyBindingRequest","com.azure.ai.agents.models.UserConversationSimulationAudioEffect":"Azure.AI.Projects.UserConversationSimulationAudioEffect","com.azure.ai.agents.models.UserConversationSimulationAudioEffectsConfiguration":"Azure.AI.Projects.UserConversationSimulationAudioEffectsConfiguration","com.azure.ai.agents.models.UserConversationSimulationConfiguration":"Azure.AI.Projects.UserConversationSimulationConfiguration","com.azure.ai.agents.models.UserConversationSimulationDefaultInterruptionConfiguration":"Azure.AI.Projects.UserConversationSimulationDefaultInterruptionConfiguration","com.azure.ai.agents.models.UserConversationSimulationInterruptionConfiguration":"Azure.AI.Projects.UserConversationSimulationInterruptionConfiguration","com.azure.ai.agents.models.UserConversationSimulationTestCase":"Azure.AI.Projects.UserConversationSimulationTestCase","com.azure.ai.agents.models.UserConversationSimulationUserBehaviorConfiguration":"Azure.AI.Projects.UserConversationSimulationUserBehaviorConfiguration","com.azure.ai.agents.models.UserProfileMemoryItem":"Azure.AI.Projects.UserProfileMemoryItem","com.azure.ai.agents.models.VersionIndicator":"Azure.AI.Projects.VersionIndicator","com.azure.ai.agents.models.VersionIndicatorType":"Azure.AI.Projects.VersionIndicatorType","com.azure.ai.agents.models.VersionRefIndicator":"Azure.AI.Projects.VersionRefIndicator","com.azure.ai.agents.models.VersionSelectionRule":"Azure.AI.Projects.VersionSelectionRule","com.azure.ai.agents.models.VersionSelector":"Azure.AI.Projects.VersionSelector","com.azure.ai.agents.models.VersionSelectorType":"Azure.AI.Projects.VersionSelectorType","com.azure.ai.agents.models.VoiceAgentAnimationConfiguration":"Azure.AI.Projects.VoiceAgentAnimationConfig","com.azure.ai.agents.models.VoiceAgentAnimationOutputType":"Azure.AI.Projects.VoiceAgentAnimationOutputType","com.azure.ai.agents.models.VoiceAgentAudioConfiguration":"Azure.AI.Projects.VoiceAgentAudioConfig","com.azure.ai.agents.models.VoiceAgentAudioInputConfiguration":"Azure.AI.Projects.VoiceAgentAudioInputConfig","com.azure.ai.agents.models.VoiceAgentAudioOutputConfiguration":"Azure.AI.Projects.VoiceAgentAudioOutputConfig","com.azure.ai.agents.models.VoiceAgentAudioTimestampType":"Azure.AI.Projects.VoiceAgentAudioTimestampType","com.azure.ai.agents.models.VoiceAgentAvatarConfiguration":"Azure.AI.Projects.VoiceAgentAvatarConfig","com.azure.ai.agents.models.VoiceAgentAvatarIceServer":"Azure.AI.Projects.VoiceAgentAvatarIceServer","com.azure.ai.agents.models.VoiceAgentAvatarOutputProtocol":"Azure.AI.Projects.VoiceAgentAvatarOutputProtocol","com.azure.ai.agents.models.VoiceAgentAvatarScene":"Azure.AI.Projects.VoiceAgentAvatarScene","com.azure.ai.agents.models.VoiceAgentAvatarType":"Azure.AI.Projects.VoiceAgentAvatarType","com.azure.ai.agents.models.VoiceAgentAvatarVideoBackground":"Azure.AI.Projects.VoiceAgentAvatarVideoBackground","com.azure.ai.agents.models.VoiceAgentAvatarVideoCrop":"Azure.AI.Projects.VoiceAgentAvatarVideoCrop","com.azure.ai.agents.models.VoiceAgentAvatarVideoParameters":"Azure.AI.Projects.VoiceAgentAvatarVideoParams","com.azure.ai.agents.models.VoiceAgentAvatarVideoResolution":"Azure.AI.Projects.VoiceAgentAvatarVideoResolution","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadEnglishTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadEnTurnDetection","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadMultilingualTurnDetection","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadTurnDetection","com.azure.ai.agents.models.VoiceAgentDefinition":"Azure.AI.Projects.VoiceAgentDefinition","com.azure.ai.agents.models.VoiceAgentEchoCancellation":"Azure.AI.Projects.VoiceAgentEchoCancellation","com.azure.ai.agents.models.VoiceAgentEchoCancellationReferenceSource":"Azure.AI.Projects.VoiceAgentEchoCancellationReferenceSource","com.azure.ai.agents.models.VoiceAgentEndConversationSystemTool":"Azure.AI.Projects.VoiceAgentEndConversationSystemTool","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetection":"Azure.AI.Projects.VoiceAgentEndOfUtteranceDetection","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetectionModel":"Azure.AI.Projects.VoiceAgentEndOfUtteranceDetectionModel","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceThresholdLevel":"Azure.AI.Projects.VoiceAgentEndOfUtteranceThresholdLevel","com.azure.ai.agents.models.VoiceAgentFunctionTool":"Azure.AI.Projects.VoiceAgentFunctionTool","com.azure.ai.agents.models.VoiceAgentGreetingConfiguration":"Azure.AI.Projects.VoiceAgentGreetingConfig","com.azure.ai.agents.models.VoiceAgentInputTranscription":"Azure.AI.Projects.VoiceAgentInputTranscription","com.azure.ai.agents.models.VoiceAgentInputTranscriptionModel":"Azure.AI.Projects.VoiceAgentInputTranscriptionModel","com.azure.ai.agents.models.VoiceAgentInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentInterimResponseTrigger":"Azure.AI.Projects.VoiceAgentInterimResponseTrigger","com.azure.ai.agents.models.VoiceAgentLlmGeneratedGreetingConfiguration":"Azure.AI.Projects.VoiceAgentLlmGeneratedGreetingConfig","com.azure.ai.agents.models.VoiceAgentLlmInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentLlmInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentMcpTool":"Azure.AI.Projects.VoiceAgentMcpTool","com.azure.ai.agents.models.VoiceAgentNoiseReduction":"Azure.AI.Projects.VoiceAgentNoiseReduction","com.azure.ai.agents.models.VoiceAgentNoiseReductionType":"Azure.AI.Projects.VoiceAgentNoiseReductionType","com.azure.ai.agents.models.VoiceAgentProfanityFilterMode":"Azure.AI.Projects.VoiceAgentProfanityFilterMode","com.azure.ai.agents.models.VoiceAgentRealtimeResponse":"Azure.AI.Projects.VoiceAgentRealtimeResponse","com.azure.ai.agents.models.VoiceAgentResponseAnimationBlendshapeDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDelta","com.azure.ai.agents.models.VoiceAgentResponseAnimationBlendshapeDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDone","com.azure.ai.agents.models.VoiceAgentResponseAnimationVisemeDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDelta","com.azure.ai.agents.models.VoiceAgentResponseAnimationVisemeDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDone","com.azure.ai.agents.models.VoiceAgentResponseAudioConfig":"TypeSpec.PickProperties","com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDelta","com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDone","com.azure.ai.agents.models.VoiceAgentResponseCreateOptions":"Azure.AI.Projects.VoiceAgentResponseCreateParams","com.azure.ai.agents.models.VoiceAgentResponseVideoDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseVideoDelta","com.azure.ai.agents.models.VoiceAgentRtcCallErrorDetails":"Azure.AI.Projects.VoiceAgentRtcCallErrorDetails","com.azure.ai.agents.models.VoiceAgentRtcCallErrorEvent":"Azure.AI.Projects.VoiceAgentServerEventRtcCallError","com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreateEvent":"Azure.AI.Projects.VoiceAgentClientEventRtcCallSdpCreate","com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreatedEvent":"Azure.AI.Projects.VoiceAgentServerEventRtcCallSdpCreated","com.azure.ai.agents.models.VoiceAgentSemanticVadTurnDetection":"Azure.AI.Projects.VoiceAgentSemanticVadTurnDetection","com.azure.ai.agents.models.VoiceAgentServerVadTurnDetection":"Azure.AI.Projects.VoiceAgentServerVadTurnDetection","com.azure.ai.agents.models.VoiceAgentSessionAvatarConfiguration":"Azure.AI.Projects.VoiceAgentSessionAvatarConfig","com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectEvent":"Azure.AI.Projects.VoiceAgentClientEventSessionAvatarConnect","com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectingEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarConnecting","com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToIdleEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToIdle","com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToSpeakingEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToSpeaking","com.azure.ai.agents.models.VoiceAgentSessionIncludeOption":"Azure.AI.Projects.VoiceAgentSessionIncludeOption","com.azure.ai.agents.models.VoiceAgentSessionResponseConfiguration":"Azure.AI.Projects.VoiceAgentSessionResponseConfig","com.azure.ai.agents.models.VoiceAgentSessionSubagentAbortedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentAborted","com.azure.ai.agents.models.VoiceAgentSessionSubagentCompletedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentCompleted","com.azure.ai.agents.models.VoiceAgentSessionSubagentStartedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentStarted","com.azure.ai.agents.models.VoiceAgentSessionUpdateConfiguration":"Azure.AI.Projects.VoiceAgentSessionUpdateConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeSound":"Azure.AI.Projects.VoiceAgentSoundscapeSound","com.azure.ai.agents.models.VoiceAgentSoundscapeSourceConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeSourceConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeTrackConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeTrackConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeWorkingTrackConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeWorkingTrackConfig","com.azure.ai.agents.models.VoiceAgentStaticInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentStaticInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentSubagent":"Azure.AI.Projects.VoiceAgentSubagent","com.azure.ai.agents.models.VoiceAgentSubagentAbortReason":"Azure.AI.Projects.VoiceAgentSubagentAbortReason","com.azure.ai.agents.models.VoiceAgentSubagentConfiguration":"Azure.AI.Projects.VoiceAgentSubagentConfig","com.azure.ai.agents.models.VoiceAgentSubagentResponsePolicy":"Azure.AI.Projects.VoiceAgentSubagentResponsePolicy","com.azure.ai.agents.models.VoiceAgentSystemTool":"Azure.AI.Projects.VoiceAgentSystemTool","com.azure.ai.agents.models.VoiceAgentSystemToolName":"Azure.AI.Projects.VoiceAgentSystemToolName","com.azure.ai.agents.models.VoiceAgentTemplateGreetingConfiguration":"Azure.AI.Projects.VoiceAgentTemplateGreetingConfig","com.azure.ai.agents.models.VoiceAgentTool":"Azure.AI.Projects.VoiceAgentTool","com.azure.ai.agents.models.VoiceAgentToolResponseScheduling":"Azure.AI.Projects.VoiceAgentToolResponseScheduling","com.azure.ai.agents.models.VoiceAgentToolboxTool":"Azure.AI.Projects.VoiceAgentToolboxTool","com.azure.ai.agents.models.VoiceAgentTranscriptionPhrase":"Azure.AI.Projects.VoiceAgentTranscriptionPhrase","com.azure.ai.agents.models.VoiceAgentTranscriptionWord":"Azure.AI.Projects.VoiceAgentTranscriptionWord","com.azure.ai.agents.models.VoiceAgentTransport":"Azure.AI.Projects.VoiceAgentTransport","com.azure.ai.agents.models.VoiceAgentTurnDetectionConfiguration":"Azure.AI.Projects.VoiceAgentTurnDetectionConfig","com.azure.ai.agents.models.VoiceAgentTurnDetectionType":"Azure.AI.Projects.VoiceAgentTurnDetectionType","com.azure.ai.agents.models.VoiceAgentWarningDetails":"Azure.AI.Projects.VoiceAgentServerEventWarningDetails","com.azure.ai.agents.models.VoiceAgentWarningEvent":"Azure.AI.Projects.VoiceAgentServerEventWarning","com.azure.ai.agents.models.VoiceAudioCodec":"Azure.AI.Projects.VoiceAudioCodec","com.azure.ai.agents.models.VoiceAudioContainerFormat":"Azure.AI.Projects.VoiceAudioContainerFormat","com.azure.ai.agents.models.VoiceAudioItem":"Azure.AI.Projects.VoiceAudioItem","com.azure.ai.agents.models.VoiceAudioRole":"Azure.AI.Projects.VoiceAudioRole","com.azure.ai.agents.models.VoiceConversation":"Azure.AI.Projects.VoiceConversation","com.azure.ai.agents.models.VoiceConversationEngine":"Azure.AI.Projects.VoiceConversationEngine","com.azure.ai.agents.models.VoiceConversationStatus":"Azure.AI.Projects.VoiceConversationStatus","com.azure.ai.agents.models.VoiceGeneratedAudioItem":"Azure.AI.Projects.VoiceGeneratedAudioItem","com.azure.ai.agents.models.VoiceHostedAgentConversationEngine":"Azure.AI.Projects.VoiceHostedAgentConversationEngine","com.azure.ai.agents.models.VoiceIds":"OpenAI.VoiceIdsShared","com.azure.ai.agents.models.VoiceModelType":"Azure.AI.Projects.VoiceModelType","com.azure.ai.agents.models.VoiceOutputModality":"Azure.AI.Projects.VoiceOutputModality","com.azure.ai.agents.models.VoiceRecording":"Azure.AI.Projects.VoiceRecording","com.azure.ai.agents.models.VoiceRecordingChannelLayout":"Azure.AI.Projects.VoiceRecordingChannelLayout","com.azure.ai.agents.models.VoiceResponse":"Azure.AI.Projects.VoiceResponse","com.azure.ai.agents.models.VoiceResponseAudio":"Azure.AI.Projects.VoiceResponseAudio","com.azure.ai.agents.models.VoiceResponseAudioOutput":"Azure.AI.Projects.VoiceResponseAudioOutput","com.azure.ai.agents.models.VoiceResponseObjectType":null,"com.azure.ai.agents.models.VoiceType":"Azure.AI.Projects.VoiceType","com.azure.ai.agents.models.WebIqPreviewTool":"Azure.AI.Projects.WebIQPreviewTool","com.azure.ai.agents.models.WebIqPreviewToolboxTool":"Azure.AI.Projects.WebIQPreviewToolboxTool","com.azure.ai.agents.models.WebSearchApproximateLocation":"OpenAI.WebSearchApproximateLocation","com.azure.ai.agents.models.WebSearchConfiguration":"Azure.AI.Projects.WebSearchConfiguration","com.azure.ai.agents.models.WebSearchPreviewTool":"OpenAI.ToolWebSearchPreviewTool","com.azure.ai.agents.models.WebSearchTool":"OpenAI.ToolWebSearchTool","com.azure.ai.agents.models.WebSearchToolFilters":"OpenAI.WebSearchToolFilters","com.azure.ai.agents.models.WebSearchToolSearchContextSize":"WebSearchToolSearchContextSizeExpandable","com.azure.ai.agents.models.WebSearchToolboxTool":"Azure.AI.Projects.WebSearchToolboxTool","com.azure.ai.agents.models.WorkIqPreviewTool":"Azure.AI.Projects.WorkIQPreviewTool","com.azure.ai.agents.models.WorkIqPreviewToolboxTool":"Azure.AI.Projects.WorkIQPreviewToolboxTool","com.azure.ai.agents.models.WorkflowAgentDefinition":"Azure.AI.Projects.WorkflowAgentDefinition"},"generatedFiles":["src/main/java/com/azure/ai/agents/AgentsAsyncClient.java","src/main/java/com/azure/ai/agents/AgentsClient.java","src/main/java/com/azure/ai/agents/AgentsClientBuilder.java","src/main/java/com/azure/ai/agents/AgentsServiceVersion.java","src/main/java/com/azure/ai/agents/BetaAgentsAsyncClient.java","src/main/java/com/azure/ai/agents/BetaAgentsClient.java","src/main/java/com/azure/ai/agents/BetaMemoryStoresAsyncClient.java","src/main/java/com/azure/ai/agents/BetaMemoryStoresClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java","src/main/java/com/azure/ai/agents/ToolboxesAsyncClient.java","src/main/java/com/azure/ai/agents/ToolboxesClient.java","src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java","src/main/java/com/azure/ai/agents/implementation/AgentsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaAgentsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaMemoryStoresImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java","src/main/java/com/azure/ai/agents/implementation/JsonMergePatchHelper.java","src/main/java/com/azure/ai/agents/implementation/MultipartFormDataHelper.java","src/main/java/com/azure/ai/agents/implementation/OperationLocationPollingStrategy.java","src/main/java/com/azure/ai/agents/implementation/PollingUtils.java","src/main/java/com/azure/ai/agents/implementation/SyncOperationLocationPollingStrategy.java","src/main/java/com/azure/ai/agents/implementation/ToolboxesImpl.java","src/main/java/com/azure/ai/agents/implementation/models/AgentDefinitionOptInKeys.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentFromCodeContent.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentOptions.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentVersionFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentVersionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateMemoryRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateMemoryStoreRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateSessionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateToolboxVersionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/FoundryFeaturesOptInKeys.java","src/main/java/com/azure/ai/agents/implementation/models/GetMicrosoft365AppPackageRequest.java","src/main/java/com/azure/ai/agents/implementation/models/ListMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/PublishAgentToMicrosoft365Request.java","src/main/java/com/azure/ai/agents/implementation/models/ReplaceTelephonyTransferTargetsRequest.java","src/main/java/com/azure/ai/agents/implementation/models/SearchMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/TransferTelephonyCallRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateAgentFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateAgentRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoryRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoryStoreRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateToolboxInput.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateToolboxRequest.java","src/main/java/com/azure/ai/agents/implementation/models/package-info.java","src/main/java/com/azure/ai/agents/implementation/package-info.java","src/main/java/com/azure/ai/agents/models/A2APreviewTool.java","src/main/java/com/azure/ai/agents/models/A2APreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/A2AProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/A2AProtocolVersion.java","src/main/java/com/azure/ai/agents/models/A2ATool.java","src/main/java/com/azure/ai/agents/models/A2AToolCall.java","src/main/java/com/azure/ai/agents/models/A2AToolCallOutput.java","src/main/java/com/azure/ai/agents/models/A2AToolboxTool.java","src/main/java/com/azure/ai/agents/models/AISearchIndexResource.java","src/main/java/com/azure/ai/agents/models/ActivityProtocolAccessBoundary.java","src/main/java/com/azure/ai/agents/models/ActivityProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentBlueprintReference.java","src/main/java/com/azure/ai/agents/models/AgentBlueprintReferenceType.java","src/main/java/com/azure/ai/agents/models/AgentCard.java","src/main/java/com/azure/ai/agents/models/AgentCardSkill.java","src/main/java/com/azure/ai/agents/models/AgentDefinition.java","src/main/java/com/azure/ai/agents/models/AgentDetails.java","src/main/java/com/azure/ai/agents/models/AgentDetailsVersions.java","src/main/java/com/azure/ai/agents/models/AgentEndpointAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/AgentEndpointAuthorizationSchemeType.java","src/main/java/com/azure/ai/agents/models/AgentEndpointConfig.java","src/main/java/com/azure/ai/agents/models/AgentEndpointProtocol.java","src/main/java/com/azure/ai/agents/models/AgentHarness.java","src/main/java/com/azure/ai/agents/models/AgentIdentity.java","src/main/java/com/azure/ai/agents/models/AgentIdentityStatus.java","src/main/java/com/azure/ai/agents/models/AgentKind.java","src/main/java/com/azure/ai/agents/models/AgentObjectType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationAgentCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationBaselineAgentConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateEvaluation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateExpand.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidatePromotionInfo.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateStatus.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfigurationBase.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfigurationType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCostEstimate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationDataSourceType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateBand.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateInputs.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateResult.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationSetType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluatorReference.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationFoundryAgentTargetConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationGoal.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationInstructionsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJob.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobLatency.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobResult.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobTokenUsage.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationModelConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationModelMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationPromptCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationResultCandidateSummary.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSkill.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSkillsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSpace.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationStage.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationStageEstimate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionDatasetReferenceDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionInlineDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionTestCase.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetConfigurationType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTerminationReason.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationToolsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationDatasetReferenceDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationInlineDataSource.java","src/main/java/com/azure/ai/agents/models/AgentReference.java","src/main/java/com/azure/ai/agents/models/AgentSessionResource.java","src/main/java/com/azure/ai/agents/models/AgentSessionStatus.java","src/main/java/com/azure/ai/agents/models/AgentState.java","src/main/java/com/azure/ai/agents/models/AgentStateSource.java","src/main/java/com/azure/ai/agents/models/AgentVersionDetails.java","src/main/java/com/azure/ai/agents/models/AgentVersionStatus.java","src/main/java/com/azure/ai/agents/models/ApiError.java","src/main/java/com/azure/ai/agents/models/ApplyPatchToolParameter.java","src/main/java/com/azure/ai/agents/models/ApproximateLocation.java","src/main/java/com/azure/ai/agents/models/AudioTranscription.java","src/main/java/com/azure/ai/agents/models/AudioTranscriptionModel.java","src/main/java/com/azure/ai/agents/models/AutoCodeInterpreterToolParameter.java","src/main/java/com/azure/ai/agents/models/AzureAISearchQueryType.java","src/main/java/com/azure/ai/agents/models/AzureAISearchTool.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolCall.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolCallOutput.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolResource.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/AzureCreateResponseDetails.java","src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java","src/main/java/com/azure/ai/agents/models/AzureFunctionBinding.java","src/main/java/com/azure/ai/agents/models/AzureFunctionDefinition.java","src/main/java/com/azure/ai/agents/models/AzureFunctionDefinitionDetails.java","src/main/java/com/azure/ai/agents/models/AzureFunctionStorageQueue.java","src/main/java/com/azure/ai/agents/models/AzureFunctionTool.java","src/main/java/com/azure/ai/agents/models/AzureFunctionToolCall.java","src/main/java/com/azure/ai/agents/models/AzureFunctionToolCallOutput.java","src/main/java/com/azure/ai/agents/models/AzureUserSecurityContext.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolCall.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolParameters.java","src/main/java/com/azure/ai/agents/models/BingGroundingSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/BingGroundingSearchToolParameters.java","src/main/java/com/azure/ai/agents/models/BingGroundingTool.java","src/main/java/com/azure/ai/agents/models/BingGroundingToolCall.java","src/main/java/com/azure/ai/agents/models/BingGroundingToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BotServiceAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BotServiceRbacAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BotServiceTenantAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationPreviewTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolCall.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolConnectionParameters.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolParameters.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolboxTool.java","src/main/java/com/azure/ai/agents/models/CallableToolAllowedCaller.java","src/main/java/com/azure/ai/agents/models/CaptureStructuredOutputsTool.java","src/main/java/com/azure/ai/agents/models/ChatSummaryMemoryItem.java","src/main/java/com/azure/ai/agents/models/CodeConfiguration.java","src/main/java/com/azure/ai/agents/models/CodeDependencyResolution.java","src/main/java/com/azure/ai/agents/models/CodeFileDetails.java","src/main/java/com/azure/ai/agents/models/CodeInterpreterTool.java","src/main/java/com/azure/ai/agents/models/CodeInterpreterToolboxTool.java","src/main/java/com/azure/ai/agents/models/ComputerEnvironment.java","src/main/java/com/azure/ai/agents/models/ComputerTool.java","src/main/java/com/azure/ai/agents/models/ComputerUsePreviewTool.java","src/main/java/com/azure/ai/agents/models/ContainerAutoParameter.java","src/main/java/com/azure/ai/agents/models/ContainerConfiguration.java","src/main/java/com/azure/ai/agents/models/ContainerMemoryLimit.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyAllowlistParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyDisabledParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyDomainSecretParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyParamType.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyParameter.java","src/main/java/com/azure/ai/agents/models/ContainerSkill.java","src/main/java/com/azure/ai/agents/models/ContainerSkillType.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionFromCodeContent.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionFromCodeMetadata.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionInput.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionOptions.java","src/main/java/com/azure/ai/agents/models/CreateTeamsPhoneExtensibilityTelephonyBindingInput.java","src/main/java/com/azure/ai/agents/models/CreateTelephonyBindingInput.java","src/main/java/com/azure/ai/agents/models/CreateTelephonyCallJobInput.java","src/main/java/com/azure/ai/agents/models/CreateTwilioTelephonyBindingInput.java","src/main/java/com/azure/ai/agents/models/CustomGrammarFormatParameter.java","src/main/java/com/azure/ai/agents/models/CustomTextFormatParameter.java","src/main/java/com/azure/ai/agents/models/CustomToolParamFormat.java","src/main/java/com/azure/ai/agents/models/CustomToolParamFormatType.java","src/main/java/com/azure/ai/agents/models/CustomToolParameter.java","src/main/java/com/azure/ai/agents/models/DigitalWorkerType.java","src/main/java/com/azure/ai/agents/models/EntraAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/EvaluationAzureStandardVoiceModelConfiguration.java","src/main/java/com/azure/ai/agents/models/EvaluationModelConfiguration.java","src/main/java/com/azure/ai/agents/models/EvaluationVoiceModelConfiguration.java","src/main/java/com/azure/ai/agents/models/ExternalAgentDefinition.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolCall.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolCallOutput.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolParameters.java","src/main/java/com/azure/ai/agents/models/FabricIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/FabricIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/FileSearchTool.java","src/main/java/com/azure/ai/agents/models/FileSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/FixedRatioVersionSelectionRule.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParamEnvironment.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParamEnvironmentType.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameter.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameterEnvironmentContainerReferenceParameter.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameterEnvironmentLocalEnvironmentParameter.java","src/main/java/com/azure/ai/agents/models/FunctionTool.java","src/main/java/com/azure/ai/agents/models/GetMicrosoft365AppPackageOptions.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotBuiltInTool.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotHarness.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetConfig.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetDefaultConfig.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetPreview.java","src/main/java/com/azure/ai/agents/models/GrammarSyntax.java","src/main/java/com/azure/ai/agents/models/HeaderTelemetryEndpointAuth.java","src/main/java/com/azure/ai/agents/models/HostedAgentDefinition.java","src/main/java/com/azure/ai/agents/models/HybridSearchOptions.java","src/main/java/com/azure/ai/agents/models/ImageGenActionEnum.java","src/main/java/com/azure/ai/agents/models/ImageGenTool.java","src/main/java/com/azure/ai/agents/models/ImageGenToolBackground.java","src/main/java/com/azure/ai/agents/models/ImageGenToolInputImageMask.java","src/main/java/com/azure/ai/agents/models/ImageGenToolModel.java","src/main/java/com/azure/ai/agents/models/ImageGenToolModeration.java","src/main/java/com/azure/ai/agents/models/ImageGenToolOutputFormat.java","src/main/java/com/azure/ai/agents/models/ImageGenToolQuality.java","src/main/java/com/azure/ai/agents/models/ImageGenToolSize.java","src/main/java/com/azure/ai/agents/models/IncludeEnum.java","src/main/java/com/azure/ai/agents/models/InlineSkillParameter.java","src/main/java/com/azure/ai/agents/models/InlineSkillSourceParameter.java","src/main/java/com/azure/ai/agents/models/InputFidelity.java","src/main/java/com/azure/ai/agents/models/InvocationsProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/InvocationsWsProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/JobStatus.java","src/main/java/com/azure/ai/agents/models/ListMemoriesOptions.java","src/main/java/com/azure/ai/agents/models/LocalShellToolParameter.java","src/main/java/com/azure/ai/agents/models/LocalSkillParameter.java","src/main/java/com/azure/ai/agents/models/ManagedAgentIdentityBlueprintReference.java","src/main/java/com/azure/ai/agents/models/McpListToolsTool.java","src/main/java/com/azure/ai/agents/models/McpListToolsToolAnnotations.java","src/main/java/com/azure/ai/agents/models/McpListToolsToolInputSchema.java","src/main/java/com/azure/ai/agents/models/McpProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/McpTool.java","src/main/java/com/azure/ai/agents/models/McpToolConnectorId.java","src/main/java/com/azure/ai/agents/models/McpToolFilter.java","src/main/java/com/azure/ai/agents/models/McpToolRequireApproval.java","src/main/java/com/azure/ai/agents/models/McpToolboxTool.java","src/main/java/com/azure/ai/agents/models/MemoryCommandToolCall.java","src/main/java/com/azure/ai/agents/models/MemoryCommandToolCallOutput.java","src/main/java/com/azure/ai/agents/models/MemoryItem.java","src/main/java/com/azure/ai/agents/models/MemoryItemKind.java","src/main/java/com/azure/ai/agents/models/MemoryOperation.java","src/main/java/com/azure/ai/agents/models/MemoryOperationKind.java","src/main/java/com/azure/ai/agents/models/MemorySearchItem.java","src/main/java/com/azure/ai/agents/models/MemorySearchOptions.java","src/main/java/com/azure/ai/agents/models/MemorySearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/MemorySearchToolCall.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefaultDefinition.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefaultOptions.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefinition.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDetails.java","src/main/java/com/azure/ai/agents/models/MemoryStoreKind.java","src/main/java/com/azure/ai/agents/models/MemoryStoreObjectType.java","src/main/java/com/azure/ai/agents/models/MemoryStoreOperationUsage.java","src/main/java/com/azure/ai/agents/models/MemoryStoreSearchResponse.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateCompletedResult.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateResponse.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateStatus.java","src/main/java/com/azure/ai/agents/models/Microsoft365PermissionScopes.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishDefaults.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishResult.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishScope.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotBuiltInTool.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotHarness.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetConfiguration.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetDefaultConfiguration.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetPreview.java","src/main/java/com/azure/ai/agents/models/MicrosoftFabricPreviewTool.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttempt.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttemptError.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttemptResult.java","src/main/java/com/azure/ai/agents/models/ModelRouterDetails.java","src/main/java/com/azure/ai/agents/models/ModelRouterMode.java","src/main/java/com/azure/ai/agents/models/ModelSamplingParameters.java","src/main/java/com/azure/ai/agents/models/ModelSelectionDetails.java","src/main/java/com/azure/ai/agents/models/NamespaceTool.java","src/main/java/com/azure/ai/agents/models/OpenApiAnonymousAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiAuthType.java","src/main/java/com/azure/ai/agents/models/OpenApiFunctionDefinition.java","src/main/java/com/azure/ai/agents/models/OpenApiFunctionDefinitionFunction.java","src/main/java/com/azure/ai/agents/models/OpenApiManagedAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiManagedSecurityScheme.java","src/main/java/com/azure/ai/agents/models/OpenApiProjectConnectionAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiProjectConnectionSecurityScheme.java","src/main/java/com/azure/ai/agents/models/OpenApiTool.java","src/main/java/com/azure/ai/agents/models/OpenApiToolCall.java","src/main/java/com/azure/ai/agents/models/OpenApiToolCallOutput.java","src/main/java/com/azure/ai/agents/models/OpenApiToolboxTool.java","src/main/java/com/azure/ai/agents/models/OptimizationContext.java","src/main/java/com/azure/ai/agents/models/OptimizationContextType.java","src/main/java/com/azure/ai/agents/models/OtlpTelemetryEndpoint.java","src/main/java/com/azure/ai/agents/models/PageOrder.java","src/main/java/com/azure/ai/agents/models/ProceduralMemoryItem.java","src/main/java/com/azure/ai/agents/models/ProgrammaticToolCallingParameter.java","src/main/java/com/azure/ai/agents/models/PromptAgentDefinition.java","src/main/java/com/azure/ai/agents/models/PromptAgentDefinitionTextOptions.java","src/main/java/com/azure/ai/agents/models/PromptOptimizationConfiguration.java","src/main/java/com/azure/ai/agents/models/ProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/ProtocolVersionRecord.java","src/main/java/com/azure/ai/agents/models/PstnTelephonyTransferDestination.java","src/main/java/com/azure/ai/agents/models/PublishAgentToMicrosoft365Options.java","src/main/java/com/azure/ai/agents/models/PublishApprovalStatus.java","src/main/java/com/azure/ai/agents/models/RaiConfig.java","src/main/java/com/azure/ai/agents/models/RaiInvocationContentType.java","src/main/java/com/azure/ai/agents/models/RaiInvocationModeration.java","src/main/java/com/azure/ai/agents/models/RaiInvocationResponseMode.java","src/main/java/com/azure/ai/agents/models/RaiSseTextSelector.java","src/main/java/com/azure/ai/agents/models/RankerVersionType.java","src/main/java/com/azure/ai/agents/models/RankingOptions.java","src/main/java/com/azure/ai/agents/models/RealtimeAudioFormat.java","src/main/java/com/azure/ai/agents/models/RealtimeAudioFormatType.java","src/main/java/com/azure/ai/agents/models/RealtimeClientEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeClientEventType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemCreateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDeleteEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDeletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionSegmentEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemMessageType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemObjectType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemRetrieveEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemRetrievedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemTruncateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemTruncatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeErrorEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferAppendEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferClearEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferClearedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferCommitEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferCommittedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferDtmfReceivedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferSpeechStartedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferSpeechStoppedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferTimeoutTriggeredEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpApprovalInput.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpApprovalOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpError.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpErrorType.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpHttpError.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsInProgressEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpProtocolError.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpToolExecutionError.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferClearEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferClearedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferStartedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferStoppedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimePcmAudioFormat.java","src/main/java/com/azure/ai/agents/models/RealtimePcmaAudioFormat.java","src/main/java/com/azure/ai/agents/models/RealtimePcmuAudioFormat.java","src/main/java/com/azure/ai/agents/models/RealtimeRateLimitsUpdatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioTranscriptDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioTranscriptDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCancelEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPartAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPartDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCreateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseFunctionCallArgumentsDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseFunctionCallArgumentsDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputAudio.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputFunctionCall.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputFunctionCallOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputImage.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputItemStatus.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageAssistant.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageAssistantContent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageDeveloper.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageSystem.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageType.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageUser.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputText.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseItemReference.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallArgumentsDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallArgumentsDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallInProgressEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseOutputItemAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseOutputItemDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseTextDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseTextDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeSemanticVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java","src/main/java/com/azure/ai/agents/models/RealtimeServerVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioConfiguration.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioInput.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionAudioOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionConfiguration.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionConfigurationBase.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionCreateRequestGAAudioOutputVoice.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionTracingConfiguration.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionType.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioConfiguration.java","src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionAudioInput.java","src/main/java/com/azure/ai/agents/models/RealtimeTranscriptionSessionConfiguration.java","src/main/java/com/azure/ai/agents/models/RealtimeTurnDetection.java","src/main/java/com/azure/ai/agents/models/RealtimeTurnDetectionType.java","src/main/java/com/azure/ai/agents/models/ReminderPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/ResponseFormatJsonSchemaInner.java","src/main/java/com/azure/ai/agents/models/ResponseUsageInputTokensDetails.java","src/main/java/com/azure/ai/agents/models/ResponseUsageOutputTokensDetails.java","src/main/java/com/azure/ai/agents/models/ResponsesProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/RoutingConfiguration.java","src/main/java/com/azure/ai/agents/models/RoutingTraceEntry.java","src/main/java/com/azure/ai/agents/models/SearchContentType.java","src/main/java/com/azure/ai/agents/models/SearchContextSize.java","src/main/java/com/azure/ai/agents/models/SessionAffinityConfiguration.java","src/main/java/com/azure/ai/agents/models/SessionAffinityDecision.java","src/main/java/com/azure/ai/agents/models/SessionAffinityDetails.java","src/main/java/com/azure/ai/agents/models/SessionAffinityMode.java","src/main/java/com/azure/ai/agents/models/SessionAffinityRequestMode.java","src/main/java/com/azure/ai/agents/models/SessionAffinitySource.java","src/main/java/com/azure/ai/agents/models/SessionConfiguration.java","src/main/java/com/azure/ai/agents/models/SessionDirectoryEntry.java","src/main/java/com/azure/ai/agents/models/SessionFileWriteResult.java","src/main/java/com/azure/ai/agents/models/SessionLogEvent.java","src/main/java/com/azure/ai/agents/models/SessionLogEventType.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolCall.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolCallOutput.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolParameters.java","src/main/java/com/azure/ai/agents/models/SharepointPreviewTool.java","src/main/java/com/azure/ai/agents/models/ShellToolboxTool.java","src/main/java/com/azure/ai/agents/models/SipTelephonyTransferDestination.java","src/main/java/com/azure/ai/agents/models/SkillReference.java","src/main/java/com/azure/ai/agents/models/SkillReferenceParameter.java","src/main/java/com/azure/ai/agents/models/SteeringPromptOptimizationContext.java","src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java","src/main/java/com/azure/ai/agents/models/StructuredOutputDefinition.java","src/main/java/com/azure/ai/agents/models/TargetAttribute.java","src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/TeamsTelephonyTransferDestination.java","src/main/java/com/azure/ai/agents/models/TelemetryConfig.java","src/main/java/com/azure/ai/agents/models/TelemetryDataKind.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpoint.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointAuth.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointAuthType.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointKind.java","src/main/java/com/azure/ai/agents/models/TelemetryTransportProtocol.java","src/main/java/com/azure/ai/agents/models/TelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/TelephonyBindingStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCallDurationBasis.java","src/main/java/com/azure/ai/agents/models/TelephonyCallEndReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobCancellation.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobTerminalReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEvent.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventName.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventOutcome.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventSource.java","src/main/java/com/azure/ai/agents/models/TelephonyCallPhase.java","src/main/java/com/azure/ai/agents/models/TelephonyCallRecord.java","src/main/java/com/azure/ai/agents/models/TelephonyCallStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCallSummary.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTimestampSource.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTiming.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTrace.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTraceMode.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTraceStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestination.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundDestinationType.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundFixedIntervalRetryPolicy.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicyType.java","src/main/java/com/azure/ai/agents/models/TelephonyProvider.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferDestination.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferDestinationKind.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferTargets.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfiguration.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationResponseFormatJsonObject.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationResponseFormatText.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationType.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatJsonSchema.java","src/main/java/com/azure/ai/agents/models/Tool.java","src/main/java/com/azure/ai/agents/models/ToolCallStatus.java","src/main/java/com/azure/ai/agents/models/ToolConfig.java","src/main/java/com/azure/ai/agents/models/ToolFunctionToolType1.java","src/main/java/com/azure/ai/agents/models/ToolProjectConnection.java","src/main/java/com/azure/ai/agents/models/ToolSearchExecutionType.java","src/main/java/com/azure/ai/agents/models/ToolSearchTool.java","src/main/java/com/azure/ai/agents/models/ToolSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolType.java","src/main/java/com/azure/ai/agents/models/ToolboxDetails.java","src/main/java/com/azure/ai/agents/models/ToolboxPolicies.java","src/main/java/com/azure/ai/agents/models/ToolboxSearchPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolboxShellContainerAutoEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellContainerReferenceEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellNetworkPolicy.java","src/main/java/com/azure/ai/agents/models/ToolboxShellNetworkPolicyDisabled.java","src/main/java/com/azure/ai/agents/models/ToolboxSkill.java","src/main/java/com/azure/ai/agents/models/ToolboxSkillReference.java","src/main/java/com/azure/ai/agents/models/ToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolboxToolType.java","src/main/java/com/azure/ai/agents/models/ToolboxVersionDetails.java","src/main/java/com/azure/ai/agents/models/ToolboxVersions.java","src/main/java/com/azure/ai/agents/models/TranscriptTextInputTokenDetails.java","src/main/java/com/azure/ai/agents/models/TranscriptTextUsage.java","src/main/java/com/azure/ai/agents/models/TranscriptTextUsageDuration.java","src/main/java/com/azure/ai/agents/models/TranscriptTextUsageTokens.java","src/main/java/com/azure/ai/agents/models/TranscriptTextUsageType.java","src/main/java/com/azure/ai/agents/models/TranscriptionLanguage.java","src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/UpdateAgentDetailsOptions.java","src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationAudioEffect.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationAudioEffectsConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationDefaultInterruptionConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationInterruptionConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationTestCase.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationUserBehaviorConfiguration.java","src/main/java/com/azure/ai/agents/models/UserProfileMemoryItem.java","src/main/java/com/azure/ai/agents/models/VersionIndicator.java","src/main/java/com/azure/ai/agents/models/VersionIndicatorType.java","src/main/java/com/azure/ai/agents/models/VersionRefIndicator.java","src/main/java/com/azure/ai/agents/models/VersionSelectionRule.java","src/main/java/com/azure/ai/agents/models/VersionSelector.java","src/main/java/com/azure/ai/agents/models/VersionSelectorType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAnimationConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAnimationOutputType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioTimestampType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarIceServer.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarOutputProtocol.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarScene.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoBackground.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoCrop.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoParameters.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoResolution.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadEnglishTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadMultilingualTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEchoCancellation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEchoCancellationReferenceSource.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceDetectionModel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceThresholdLevel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscriptionModel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseTrigger.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentNoiseReduction.java","src/main/java/com/azure/ai/agents/models/VoiceAgentNoiseReductionType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentProfanityFilterMode.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationBlendshapeDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationBlendshapeDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationVisemeDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationVisemeDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioConfig.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseVideoDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallSdpCreateEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallSdpCreatedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSemanticVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentServerVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConnectEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConnectingEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarSwitchToIdleEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarSwitchToSpeakingEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionIncludeOption.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentAbortedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentCompletedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentStartedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeSound.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeSourceConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeTrackConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeWorkingTrackConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentAbortReason.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentResponsePolicy.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentToolResponseScheduling.java","src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTranscriptionPhrase.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTranscriptionWord.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransport.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTurnDetectionConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTurnDetectionType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentWarningDetails.java","src/main/java/com/azure/ai/agents/models/VoiceAgentWarningEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAudioCodec.java","src/main/java/com/azure/ai/agents/models/VoiceAudioContainerFormat.java","src/main/java/com/azure/ai/agents/models/VoiceAudioItem.java","src/main/java/com/azure/ai/agents/models/VoiceAudioRole.java","src/main/java/com/azure/ai/agents/models/VoiceConversation.java","src/main/java/com/azure/ai/agents/models/VoiceConversationEngine.java","src/main/java/com/azure/ai/agents/models/VoiceConversationStatus.java","src/main/java/com/azure/ai/agents/models/VoiceGeneratedAudioItem.java","src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java","src/main/java/com/azure/ai/agents/models/VoiceIds.java","src/main/java/com/azure/ai/agents/models/VoiceModelType.java","src/main/java/com/azure/ai/agents/models/VoiceOutputModality.java","src/main/java/com/azure/ai/agents/models/VoiceRecording.java","src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java","src/main/java/com/azure/ai/agents/models/VoiceResponse.java","src/main/java/com/azure/ai/agents/models/VoiceResponseAudio.java","src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java","src/main/java/com/azure/ai/agents/models/VoiceResponseObjectType.java","src/main/java/com/azure/ai/agents/models/VoiceType.java","src/main/java/com/azure/ai/agents/models/WebIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/WebIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/WebSearchApproximateLocation.java","src/main/java/com/azure/ai/agents/models/WebSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/WebSearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/WebSearchTool.java","src/main/java/com/azure/ai/agents/models/WebSearchToolFilters.java","src/main/java/com/azure/ai/agents/models/WebSearchToolSearchContextSize.java","src/main/java/com/azure/ai/agents/models/WebSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/WorkIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/WorkIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/WorkflowAgentDefinition.java","src/main/java/com/azure/ai/agents/models/package-info.java","src/main/java/com/azure/ai/agents/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file +{"flavor":"azure","apiVersions":{"Azure.AI.Projects":"v1"},"crossLanguagePackageId":"Azure.AI.Projects","crossLanguageVersion":"54ffc5f68a09","crossLanguageDefinitions":{"com.azure.ai.agents.AgentsAsyncClient":"Azure.AI.Projects.Agents","com.azure.ai.agents.AgentsAsyncClient.beginCreateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsAsyncClient.beginCreateOptimizationJobWithModel":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsAsyncClient.cancelOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsAsyncClient.cancelOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsAsyncClient.createAgent":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsAsyncClient.createAgentFromCode":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentFromManifest":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersion":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromCode":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromManifest":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsAsyncClient.createAgentVersionWithResponse":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsAsyncClient.createAgentWithResponse":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsAsyncClient.createSession":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsAsyncClient.createSessionWithResponse":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsAsyncClient.deleteOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsAsyncClient.deleteOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsAsyncClient.deleteSession":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsAsyncClient.deleteSessionFile":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsAsyncClient.deleteSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsAsyncClient.deleteSessionWithResponse":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsAsyncClient.disableAgent":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsAsyncClient.disableAgentWithResponse":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsAsyncClient.downloadAgentCode":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsAsyncClient.downloadAgentCodeWithResponse":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsAsyncClient.downloadSessionFile":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsAsyncClient.downloadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsAsyncClient.enableAgent":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsAsyncClient.enableAgentWithResponse":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsAsyncClient.estimateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsAsyncClient.estimateOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsAsyncClient.getAgent":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsAsyncClient.getAgentVersionDetails":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsAsyncClient.getAgentVersionDetailsWithResponse":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsAsyncClient.getAgentWithResponse":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365AppPackage":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365AppPackageWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365PublishDefaults":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsAsyncClient.getMicrosoft365PublishDefaultsWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsAsyncClient.getOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsAsyncClient.getOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsAsyncClient.getOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsAsyncClient.getOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsAsyncClient.getSession":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsAsyncClient.getSessionWithResponse":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsAsyncClient.listAgentConversations":"Azure.AI.Projects.Conversations.listConversations","com.azure.ai.agents.AgentsAsyncClient.listAgentVersions":"Azure.AI.Projects.Agents.listAgentVersions","com.azure.ai.agents.AgentsAsyncClient.listAgents":"Azure.AI.Projects.Agents.listAgents","com.azure.ai.agents.AgentsAsyncClient.listOptimizationCandidates":"Azure.AI.Projects.AgentOptimizationJobCandidates.listCandidates","com.azure.ai.agents.AgentsAsyncClient.listOptimizationJobs":"Azure.AI.Projects.AgentOptimizationJobs.list","com.azure.ai.agents.AgentsAsyncClient.listSessionFiles":"Azure.AI.Projects.AgentSessionFiles.listSessionFiles","com.azure.ai.agents.AgentsAsyncClient.listSessions":"Azure.AI.Projects.Agents.listSessions","com.azure.ai.agents.AgentsAsyncClient.promoteOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsAsyncClient.promoteOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsAsyncClient.publishAgentToMicrosoft365":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsAsyncClient.publishAgentToMicrosoft365WithResponse":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsAsyncClient.stopSession":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsAsyncClient.stopSessionWithResponse":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsAsyncClient.updateAgent":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsAsyncClient.updateAgentDetails":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsAsyncClient.updateAgentDetailsWithResponse":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromCode":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromManifest":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.updateAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsAsyncClient.updateAgentWithResponse":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsAsyncClient.uploadSessionFile":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsAsyncClient.uploadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClient":"Azure.AI.Projects.Agents","com.azure.ai.agents.AgentsClient.beginCreateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsClient.beginCreateOptimizationJobWithModel":"Azure.AI.Projects.AgentOptimizationJobs.create","com.azure.ai.agents.AgentsClient.cancelOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsClient.cancelOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.cancel","com.azure.ai.agents.AgentsClient.createAgent":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsClient.createAgentFromCode":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsClient.createAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentFromCode","com.azure.ai.agents.AgentsClient.createAgentFromManifest":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsClient.createAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersion":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsClient.createAgentVersionFromCode":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsClient.createAgentVersionFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.createAgentVersionFromCode","com.azure.ai.agents.AgentsClient.createAgentVersionFromManifest":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersionFromManifestWithResponse":"Azure.AI.Projects.Agents.createAgentVersionFromManifest","com.azure.ai.agents.AgentsClient.createAgentVersionWithResponse":"Azure.AI.Projects.Agents.createAgentVersion","com.azure.ai.agents.AgentsClient.createAgentWithResponse":"Azure.AI.Projects.Agents.createAgent","com.azure.ai.agents.AgentsClient.createSession":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsClient.createSessionWithResponse":"Azure.AI.Projects.Agents.createSession","com.azure.ai.agents.AgentsClient.deleteOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsClient.deleteOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.delete","com.azure.ai.agents.AgentsClient.deleteSession":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsClient.deleteSessionFile":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsClient.deleteSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.deleteSessionFile","com.azure.ai.agents.AgentsClient.deleteSessionWithResponse":"Azure.AI.Projects.Agents.deleteSession","com.azure.ai.agents.AgentsClient.disableAgent":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsClient.disableAgentWithResponse":"Azure.AI.Projects.Agents.disableAgent","com.azure.ai.agents.AgentsClient.downloadAgentCode":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsClient.downloadAgentCodeWithResponse":"Azure.AI.Projects.Agents.downloadAgentCode","com.azure.ai.agents.AgentsClient.downloadSessionFile":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsClient.downloadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.downloadSessionFile","com.azure.ai.agents.AgentsClient.enableAgent":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsClient.enableAgentWithResponse":"Azure.AI.Projects.Agents.enableAgent","com.azure.ai.agents.AgentsClient.estimateOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsClient.estimateOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.estimate","com.azure.ai.agents.AgentsClient.getAgent":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsClient.getAgentVersionDetails":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsClient.getAgentVersionDetailsWithResponse":"Azure.AI.Projects.Agents.getAgentVersion","com.azure.ai.agents.AgentsClient.getAgentWithResponse":"Azure.AI.Projects.Agents.getAgent","com.azure.ai.agents.AgentsClient.getMicrosoft365AppPackage":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsClient.getMicrosoft365AppPackageWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365AppPackage","com.azure.ai.agents.AgentsClient.getMicrosoft365PublishDefaults":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsClient.getMicrosoft365PublishDefaultsWithResponse":"Azure.AI.Projects.Microsoft365Publishing.getMicrosoft365PublishDefaults","com.azure.ai.agents.AgentsClient.getOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsClient.getOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.getCandidate","com.azure.ai.agents.AgentsClient.getOptimizationJob":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsClient.getOptimizationJobWithResponse":"Azure.AI.Projects.AgentOptimizationJobs.get","com.azure.ai.agents.AgentsClient.getSession":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsClient.getSessionWithResponse":"Azure.AI.Projects.Agents.getSession","com.azure.ai.agents.AgentsClient.listAgentConversations":"Azure.AI.Projects.Conversations.listConversations","com.azure.ai.agents.AgentsClient.listAgentVersions":"Azure.AI.Projects.Agents.listAgentVersions","com.azure.ai.agents.AgentsClient.listAgents":"Azure.AI.Projects.Agents.listAgents","com.azure.ai.agents.AgentsClient.listOptimizationCandidates":"Azure.AI.Projects.AgentOptimizationJobCandidates.listCandidates","com.azure.ai.agents.AgentsClient.listOptimizationJobs":"Azure.AI.Projects.AgentOptimizationJobs.list","com.azure.ai.agents.AgentsClient.listSessionFiles":"Azure.AI.Projects.AgentSessionFiles.listSessionFiles","com.azure.ai.agents.AgentsClient.listSessions":"Azure.AI.Projects.Agents.listSessions","com.azure.ai.agents.AgentsClient.promoteOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsClient.promoteOptimizationCandidateWithResponse":"Azure.AI.Projects.AgentOptimizationJobCandidates.promoteCandidate","com.azure.ai.agents.AgentsClient.publishAgentToMicrosoft365":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsClient.publishAgentToMicrosoft365WithResponse":"Azure.AI.Projects.Microsoft365Publishing.publishAgentToMicrosoft365","com.azure.ai.agents.AgentsClient.stopSession":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsClient.stopSessionWithResponse":"Azure.AI.Projects.Agents.stopSession","com.azure.ai.agents.AgentsClient.updateAgent":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsClient.updateAgentDetails":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsClient.updateAgentDetailsWithResponse":"Azure.AI.Projects.Agents.patchAgentObject","com.azure.ai.agents.AgentsClient.updateAgentFromCode":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsClient.updateAgentFromCodeWithResponseInternal":"Azure.AI.Projects.Agents.updateAgentFromCode","com.azure.ai.agents.AgentsClient.updateAgentFromManifest":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsClient.updateAgentFromManifestWithResponse":"Azure.AI.Projects.Agents.updateAgentFromManifest","com.azure.ai.agents.AgentsClient.updateAgentWithResponse":"Azure.AI.Projects.Agents.updateAgent","com.azure.ai.agents.AgentsClient.uploadSessionFile":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClient.uploadSessionFileWithResponse":"Azure.AI.Projects.AgentSessionFiles.uploadSessionFile","com.azure.ai.agents.AgentsClientBuilder":"Azure.AI.Projects","com.azure.ai.agents.BetaAgentsAsyncClient":"Azure.AI.Projects.Beta.Agents","com.azure.ai.agents.BetaAgentsAsyncClient.createAgentFromPrompt":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsAsyncClient.createAgentFromPromptWithResponse":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsClient":"Azure.AI.Projects.Beta.Agents","com.azure.ai.agents.BetaAgentsClient.createAgentFromPrompt":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaAgentsClient.createAgentFromPromptWithResponse":"Azure.AI.Projects.Agents.generateAgent","com.azure.ai.agents.BetaMemoryStoresAsyncClient":"Azure.AI.Projects.Beta.MemoryStores","com.azure.ai.agents.BetaMemoryStoresAsyncClient.beginInternalUpdateMemories":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.beginInternalUpdateMemoriesWithModel":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemory":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryStore":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.createMemoryWithResponse":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemory":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryStore":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getMemoryWithResponse":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getUpdateResult":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresAsyncClient.getUpdateResultWithResponse":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresAsyncClient.internalSearchMemories":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.internalSearchMemoriesWithResponse":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.listMemories":"Azure.AI.Projects.MemoryStores.listMemories","com.azure.ai.agents.BetaMemoryStoresAsyncClient.listMemoryStores":"Azure.AI.Projects.MemoryStores.listMemoryStores","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemory":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryStore":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresAsyncClient.updateMemoryWithResponse":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresClient":"Azure.AI.Projects.Beta.MemoryStores","com.azure.ai.agents.BetaMemoryStoresClient.beginInternalUpdateMemories":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresClient.beginInternalUpdateMemoriesWithModel":"Azure.AI.Projects.MemoryStores.updateMemories","com.azure.ai.agents.BetaMemoryStoresClient.createMemory":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryStore":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.createMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.createMemoryWithResponse":"Azure.AI.Projects.MemoryStores.createMemory","com.azure.ai.agents.BetaMemoryStoresClient.getMemory":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryStore":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.getMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.getMemoryWithResponse":"Azure.AI.Projects.MemoryStores.getMemory","com.azure.ai.agents.BetaMemoryStoresClient.getUpdateResult":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresClient.getUpdateResultWithResponse":"Azure.AI.Projects.MemoryStores.getUpdateResult","com.azure.ai.agents.BetaMemoryStoresClient.internalSearchMemories":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresClient.internalSearchMemoriesWithResponse":"Azure.AI.Projects.MemoryStores.searchMemories","com.azure.ai.agents.BetaMemoryStoresClient.listMemories":"Azure.AI.Projects.MemoryStores.listMemories","com.azure.ai.agents.BetaMemoryStoresClient.listMemoryStores":"Azure.AI.Projects.MemoryStores.listMemoryStores","com.azure.ai.agents.BetaMemoryStoresClient.updateMemory":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryStore":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryStoreWithResponse":"Azure.AI.Projects.MemoryStores.updateMemoryStore","com.azure.ai.agents.BetaMemoryStoresClient.updateMemoryWithResponse":"Azure.AI.Projects.MemoryStores.updateMemory","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient":"Azure.AI.Projects.Beta.VoiceAgents.Conversations","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.downloadAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationResponseWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationResponseItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversationResponses":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses","com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversations","com.azure.ai.agents.BetaVoiceAgentsConversationsClient":"Azure.AI.Projects.Beta.VoiceAgents.Conversations","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.deleteAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.downloadAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationGeneratedAudioItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationGeneratedAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationGeneratedAudioItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationResponseWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversationResponse","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointConversations.getAgentConversation","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationResponseItems":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponseItems","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversationResponses":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversationResponses","com.azure.ai.agents.BetaVoiceAgentsConversationsClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointConversations.listAgentConversations","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient":"Azure.AI.Projects.Beta.VoiceAgents.LiveConversations","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointLiveConversations.deleteLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.deleteLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointLiveConversations.listLiveAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointLiveConversations.listLiveAgentConversations","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient":"Azure.AI.Projects.Beta.VoiceAgents.LiveConversations","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.deleteAgentConversation":"Azure.AI.Projects.AgentEndpointLiveConversations.deleteLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.deleteAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.deleteLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.downloadAgentConversationAudio":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.downloadAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.downloadAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItemContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.downloadAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioContent","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversation":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationAudio":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationAudioItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationAudioItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudioItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationAudioWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationAudio","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationItem":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationItemWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversationItem","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.getAgentConversationWithResponse":"Azure.AI.Projects.AgentEndpointLiveConversations.getLiveAgentConversation","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.listAgentConversationItems":"Azure.AI.Projects.AgentEndpointLiveConversations.listLiveAgentConversationItems","com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient.listAgentConversations":"Azure.AI.Projects.AgentEndpointLiveConversations.listLiveAgentConversations","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient":"Azure.AI.Projects.Beta.VoiceAgents.Telephony","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginCancelCampaign":"Azure.AI.Projects.TelephonyCampaigns.cancel","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginCancelCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.cancel","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginCreateCampaign":"Azure.AI.Projects.TelephonyCampaigns.create","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginCreateCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.create","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginDeleteCampaign":"Azure.AI.Projects.TelephonyCampaigns.delete","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.beginDeleteCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.delete","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.cancelTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.cancelTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyBinding":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.createTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyBinding":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.deleteTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.deleteTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.endTelephonyCall":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.endTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getCampaign":"Azure.AI.Projects.TelephonyCampaigns.get","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getCampaignOperation":"Azure.AI.Projects.TelephonyCampaigns.getOperation","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getCampaignOperationWithResponse":"Azure.AI.Projects.TelephonyCampaigns.getOperation","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getCampaignWithResponse":"Azure.AI.Projects.TelephonyCampaigns.get","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyBinding":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCall":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.getTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listCampaignValidationErrors":"Azure.AI.Projects.TelephonyCampaigns.listValidationErrors","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listCampaigns":"Azure.AI.Projects.TelephonyCampaigns.list","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listTelephonyBindings":"Azure.AI.Projects.AgentTelephony.listTelephonyBindings","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listTelephonyCallJobs":"Azure.AI.Projects.AgentTelephony.listTelephonyCallJobs","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.listTelephonyCalls":"Azure.AI.Projects.AgentTelephony.listTelephonyCalls","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.replaceTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.replaceTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.transferTelephonyCall":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.transferTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.updateTelephonyBinding":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient.updateTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient":"Azure.AI.Projects.Beta.VoiceAgents.Telephony","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginCancelCampaign":"Azure.AI.Projects.TelephonyCampaigns.cancel","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginCancelCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.cancel","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginCreateCampaign":"Azure.AI.Projects.TelephonyCampaigns.create","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginCreateCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.create","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginDeleteCampaign":"Azure.AI.Projects.TelephonyCampaigns.delete","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.beginDeleteCampaignWithModel":"Azure.AI.Projects.TelephonyCampaigns.delete","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.cancelTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.cancelTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.cancelTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyBinding":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.createTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.createTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyBinding":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.deleteTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.deleteTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.deleteTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.endTelephonyCall":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.endTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.endTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getCampaign":"Azure.AI.Projects.TelephonyCampaigns.get","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getCampaignOperation":"Azure.AI.Projects.TelephonyCampaigns.getOperation","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getCampaignOperationWithResponse":"Azure.AI.Projects.TelephonyCampaigns.getOperation","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getCampaignWithResponse":"Azure.AI.Projects.TelephonyCampaigns.get","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyBinding":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCall":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallJob":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallJobWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCallJob","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.getTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.getTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listCampaignValidationErrors":"Azure.AI.Projects.TelephonyCampaigns.listValidationErrors","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listCampaigns":"Azure.AI.Projects.TelephonyCampaigns.list","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listTelephonyBindings":"Azure.AI.Projects.AgentTelephony.listTelephonyBindings","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listTelephonyCallJobs":"Azure.AI.Projects.AgentTelephony.listTelephonyCallJobs","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.listTelephonyCalls":"Azure.AI.Projects.AgentTelephony.listTelephonyCalls","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.replaceTelephonyTransferTargets":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.replaceTelephonyTransferTargetsWithResponse":"Azure.AI.Projects.AgentTelephony.replaceTelephonyTransferTargets","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.transferTelephonyCall":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.transferTelephonyCallWithResponse":"Azure.AI.Projects.AgentTelephony.transferTelephonyCall","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.updateTelephonyBinding":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.BetaVoiceAgentsTelephonyClient.updateTelephonyBindingWithResponse":"Azure.AI.Projects.AgentTelephony.updateTelephonyBinding","com.azure.ai.agents.ToolboxesAsyncClient":"Azure.AI.Projects.Toolboxes","com.azure.ai.agents.ToolboxesAsyncClient.createToolboxVersion":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.createToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolbox":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxVersion":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.deleteToolboxWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesAsyncClient.getToolbox":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxVersion":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesAsyncClient.getToolboxWithResponse":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesAsyncClient.invokeLatestToolboxMcp":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesAsyncClient.invokeLatestToolboxMcpWithResponse":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesAsyncClient.listToolboxVersions":"Azure.AI.Projects.Toolboxes.listToolboxVersions","com.azure.ai.agents.ToolboxesAsyncClient.listToolboxes":"Azure.AI.Projects.Toolboxes.listToolboxes","com.azure.ai.agents.ToolboxesAsyncClient.updateToolbox":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesAsyncClient.updateToolboxWithResponse":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesClient":"Azure.AI.Projects.Toolboxes","com.azure.ai.agents.ToolboxesClient.createToolboxVersion":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesClient.createToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.createToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolbox":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesClient.deleteToolboxVersion":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolboxVersion","com.azure.ai.agents.ToolboxesClient.deleteToolboxWithResponse":"Azure.AI.Projects.Toolboxes.deleteToolbox","com.azure.ai.agents.ToolboxesClient.getToolbox":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesClient.getToolboxVersion":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesClient.getToolboxVersionWithResponse":"Azure.AI.Projects.Toolboxes.getToolboxVersion","com.azure.ai.agents.ToolboxesClient.getToolboxWithResponse":"Azure.AI.Projects.Toolboxes.getToolbox","com.azure.ai.agents.ToolboxesClient.invokeLatestToolboxMcp":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesClient.invokeLatestToolboxMcpWithResponse":"Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp","com.azure.ai.agents.ToolboxesClient.listToolboxVersions":"Azure.AI.Projects.Toolboxes.listToolboxVersions","com.azure.ai.agents.ToolboxesClient.listToolboxes":"Azure.AI.Projects.Toolboxes.listToolboxes","com.azure.ai.agents.ToolboxesClient.updateToolbox":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.ToolboxesClient.updateToolboxWithResponse":"Azure.AI.Projects.Toolboxes.updateToolbox","com.azure.ai.agents.implementation.models.AgentDefinitionOptInKeys":"Azure.AI.Projects.AgentDefinitionOptInKeys","com.azure.ai.agents.implementation.models.CreateAgentFromCodeContent":"Azure.AI.Projects.CreateAgentFromCodeContent","com.azure.ai.agents.implementation.models.CreateAgentFromManifestRequest":"Azure.AI.Projects.createAgentFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentOptions":null,"com.azure.ai.agents.implementation.models.CreateAgentRequest":"Azure.AI.Projects.createAgent.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentVersionFromManifestRequest":"Azure.AI.Projects.createAgentVersionFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.CreateAgentVersionRequest":"Azure.AI.Projects.createAgentVersion.Request.anonymous","com.azure.ai.agents.implementation.models.CreateMemoryRequest":"Azure.AI.Projects.createMemory.Request.anonymous","com.azure.ai.agents.implementation.models.CreateMemoryStoreRequest":"Azure.AI.Projects.createMemoryStore.Request.anonymous","com.azure.ai.agents.implementation.models.CreateSessionRequest":"Azure.AI.Projects.createSession.Request.anonymous","com.azure.ai.agents.implementation.models.CreateToolboxVersionRequest":"Azure.AI.Projects.createToolboxVersion.Request.anonymous","com.azure.ai.agents.implementation.models.FoundryFeaturesOptInKeys":"Azure.AI.Projects.FoundryFeaturesOptInKeys","com.azure.ai.agents.implementation.models.GetMicrosoft365AppPackageRequest":"Azure.AI.Projects.getMicrosoft365AppPackage.Request.anonymous","com.azure.ai.agents.implementation.models.ListMemoriesRequest":"Azure.AI.Projects.listMemories.Request.anonymous","com.azure.ai.agents.implementation.models.PublishAgentToMicrosoft365Request":"Azure.AI.Projects.publishAgentToMicrosoft365.Request.anonymous","com.azure.ai.agents.implementation.models.ReplaceTelephonyTransferTargetsRequest":"Azure.AI.Projects.replaceTelephonyTransferTargets.Request.anonymous","com.azure.ai.agents.implementation.models.SearchMemoriesRequest":"Azure.AI.Projects.searchMemories.Request.anonymous","com.azure.ai.agents.implementation.models.TransferTelephonyCallRequest":"Azure.AI.Projects.transferTelephonyCall.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateAgentFromManifestRequest":"Azure.AI.Projects.updateAgentFromManifest.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateAgentRequest":"Azure.AI.Projects.updateAgent.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoriesRequest":"Azure.AI.Projects.updateMemories.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoryRequest":"Azure.AI.Projects.updateMemory.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateMemoryStoreRequest":"Azure.AI.Projects.updateMemoryStore.Request.anonymous","com.azure.ai.agents.implementation.models.UpdateToolboxInput":"Azure.AI.Projects.UpdateToolboxRequest","com.azure.ai.agents.implementation.models.UpdateToolboxRequest":"Azure.AI.Projects.updateToolbox.Request.anonymous","com.azure.ai.agents.models.A2APreviewTool":"Azure.AI.Projects.A2APreviewTool","com.azure.ai.agents.models.A2APreviewToolboxTool":"Azure.AI.Projects.A2APreviewToolboxTool","com.azure.ai.agents.models.A2AProtocolConfiguration":"Azure.AI.Projects.A2AProtocolConfiguration","com.azure.ai.agents.models.A2AProtocolVersion":"Azure.AI.Projects.A2AProtocolVersion","com.azure.ai.agents.models.A2ATool":"Azure.AI.Projects.A2ATool","com.azure.ai.agents.models.A2AToolCall":"Azure.AI.Projects.A2AToolCall","com.azure.ai.agents.models.A2AToolCallOutput":"Azure.AI.Projects.A2AToolCallOutput","com.azure.ai.agents.models.A2AToolboxTool":"Azure.AI.Projects.A2AToolboxTool","com.azure.ai.agents.models.AISearchIndexResource":"Azure.AI.Projects.AISearchIndexResource","com.azure.ai.agents.models.ActivityProtocolAccessBoundary":"Azure.AI.Projects.ActivityProtocolAccessBoundary","com.azure.ai.agents.models.ActivityProtocolConfiguration":"Azure.AI.Projects.ActivityProtocolConfiguration","com.azure.ai.agents.models.AgentBlueprintReference":"Azure.AI.Projects.AgentBlueprintReference","com.azure.ai.agents.models.AgentBlueprintReferenceType":"Azure.AI.Projects.AgentBlueprintReferenceType","com.azure.ai.agents.models.AgentCard":"Azure.AI.Projects.AgentCard","com.azure.ai.agents.models.AgentCardSkill":"Azure.AI.Projects.AgentCardSkill","com.azure.ai.agents.models.AgentDefinition":"Azure.AI.Projects.AgentDefinition","com.azure.ai.agents.models.AgentDetails":"Azure.AI.Projects.AgentObject","com.azure.ai.agents.models.AgentDetailsVersions":"Azure.AI.Projects.AgentObject.versions.anonymous","com.azure.ai.agents.models.AgentEndpointAuthorizationScheme":"Azure.AI.Projects.AgentEndpointAuthorizationScheme","com.azure.ai.agents.models.AgentEndpointAuthorizationSchemeType":"Azure.AI.Projects.AgentEndpointAuthorizationSchemeType","com.azure.ai.agents.models.AgentEndpointConfig":"Azure.AI.Projects.AgentEndpointConfig","com.azure.ai.agents.models.AgentEndpointProtocol":"Azure.AI.Projects.AgentEndpointProtocol","com.azure.ai.agents.models.AgentHarness":"Azure.AI.Projects.AgentHarness","com.azure.ai.agents.models.AgentIdentity":"Azure.AI.Projects.AgentIdentity","com.azure.ai.agents.models.AgentIdentityStatus":"Azure.AI.Projects.AgentIdentityStatus","com.azure.ai.agents.models.AgentKind":"Azure.AI.Projects.AgentKind","com.azure.ai.agents.models.AgentObjectType":"Azure.AI.Projects.AgentObjectType","com.azure.ai.agents.models.AgentOptimizationAgentCandidateOutput":"Azure.AI.Projects.AgentOptimizationAgentCandidateOutput","com.azure.ai.agents.models.AgentOptimizationBaselineAgentConfiguration":"Azure.AI.Projects.AgentOptimizationBaselineAgentConfiguration","com.azure.ai.agents.models.AgentOptimizationCandidate":"Azure.AI.Projects.AgentOptimizationCandidate","com.azure.ai.agents.models.AgentOptimizationCandidateEvaluation":"Azure.AI.Projects.AgentOptimizationCandidateEvaluation","com.azure.ai.agents.models.AgentOptimizationCandidateExpand":"Azure.AI.Projects.AgentOptimizationCandidateExpand","com.azure.ai.agents.models.AgentOptimizationCandidateOutput":"Azure.AI.Projects.AgentOptimizationCandidateOutput","com.azure.ai.agents.models.AgentOptimizationCandidatePromotionInfo":"Azure.AI.Projects.AgentOptimizationCandidatePromotionInfo","com.azure.ai.agents.models.AgentOptimizationCandidateSearchConfiguration":"Azure.AI.Projects.AgentOptimizationCandidateSearchConfiguration","com.azure.ai.agents.models.AgentOptimizationCandidateStatus":"Azure.AI.Projects.AgentOptimizationCandidateStatus","com.azure.ai.agents.models.AgentOptimizationConfiguration":"Azure.AI.Projects.AgentOptimizationConfiguration","com.azure.ai.agents.models.AgentOptimizationConfigurationBase":"Azure.AI.Projects.AgentOptimizationConfigurationBase","com.azure.ai.agents.models.AgentOptimizationConfigurationType":"Azure.AI.Projects.AgentOptimizationConfigurationType","com.azure.ai.agents.models.AgentOptimizationCostEstimate":"Azure.AI.Projects.AgentOptimizationCostEstimate","com.azure.ai.agents.models.AgentOptimizationDataSourceType":"Azure.AI.Projects.AgentOptimizationDataSourceType","com.azure.ai.agents.models.AgentOptimizationEstimateBand":"Azure.AI.Projects.AgentOptimizationEstimateBand","com.azure.ai.agents.models.AgentOptimizationEstimateInputs":"Azure.AI.Projects.AgentOptimizationEstimateInputs","com.azure.ai.agents.models.AgentOptimizationEstimateResult":"Azure.AI.Projects.AgentOptimizationEstimateResult","com.azure.ai.agents.models.AgentOptimizationEvaluationConfiguration":"Azure.AI.Projects.AgentOptimizationEvaluationConfiguration","com.azure.ai.agents.models.AgentOptimizationEvaluationSet":"Azure.AI.Projects.AgentOptimizationEvaluationSet","com.azure.ai.agents.models.AgentOptimizationEvaluationSetType":"Azure.AI.Projects.AgentOptimizationEvaluationSetType","com.azure.ai.agents.models.AgentOptimizationEvaluatorReference":"Azure.AI.Projects.AgentOptimizationEvaluator","com.azure.ai.agents.models.AgentOptimizationFoundryAgentTargetConfiguration":"Azure.AI.Projects.AgentOptimizationFoundryAgentTargetConfiguration","com.azure.ai.agents.models.AgentOptimizationGoal":"Azure.AI.Projects.AgentOptimizationGoal","com.azure.ai.agents.models.AgentOptimizationInstructionsMutation":"Azure.AI.Projects.AgentOptimizationInstructionsMutation","com.azure.ai.agents.models.AgentOptimizationJob":"Azure.AI.Projects.AgentOptimizationJob","com.azure.ai.agents.models.AgentOptimizationJobLatency":"Azure.AI.Projects.AgentOptimizationJobLatency","com.azure.ai.agents.models.AgentOptimizationJobResult":"Azure.AI.Projects.AgentOptimizationJobResult","com.azure.ai.agents.models.AgentOptimizationJobTokenUsage":"Azure.AI.Projects.AgentOptimizationJobTokenUsage","com.azure.ai.agents.models.AgentOptimizationModelConfiguration":"Azure.AI.Projects.AgentOptimizationModelConfiguration","com.azure.ai.agents.models.AgentOptimizationModelMutation":"Azure.AI.Projects.AgentOptimizationModelMutation","com.azure.ai.agents.models.AgentOptimizationMutation":"Azure.AI.Projects.AgentOptimizationMutation","com.azure.ai.agents.models.AgentOptimizationPromptCandidateOutput":"Azure.AI.Projects.AgentOptimizationPromptCandidateOutput","com.azure.ai.agents.models.AgentOptimizationResultCandidateSummary":"Azure.AI.Projects.AgentOptimizationResultCandidateSummary","com.azure.ai.agents.models.AgentOptimizationSkill":"Azure.AI.Projects.AgentOptimizationSkill","com.azure.ai.agents.models.AgentOptimizationSkillsMutation":"Azure.AI.Projects.AgentOptimizationSkillsMutation","com.azure.ai.agents.models.AgentOptimizationSpace":"Azure.AI.Projects.AgentOptimizationSpace","com.azure.ai.agents.models.AgentOptimizationStage":"Azure.AI.Projects.AgentOptimizationStage","com.azure.ai.agents.models.AgentOptimizationStageEstimate":"Azure.AI.Projects.AgentOptimizationStageEstimate","com.azure.ai.agents.models.AgentOptimizationTargetCompletionDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionDatasetReferenceDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionDatasetReferenceDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionEvaluationSet":"Azure.AI.Projects.AgentOptimizationTargetCompletionEvaluationSet","com.azure.ai.agents.models.AgentOptimizationTargetCompletionInlineDataSource":"Azure.AI.Projects.AgentOptimizationTargetCompletionInlineDataSource","com.azure.ai.agents.models.AgentOptimizationTargetCompletionTestCase":"Azure.AI.Projects.AgentOptimizationTargetCompletionTestCase","com.azure.ai.agents.models.AgentOptimizationTargetConfiguration":"Azure.AI.Projects.AgentOptimizationTargetConfiguration","com.azure.ai.agents.models.AgentOptimizationTargetConfigurationType":"Azure.AI.Projects.AgentOptimizationTargetConfigurationType","com.azure.ai.agents.models.AgentOptimizationTerminationReason":"Azure.AI.Projects.AgentOptimizationTerminationReason","com.azure.ai.agents.models.AgentOptimizationToolsMutation":"Azure.AI.Projects.AgentOptimizationToolsMutation","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationDataSource","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationDatasetReferenceDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationDatasetReferenceDataSource","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationEvaluationSet":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationEvaluationSet","com.azure.ai.agents.models.AgentOptimizationUserConversationSimulationInlineDataSource":"Azure.AI.Projects.AgentOptimizationUserConversationSimulationInlineDataSource","com.azure.ai.agents.models.AgentReference":"Azure.AI.Projects.AgentReference","com.azure.ai.agents.models.AgentSessionResource":"Azure.AI.Projects.AgentSessionResource","com.azure.ai.agents.models.AgentSessionStatus":"Azure.AI.Projects.AgentSessionStatus","com.azure.ai.agents.models.AgentState":"Azure.AI.Projects.AgentState","com.azure.ai.agents.models.AgentStateSource":"Azure.AI.Projects.AgentStateSource","com.azure.ai.agents.models.AgentVersionDetails":"Azure.AI.Projects.AgentVersionObject","com.azure.ai.agents.models.AgentVersionStatus":"Azure.AI.Projects.AgentVersionStatus","com.azure.ai.agents.models.ApiError":"OpenAI.Error","com.azure.ai.agents.models.ApplyPatchToolParameter":"OpenAI.ToolApplyPatchToolParam","com.azure.ai.agents.models.ApproximateLocation":"OpenAI.ApproximateLocation","com.azure.ai.agents.models.AutoCodeInterpreterToolParameter":"OpenAI.AutoCodeInterpreterToolParam","com.azure.ai.agents.models.AzureAISearchQueryType":"Azure.AI.Projects.AzureAISearchQueryType","com.azure.ai.agents.models.AzureAISearchTool":"Azure.AI.Projects.AzureAISearchTool","com.azure.ai.agents.models.AzureAISearchToolCall":"Azure.AI.Projects.AzureAISearchToolCall","com.azure.ai.agents.models.AzureAISearchToolCallOutput":"Azure.AI.Projects.AzureAISearchToolCallOutput","com.azure.ai.agents.models.AzureAISearchToolResource":"Azure.AI.Projects.AzureAISearchToolResource","com.azure.ai.agents.models.AzureAISearchToolboxTool":"Azure.AI.Projects.AzureAISearchToolboxTool","com.azure.ai.agents.models.AzureCreateResponseDetails":"Azure.AI.Projects.AzureCreateResponseDetails","com.azure.ai.agents.models.AzureCreateResponseOptions":"Azure.AI.Projects.AzureCreateResponseOptions","com.azure.ai.agents.models.AzureFunctionBinding":"Azure.AI.Projects.AzureFunctionBinding","com.azure.ai.agents.models.AzureFunctionDefinition":"Azure.AI.Projects.AzureFunctionDefinition","com.azure.ai.agents.models.AzureFunctionDefinitionDetails":"Azure.AI.Projects.AzureFunctionDefinition.function.anonymous","com.azure.ai.agents.models.AzureFunctionStorageQueue":"Azure.AI.Projects.AzureFunctionStorageQueue","com.azure.ai.agents.models.AzureFunctionTool":"Azure.AI.Projects.AzureFunctionTool","com.azure.ai.agents.models.AzureFunctionToolCall":"Azure.AI.Projects.AzureFunctionToolCall","com.azure.ai.agents.models.AzureFunctionToolCallOutput":"Azure.AI.Projects.AzureFunctionToolCallOutput","com.azure.ai.agents.models.AzureUserSecurityContext":"Azure.AI.Projects.AzureUserSecurityContext","com.azure.ai.agents.models.BingCustomSearchConfiguration":"Azure.AI.Projects.BingCustomSearchConfiguration","com.azure.ai.agents.models.BingCustomSearchPreviewTool":"Azure.AI.Projects.BingCustomSearchPreviewTool","com.azure.ai.agents.models.BingCustomSearchToolCall":"Azure.AI.Projects.BingCustomSearchToolCall","com.azure.ai.agents.models.BingCustomSearchToolCallOutput":"Azure.AI.Projects.BingCustomSearchToolCallOutput","com.azure.ai.agents.models.BingCustomSearchToolParameters":"Azure.AI.Projects.BingCustomSearchToolParameters","com.azure.ai.agents.models.BingGroundingSearchConfiguration":"Azure.AI.Projects.BingGroundingSearchConfiguration","com.azure.ai.agents.models.BingGroundingSearchToolParameters":"Azure.AI.Projects.BingGroundingSearchToolParameters","com.azure.ai.agents.models.BingGroundingTool":"Azure.AI.Projects.BingGroundingTool","com.azure.ai.agents.models.BingGroundingToolCall":"Azure.AI.Projects.BingGroundingToolCall","com.azure.ai.agents.models.BingGroundingToolCallOutput":"Azure.AI.Projects.BingGroundingToolCallOutput","com.azure.ai.agents.models.BotServiceAuthorizationScheme":"Azure.AI.Projects.BotServiceAuthorizationScheme","com.azure.ai.agents.models.BotServiceRbacAuthorizationScheme":"Azure.AI.Projects.BotServiceRbacAuthorizationScheme","com.azure.ai.agents.models.BotServiceTenantAuthorizationScheme":"Azure.AI.Projects.BotServiceTenantAuthorizationScheme","com.azure.ai.agents.models.BrowserAutomationPreviewTool":"Azure.AI.Projects.BrowserAutomationPreviewTool","com.azure.ai.agents.models.BrowserAutomationPreviewToolboxTool":"Azure.AI.Projects.BrowserAutomationPreviewToolboxTool","com.azure.ai.agents.models.BrowserAutomationTool":"Azure.AI.Projects.BrowserAutomationTool","com.azure.ai.agents.models.BrowserAutomationToolCall":"Azure.AI.Projects.BrowserAutomationToolCall","com.azure.ai.agents.models.BrowserAutomationToolCallOutput":"Azure.AI.Projects.BrowserAutomationToolCallOutput","com.azure.ai.agents.models.BrowserAutomationToolConnectionParameters":"Azure.AI.Projects.BrowserAutomationToolConnectionParameters","com.azure.ai.agents.models.BrowserAutomationToolParameters":"Azure.AI.Projects.BrowserAutomationToolParameters","com.azure.ai.agents.models.BrowserAutomationToolboxTool":"Azure.AI.Projects.BrowserAutomationToolboxTool","com.azure.ai.agents.models.CallableToolAllowedCaller":"OpenAI.CallableToolAllowedCaller","com.azure.ai.agents.models.CaptureStructuredOutputsTool":"Azure.AI.Projects.CaptureStructuredOutputsTool","com.azure.ai.agents.models.ChatSummaryMemoryItem":"Azure.AI.Projects.ChatSummaryMemoryItem","com.azure.ai.agents.models.CodeConfiguration":"Azure.AI.Projects.CodeConfiguration","com.azure.ai.agents.models.CodeDependencyResolution":"Azure.AI.Projects.CodeDependencyResolution","com.azure.ai.agents.models.CodeFileDetails":null,"com.azure.ai.agents.models.CodeInterpreterTool":"OpenAI.ToolCodeInterpreterTool","com.azure.ai.agents.models.CodeInterpreterToolboxTool":"Azure.AI.Projects.CodeInterpreterToolboxTool","com.azure.ai.agents.models.ComputerEnvironment":"ComputerEnvironmentExpandable","com.azure.ai.agents.models.ComputerTool":"OpenAI.ToolComputerTool","com.azure.ai.agents.models.ComputerUsePreviewTool":"OpenAI.ToolComputerUsePreviewTool","com.azure.ai.agents.models.ContainerAutoParameter":"OpenAI.ContainerAutoParam","com.azure.ai.agents.models.ContainerConfiguration":"Azure.AI.Projects.ContainerConfiguration","com.azure.ai.agents.models.ContainerMemoryLimit":"ContainerMemoryLimitExpandable","com.azure.ai.agents.models.ContainerNetworkPolicyAllowlistParameter":"OpenAI.ContainerNetworkPolicyAllowlistParam","com.azure.ai.agents.models.ContainerNetworkPolicyDisabledParameter":"OpenAI.ContainerNetworkPolicyDisabledParam","com.azure.ai.agents.models.ContainerNetworkPolicyDomainSecretParameter":"OpenAI.ContainerNetworkPolicyDomainSecretParam","com.azure.ai.agents.models.ContainerNetworkPolicyParamType":"OpenAI.ContainerNetworkPolicyParamType","com.azure.ai.agents.models.ContainerNetworkPolicyParameter":"OpenAI.ContainerNetworkPolicyParam","com.azure.ai.agents.models.ContainerSkill":"OpenAI.ContainerSkill","com.azure.ai.agents.models.ContainerSkillType":"OpenAI.ContainerSkillType","com.azure.ai.agents.models.CreateAgentVersionFromCodeContent":"Azure.AI.Projects.CreateAgentVersionFromCodeContent","com.azure.ai.agents.models.CreateAgentVersionFromCodeMetadata":"Azure.AI.Projects.CreateAgentVersionFromCodeMetadata","com.azure.ai.agents.models.CreateAgentVersionInput":"Azure.AI.Projects.CreateAgentVersionRequest","com.azure.ai.agents.models.CreateAgentVersionOptions":null,"com.azure.ai.agents.models.CustomGrammarFormatParameter":"OpenAI.CustomGrammarFormatParam","com.azure.ai.agents.models.CustomTextFormatParameter":"OpenAI.CustomTextFormatParam","com.azure.ai.agents.models.CustomToolParamFormat":"OpenAI.CustomToolParamFormat","com.azure.ai.agents.models.CustomToolParamFormatType":"OpenAI.CustomToolParamFormatType","com.azure.ai.agents.models.CustomToolParameter":"OpenAI.ToolCustomToolParam","com.azure.ai.agents.models.DatasetReference":"Azure.AI.Projects.DatasetReference","com.azure.ai.agents.models.DigitalWorkerType":"Azure.AI.Projects.DigitalWorkerType","com.azure.ai.agents.models.EntraAuthorizationScheme":"Azure.AI.Projects.EntraAuthorizationScheme","com.azure.ai.agents.models.EvaluationAzureStandardVoiceModelConfiguration":"Azure.AI.Projects.EvaluationAzureStandardVoiceModelConfiguration","com.azure.ai.agents.models.EvaluationModelConfiguration":"Azure.AI.Projects.EvaluationModelConfiguration","com.azure.ai.agents.models.EvaluationVoiceModelConfiguration":"Azure.AI.Projects.EvaluationVoiceModelConfiguration","com.azure.ai.agents.models.ExternalAgentDefinition":"Azure.AI.Projects.ExternalAgentDefinition","com.azure.ai.agents.models.FabricDataAgentToolCall":"Azure.AI.Projects.FabricDataAgentToolCall","com.azure.ai.agents.models.FabricDataAgentToolCallOutput":"Azure.AI.Projects.FabricDataAgentToolCallOutput","com.azure.ai.agents.models.FabricDataAgentToolParameters":"Azure.AI.Projects.FabricDataAgentToolParameters","com.azure.ai.agents.models.FabricIqPreviewTool":"Azure.AI.Projects.FabricIQPreviewTool","com.azure.ai.agents.models.FabricIqPreviewToolboxTool":"Azure.AI.Projects.FabricIQPreviewToolboxTool","com.azure.ai.agents.models.FileSearchTool":"OpenAI.ToolFileSearchTool","com.azure.ai.agents.models.FileSearchToolboxTool":"Azure.AI.Projects.FileSearchToolboxTool","com.azure.ai.agents.models.FixedRatioVersionSelectionRule":"Azure.AI.Projects.FixedRatioVersionSelectionRule","com.azure.ai.agents.models.FunctionShellToolParamEnvironment":"OpenAI.FunctionShellToolParamEnvironment","com.azure.ai.agents.models.FunctionShellToolParamEnvironmentType":"OpenAI.FunctionShellToolParamEnvironmentType","com.azure.ai.agents.models.FunctionShellToolParameter":"OpenAI.ToolFunctionShellToolParam","com.azure.ai.agents.models.FunctionShellToolParameterEnvironmentContainerReferenceParameter":"OpenAI.FunctionShellToolParamEnvironmentContainerReferenceParam","com.azure.ai.agents.models.FunctionShellToolParameterEnvironmentLocalEnvironmentParameter":"OpenAI.FunctionShellToolParamEnvironmentLocalEnvironmentParam","com.azure.ai.agents.models.FunctionTool":"OpenAI.ToolFunctionTool","com.azure.ai.agents.models.GetMicrosoft365AppPackageOptions":null,"com.azure.ai.agents.models.GitHubCopilotBuiltInTool":"Azure.AI.Projects.GitHubCopilotBuiltInTool","com.azure.ai.agents.models.GitHubCopilotHarness":"Azure.AI.Projects.GitHubCopilotHarness","com.azure.ai.agents.models.GitHubCopilotToolsetConfig":"Azure.AI.Projects.GitHubCopilotToolsetConfig","com.azure.ai.agents.models.GitHubCopilotToolsetDefaultConfig":"Azure.AI.Projects.GitHubCopilotToolsetDefaultConfig","com.azure.ai.agents.models.GitHubCopilotToolsetPreview":"Azure.AI.Projects.GitHubCopilotToolsetPreview","com.azure.ai.agents.models.GrammarSyntax":"GrammarSyntaxExpandable","com.azure.ai.agents.models.HeaderTelemetryEndpointAuth":"Azure.AI.Projects.HeaderTelemetryEndpointAuth","com.azure.ai.agents.models.HostedAgentDefinition":"Azure.AI.Projects.HostedAgentDefinition","com.azure.ai.agents.models.HybridSearchOptions":"OpenAI.HybridSearchOptions","com.azure.ai.agents.models.ImageGenActionEnum":"ImageGenActionEnumExpandable","com.azure.ai.agents.models.ImageGenTool":"OpenAI.ToolImageGenTool","com.azure.ai.agents.models.ImageGenToolBackground":"ImageGenToolBackgroundExpandable","com.azure.ai.agents.models.ImageGenToolInputImageMask":"OpenAI.ImageGenToolInputImageMask","com.azure.ai.agents.models.ImageGenToolModel":"OpenAI.ToolImageGenTool.model.anonymous","com.azure.ai.agents.models.ImageGenToolModeration":"ImageGenToolModerationExpandable","com.azure.ai.agents.models.ImageGenToolOutputFormat":"ImageGenToolOutputFormatExpandable","com.azure.ai.agents.models.ImageGenToolQuality":"ImageGenToolQualityExpandable","com.azure.ai.agents.models.ImageGenToolSize":"ImageGenToolSizeExpandable","com.azure.ai.agents.models.IncludeEnum":"OpenAI.IncludeEnum","com.azure.ai.agents.models.InlineSkillParameter":"OpenAI.InlineSkillParam","com.azure.ai.agents.models.InlineSkillSourceParameter":"OpenAI.InlineSkillSourceParam","com.azure.ai.agents.models.InlineVoiceSubagent":"Azure.AI.Projects.InlineVoiceSubagent","com.azure.ai.agents.models.InputFidelity":"InputFidelityExpandable","com.azure.ai.agents.models.InvocationsProtocolConfiguration":"Azure.AI.Projects.InvocationsProtocolConfiguration","com.azure.ai.agents.models.InvocationsWsProtocolConfiguration":"Azure.AI.Projects.InvocationsWsProtocolConfiguration","com.azure.ai.agents.models.JobStatus":"Azure.AI.Projects.JobStatus","com.azure.ai.agents.models.ListMemoriesOptions":null,"com.azure.ai.agents.models.LocalShellToolParameter":"OpenAI.ToolLocalShellToolParam","com.azure.ai.agents.models.LocalSkillParameter":"OpenAI.LocalSkillParam","com.azure.ai.agents.models.ManagedAgentIdentityBlueprintReference":"Azure.AI.Projects.ManagedAgentIdentityBlueprintReference","com.azure.ai.agents.models.McpProtocolConfiguration":"Azure.AI.Projects.McpProtocolConfiguration","com.azure.ai.agents.models.McpTool":"OpenAI.ToolMcpTool","com.azure.ai.agents.models.McpToolConnectorId":"McpToolConnectorIdExpandable","com.azure.ai.agents.models.McpToolFilter":"OpenAI.MCPToolFilter","com.azure.ai.agents.models.McpToolRequireApproval":"OpenAI.MCPToolRequireApproval","com.azure.ai.agents.models.McpToolboxTool":"Azure.AI.Projects.MCPToolboxTool","com.azure.ai.agents.models.MemoryCommandToolCall":"Azure.AI.Projects.MemoryCommandToolCall","com.azure.ai.agents.models.MemoryCommandToolCallOutput":"Azure.AI.Projects.MemoryCommandToolCallOutput","com.azure.ai.agents.models.MemoryItem":"Azure.AI.Projects.MemoryItem","com.azure.ai.agents.models.MemoryItemKind":"Azure.AI.Projects.MemoryItemKind","com.azure.ai.agents.models.MemoryOperation":"Azure.AI.Projects.MemoryOperation","com.azure.ai.agents.models.MemoryOperationKind":"Azure.AI.Projects.MemoryOperationKind","com.azure.ai.agents.models.MemorySearchItem":"Azure.AI.Projects.MemorySearchItem","com.azure.ai.agents.models.MemorySearchOptions":"Azure.AI.Projects.MemorySearchOptions","com.azure.ai.agents.models.MemorySearchPreviewTool":"Azure.AI.Projects.MemorySearchPreviewTool","com.azure.ai.agents.models.MemorySearchToolCall":"Azure.AI.Projects.MemorySearchToolCall","com.azure.ai.agents.models.MemoryStoreDefaultDefinition":"Azure.AI.Projects.MemoryStoreDefaultDefinition","com.azure.ai.agents.models.MemoryStoreDefaultOptions":"Azure.AI.Projects.MemoryStoreDefaultOptions","com.azure.ai.agents.models.MemoryStoreDefinition":"Azure.AI.Projects.MemoryStoreDefinition","com.azure.ai.agents.models.MemoryStoreDetails":"Azure.AI.Projects.MemoryStoreObject","com.azure.ai.agents.models.MemoryStoreKind":"Azure.AI.Projects.MemoryStoreKind","com.azure.ai.agents.models.MemoryStoreObjectType":"Azure.AI.Projects.MemoryStoreObjectType","com.azure.ai.agents.models.MemoryStoreOperationUsage":"Azure.AI.Projects.MemoryStoreOperationUsage","com.azure.ai.agents.models.MemoryStoreSearchResponse":"Azure.AI.Projects.MemoryStoreSearchResponse","com.azure.ai.agents.models.MemoryStoreUpdateCompletedResult":"Azure.AI.Projects.MemoryStoreUpdateCompletedResult","com.azure.ai.agents.models.MemoryStoreUpdateResponse":"Azure.AI.Projects.MemoryStoreUpdateResponse","com.azure.ai.agents.models.MemoryStoreUpdateStatus":"Azure.AI.Projects.MemoryStoreUpdateStatus","com.azure.ai.agents.models.Microsoft365PermissionScopes":"Azure.AI.Projects.Microsoft365PermissionScopes","com.azure.ai.agents.models.Microsoft365PublishDefaults":"Azure.AI.Projects.Microsoft365PublishDefaults","com.azure.ai.agents.models.Microsoft365PublishResult":"Azure.AI.Projects.Microsoft365PublishResponse","com.azure.ai.agents.models.Microsoft365PublishScope":"Azure.AI.Projects.Microsoft365PublishScope","com.azure.ai.agents.models.MicrosoftCopilotBuiltInTool":"Azure.AI.Projects.MicrosoftCopilotBuiltInTool","com.azure.ai.agents.models.MicrosoftCopilotHarness":"Azure.AI.Projects.MicrosoftCopilotHarness","com.azure.ai.agents.models.MicrosoftCopilotToolsetConfiguration":"Azure.AI.Projects.MicrosoftCopilotToolsetConfig","com.azure.ai.agents.models.MicrosoftCopilotToolsetDefaultConfiguration":"Azure.AI.Projects.MicrosoftCopilotToolsetDefaultConfig","com.azure.ai.agents.models.MicrosoftCopilotToolsetPreview":"Azure.AI.Projects.MicrosoftCopilotToolsetPreview","com.azure.ai.agents.models.MicrosoftFabricPreviewTool":"Azure.AI.Projects.MicrosoftFabricPreviewTool","com.azure.ai.agents.models.ModelRouterAttempt":"Azure.AI.Projects.ModelRouterAttempt","com.azure.ai.agents.models.ModelRouterAttemptError":"Azure.AI.Projects.ModelRouterAttemptError","com.azure.ai.agents.models.ModelRouterAttemptResult":"Azure.AI.Projects.ModelRouterAttemptResult","com.azure.ai.agents.models.ModelRouterDetails":"Azure.AI.Projects.ModelRouterDetails","com.azure.ai.agents.models.ModelRouterMode":"Azure.AI.Projects.ModelRouterMode","com.azure.ai.agents.models.ModelSamplingParameters":"Azure.AI.Projects.ModelSamplingParams","com.azure.ai.agents.models.ModelSelectionDetails":"Azure.AI.Projects.ModelSelectionDetails","com.azure.ai.agents.models.NamespaceTool":"OpenAI.NamespaceToolParam","com.azure.ai.agents.models.OpenApiAnonymousAuthDetails":"Azure.AI.Projects.OpenApiAnonymousAuthDetails","com.azure.ai.agents.models.OpenApiAuthDetails":"Azure.AI.Projects.OpenApiAuthDetails","com.azure.ai.agents.models.OpenApiAuthType":"Azure.AI.Projects.OpenApiAuthType","com.azure.ai.agents.models.OpenApiFunctionDefinition":"Azure.AI.Projects.OpenApiFunctionDefinition","com.azure.ai.agents.models.OpenApiFunctionDefinitionFunction":"Azure.AI.Projects.OpenApiFunctionDefinition.function.anonymous","com.azure.ai.agents.models.OpenApiManagedAuthDetails":"Azure.AI.Projects.OpenApiManagedAuthDetails","com.azure.ai.agents.models.OpenApiManagedSecurityScheme":"Azure.AI.Projects.OpenApiManagedSecurityScheme","com.azure.ai.agents.models.OpenApiProjectConnectionAuthDetails":"Azure.AI.Projects.OpenApiProjectConnectionAuthDetails","com.azure.ai.agents.models.OpenApiProjectConnectionSecurityScheme":"Azure.AI.Projects.OpenApiProjectConnectionSecurityScheme","com.azure.ai.agents.models.OpenApiTool":"Azure.AI.Projects.OpenApiTool","com.azure.ai.agents.models.OpenApiToolCall":"Azure.AI.Projects.OpenApiToolCall","com.azure.ai.agents.models.OpenApiToolCallOutput":"Azure.AI.Projects.OpenApiToolCallOutput","com.azure.ai.agents.models.OpenApiToolboxTool":"Azure.AI.Projects.OpenApiToolboxTool","com.azure.ai.agents.models.OptimizationContext":"Azure.AI.Projects.OptimizationContext","com.azure.ai.agents.models.OptimizationContextType":"Azure.AI.Projects.OptimizationContextType","com.azure.ai.agents.models.OtlpTelemetryEndpoint":"Azure.AI.Projects.OtlpTelemetryEndpoint","com.azure.ai.agents.models.PageOrder":"Azure.AI.Projects.PageOrder","com.azure.ai.agents.models.ProceduralMemoryItem":"Azure.AI.Projects.ProceduralMemoryItem","com.azure.ai.agents.models.ProgrammaticToolCallingParameter":"OpenAI.ToolProgrammaticToolCallingParam","com.azure.ai.agents.models.PromptAgentDefinition":"Azure.AI.Projects.PromptAgentDefinition","com.azure.ai.agents.models.PromptAgentDefinitionTextOptions":"Azure.AI.Projects.PromptAgentDefinitionTextOptions","com.azure.ai.agents.models.PromptOptimizationConfiguration":"Azure.AI.Projects.PromptOptimizationConfiguration","com.azure.ai.agents.models.ProtocolConfiguration":"Azure.AI.Projects.ProtocolConfiguration","com.azure.ai.agents.models.ProtocolVersionRecord":"Azure.AI.Projects.ProtocolVersionRecord","com.azure.ai.agents.models.PublishAgentToMicrosoft365Options":null,"com.azure.ai.agents.models.PublishApprovalStatus":"Azure.AI.Projects.PublishApprovalStatus","com.azure.ai.agents.models.RaiConfig":"Azure.AI.Projects.RaiConfig","com.azure.ai.agents.models.RaiInvocationContentType":"Azure.AI.Projects.RaiInvocationContentType","com.azure.ai.agents.models.RaiInvocationModeration":"Azure.AI.Projects.RaiInvocationModeration","com.azure.ai.agents.models.RaiInvocationResponseMode":"Azure.AI.Projects.RaiInvocationMode","com.azure.ai.agents.models.RaiSseTextSelector":"Azure.AI.Projects.RaiSseTextSelector","com.azure.ai.agents.models.RankerVersionType":"RankerVersionTypeExpandable","com.azure.ai.agents.models.RankingOptions":"OpenAI.RankingOptions","com.azure.ai.agents.models.RealtimeClientEvent":"OpenAI.RealtimeClientEvent","com.azure.ai.agents.models.RealtimeClientEventType":"OpenAI.RealtimeClientEventType","com.azure.ai.agents.models.RealtimeConversationCreatedEvent":"OpenAI.RealtimeServerEventConversationCreated","com.azure.ai.agents.models.RealtimeConversationItem":"OpenAI.RealtimeConversationItem","com.azure.ai.agents.models.RealtimeConversationItemAddedEvent":"OpenAI.RealtimeServerEventConversationItemAdded","com.azure.ai.agents.models.RealtimeConversationItemAssistantMessage":"OpenAI.RealtimeConversationItemMessageAssistant","com.azure.ai.agents.models.RealtimeConversationItemCreateEvent":"OpenAI.RealtimeClientEventConversationItemCreate","com.azure.ai.agents.models.RealtimeConversationItemCreatedEvent":"OpenAI.RealtimeServerEventConversationItemCreated","com.azure.ai.agents.models.RealtimeConversationItemDeleteEvent":"OpenAI.RealtimeClientEventConversationItemDelete","com.azure.ai.agents.models.RealtimeConversationItemDeletedEvent":"OpenAI.RealtimeServerEventConversationItemDeleted","com.azure.ai.agents.models.RealtimeConversationItemDoneEvent":"OpenAI.RealtimeServerEventConversationItemDone","com.azure.ai.agents.models.RealtimeConversationItemFunctionCall":"OpenAI.RealtimeConversationItemFunctionCall","com.azure.ai.agents.models.RealtimeConversationItemFunctionCallOutput":"OpenAI.RealtimeConversationItemFunctionCallOutput","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionCompletedEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionDeltaEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionDelta","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionFailedEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailed","com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionSegmentEvent":"OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionSegment","com.azure.ai.agents.models.RealtimeConversationItemMessage":"OpenAI.RealtimeConversationItemMessage","com.azure.ai.agents.models.RealtimeConversationItemMessageType":"OpenAI.RealtimeConversationItemMessageType","com.azure.ai.agents.models.RealtimeConversationItemObjectType":"RealtimeConversationItemObject","com.azure.ai.agents.models.RealtimeConversationItemRetrieveEvent":"OpenAI.RealtimeClientEventConversationItemRetrieve","com.azure.ai.agents.models.RealtimeConversationItemRetrievedEvent":"OpenAI.RealtimeServerEventConversationItemRetrieved","com.azure.ai.agents.models.RealtimeConversationItemSystemMessage":"OpenAI.RealtimeConversationItemMessageSystem","com.azure.ai.agents.models.RealtimeConversationItemTruncateEvent":"OpenAI.RealtimeClientEventConversationItemTruncate","com.azure.ai.agents.models.RealtimeConversationItemTruncatedEvent":"OpenAI.RealtimeServerEventConversationItemTruncated","com.azure.ai.agents.models.RealtimeConversationItemType":"OpenAI.RealtimeConversationItemType","com.azure.ai.agents.models.RealtimeConversationItemUserMessage":"OpenAI.RealtimeConversationItemMessageUser","com.azure.ai.agents.models.RealtimeErrorEvent":"OpenAI.RealtimeServerEventRealtimeServerEventError","com.azure.ai.agents.models.RealtimeInputAudioBufferAppendEvent":"OpenAI.RealtimeClientEventInputAudioBufferAppend","com.azure.ai.agents.models.RealtimeInputAudioBufferClearEvent":"OpenAI.RealtimeClientEventInputAudioBufferClear","com.azure.ai.agents.models.RealtimeInputAudioBufferClearedEvent":"OpenAI.RealtimeServerEventInputAudioBufferCleared","com.azure.ai.agents.models.RealtimeInputAudioBufferCommitEvent":"OpenAI.RealtimeClientEventInputAudioBufferCommit","com.azure.ai.agents.models.RealtimeInputAudioBufferCommittedEvent":"OpenAI.RealtimeServerEventInputAudioBufferCommitted","com.azure.ai.agents.models.RealtimeInputAudioBufferDtmfReceivedEvent":"OpenAI.RealtimeServerEventInputAudioBufferDtmfEventReceived","com.azure.ai.agents.models.RealtimeInputAudioBufferSpeechStartedEvent":"OpenAI.RealtimeServerEventInputAudioBufferSpeechStarted","com.azure.ai.agents.models.RealtimeInputAudioBufferSpeechStoppedEvent":"OpenAI.RealtimeServerEventInputAudioBufferSpeechStopped","com.azure.ai.agents.models.RealtimeInputAudioBufferTimeoutTriggeredEvent":"OpenAI.RealtimeServerEventInputAudioBufferTimeoutTriggered","com.azure.ai.agents.models.RealtimeMcpApprovalInput":"OpenAI.RealtimeMCPApprovalRequest","com.azure.ai.agents.models.RealtimeMcpApprovalOutput":"OpenAI.RealtimeMCPApprovalResponse","com.azure.ai.agents.models.RealtimeMcpListTools":"OpenAI.RealtimeMCPListTools","com.azure.ai.agents.models.RealtimeMcpListToolsCompletedEvent":"OpenAI.RealtimeServerEventMCPListToolsCompleted","com.azure.ai.agents.models.RealtimeMcpListToolsFailedEvent":"OpenAI.RealtimeServerEventMCPListToolsFailed","com.azure.ai.agents.models.RealtimeMcpListToolsInProgressEvent":"OpenAI.RealtimeServerEventMCPListToolsInProgress","com.azure.ai.agents.models.RealtimeMcpToolCall":"OpenAI.RealtimeMCPToolCall","com.azure.ai.agents.models.RealtimeOutputAudioBufferClearEvent":"OpenAI.RealtimeClientEventOutputAudioBufferClear","com.azure.ai.agents.models.RealtimeOutputAudioBufferClearedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferCleared","com.azure.ai.agents.models.RealtimeOutputAudioBufferStartedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferStarted","com.azure.ai.agents.models.RealtimeOutputAudioBufferStoppedEvent":"OpenAI.RealtimeServerEventOutputAudioBufferStopped","com.azure.ai.agents.models.RealtimeRateLimitsUpdatedEvent":"OpenAI.RealtimeServerEventRateLimitsUpdated","com.azure.ai.agents.models.RealtimeResponseAudioDeltaEvent":"OpenAI.RealtimeServerEventResponseAudioDelta","com.azure.ai.agents.models.RealtimeResponseAudioDoneEvent":"OpenAI.RealtimeServerEventResponseAudioDone","com.azure.ai.agents.models.RealtimeResponseAudioTranscriptDeltaEvent":"OpenAI.RealtimeServerEventResponseAudioTranscriptDelta","com.azure.ai.agents.models.RealtimeResponseAudioTranscriptDoneEvent":"OpenAI.RealtimeServerEventResponseAudioTranscriptDone","com.azure.ai.agents.models.RealtimeResponseCancelEvent":"OpenAI.RealtimeClientEventResponseCancel","com.azure.ai.agents.models.RealtimeResponseContentPart":"OpenAI.RealtimeServerEventResponseContentPartDonePart","com.azure.ai.agents.models.RealtimeResponseContentPartAddedEvent":"OpenAI.RealtimeServerEventResponseContentPartAdded","com.azure.ai.agents.models.RealtimeResponseContentPartDoneEvent":"OpenAI.RealtimeServerEventResponseContentPartDone","com.azure.ai.agents.models.RealtimeResponseCreateEvent":"OpenAI.RealtimeClientEventResponseCreate","com.azure.ai.agents.models.RealtimeResponseCreatedEvent":"OpenAI.RealtimeServerEventResponseCreated","com.azure.ai.agents.models.RealtimeResponseDoneEvent":"OpenAI.RealtimeServerEventResponseDone","com.azure.ai.agents.models.RealtimeResponseFunctionCallArgumentsDeltaEvent":"OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDelta","com.azure.ai.agents.models.RealtimeResponseFunctionCallArgumentsDoneEvent":"OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDone","com.azure.ai.agents.models.RealtimeResponseInputAudio":"OpenAI.RealtimeResponseInputAudio","com.azure.ai.agents.models.RealtimeResponseInputFunctionCall":"OpenAI.RealtimeResponseInputFunctionCall","com.azure.ai.agents.models.RealtimeResponseInputFunctionCallOutput":"OpenAI.RealtimeResponseInputFunctionCallOutput","com.azure.ai.agents.models.RealtimeResponseInputImage":"OpenAI.RealtimeResponseInputImage","com.azure.ai.agents.models.RealtimeResponseInputItemStatus":"OpenAI.RealtimeResponseInputMessageSystem.status.anonymous","com.azure.ai.agents.models.RealtimeResponseInputMessage":"OpenAI.RealtimeResponseInputMessage","com.azure.ai.agents.models.RealtimeResponseInputMessageAssistant":"OpenAI.RealtimeResponseInputMessageAssistant","com.azure.ai.agents.models.RealtimeResponseInputMessageAssistantContent":"OpenAI.RealtimeResponseInputMessageAssistantContent","com.azure.ai.agents.models.RealtimeResponseInputMessageDeveloper":"OpenAI.RealtimeResponseInputMessageDeveloper","com.azure.ai.agents.models.RealtimeResponseInputMessageSystem":"OpenAI.RealtimeResponseInputMessageSystem","com.azure.ai.agents.models.RealtimeResponseInputMessageType":"OpenAI.RealtimeResponseInputMessageType","com.azure.ai.agents.models.RealtimeResponseInputMessageUser":"OpenAI.RealtimeResponseInputMessageUser","com.azure.ai.agents.models.RealtimeResponseInputText":"OpenAI.RealtimeResponseInputText","com.azure.ai.agents.models.RealtimeResponseItemReference":"OpenAI.RealtimeResponseItemReference","com.azure.ai.agents.models.RealtimeResponseMcpCallArgumentsDeltaEvent":"OpenAI.RealtimeServerEventResponseMCPCallArgumentsDelta","com.azure.ai.agents.models.RealtimeResponseMcpCallArgumentsDoneEvent":"OpenAI.RealtimeServerEventResponseMCPCallArgumentsDone","com.azure.ai.agents.models.RealtimeResponseMcpCallCompletedEvent":"OpenAI.RealtimeServerEventResponseMCPCallCompleted","com.azure.ai.agents.models.RealtimeResponseMcpCallFailedEvent":"OpenAI.RealtimeServerEventResponseMCPCallFailed","com.azure.ai.agents.models.RealtimeResponseMcpCallInProgressEvent":"OpenAI.RealtimeServerEventResponseMCPCallInProgress","com.azure.ai.agents.models.RealtimeResponseOutputItemAddedEvent":"OpenAI.RealtimeServerEventResponseOutputItemAdded","com.azure.ai.agents.models.RealtimeResponseOutputItemDoneEvent":"OpenAI.RealtimeServerEventResponseOutputItemDone","com.azure.ai.agents.models.RealtimeResponseTextDeltaEvent":"OpenAI.RealtimeServerEventResponseTextDelta","com.azure.ai.agents.models.RealtimeResponseTextDoneEvent":"OpenAI.RealtimeServerEventResponseTextDone","com.azure.ai.agents.models.RealtimeServerEvent":"OpenAI.RealtimeServerEvent","com.azure.ai.agents.models.RealtimeServerEventType":"OpenAI.RealtimeServerEventType","com.azure.ai.agents.models.RealtimeSessionCreatedEvent":"OpenAI.RealtimeServerEventSessionCreated","com.azure.ai.agents.models.RealtimeSessionUpdateEvent":"OpenAI.RealtimeClientEventSessionUpdate","com.azure.ai.agents.models.RealtimeSessionUpdatedEvent":"OpenAI.RealtimeServerEventSessionUpdated","com.azure.ai.agents.models.ReminderPreviewToolboxTool":"Azure.AI.Projects.ReminderPreviewToolboxTool","com.azure.ai.agents.models.ResponseFormatJsonSchemaInner":"OpenAI.ResponseFormatJsonSchemaSchema","com.azure.ai.agents.models.ResponseUsageInputTokensDetails":"OpenAI.ResponseUsageInputTokensDetails","com.azure.ai.agents.models.ResponseUsageOutputTokensDetails":"OpenAI.ResponseUsageOutputTokensDetails","com.azure.ai.agents.models.ResponsesProtocolConfiguration":"Azure.AI.Projects.ResponsesProtocolConfiguration","com.azure.ai.agents.models.RoutingConfiguration":"Azure.AI.Projects.RoutingConfiguration","com.azure.ai.agents.models.RoutingTraceEntry":"Azure.AI.Projects.RoutingTraceEntry","com.azure.ai.agents.models.SearchContentType":"OpenAI.SearchContentType","com.azure.ai.agents.models.SearchContextSize":"SearchContextSizeExpandable","com.azure.ai.agents.models.SessionAffinityConfiguration":"Azure.AI.Projects.SessionAffinityConfiguration","com.azure.ai.agents.models.SessionAffinityDecision":"Azure.AI.Projects.SessionAffinityDecision","com.azure.ai.agents.models.SessionAffinityDetails":"Azure.AI.Projects.SessionAffinityDetails","com.azure.ai.agents.models.SessionAffinityMode":"Azure.AI.Projects.SessionAffinityMode","com.azure.ai.agents.models.SessionAffinityRequestMode":"Azure.AI.Projects.SessionAffinityRequestMode","com.azure.ai.agents.models.SessionAffinitySource":"Azure.AI.Projects.SessionAffinitySource","com.azure.ai.agents.models.SessionConfiguration":"Azure.AI.Projects.SessionConfiguration","com.azure.ai.agents.models.SessionDirectoryEntry":"Azure.AI.Projects.SessionDirectoryEntry","com.azure.ai.agents.models.SessionFileWriteResult":"Azure.AI.Projects.SessionFileWriteResponse","com.azure.ai.agents.models.SessionLogEvent":"Azure.AI.Projects.SessionLogEvent","com.azure.ai.agents.models.SessionLogEventType":"Azure.AI.Projects.SessionLogEventType","com.azure.ai.agents.models.SharepointGroundingToolCall":"Azure.AI.Projects.SharepointGroundingToolCall","com.azure.ai.agents.models.SharepointGroundingToolCallOutput":"Azure.AI.Projects.SharepointGroundingToolCallOutput","com.azure.ai.agents.models.SharepointGroundingToolParameters":"Azure.AI.Projects.SharepointGroundingToolParameters","com.azure.ai.agents.models.SharepointPreviewTool":"Azure.AI.Projects.SharepointPreviewTool","com.azure.ai.agents.models.ShellToolboxTool":"Azure.AI.Projects.ShellToolboxTool","com.azure.ai.agents.models.SipTelephonyBinding":"Azure.AI.Projects.SipTelephonyBinding","com.azure.ai.agents.models.SipTelephonyBindingListItem":"Azure.AI.Projects.SipTelephonyBindingListItem","com.azure.ai.agents.models.SkillReference":"Azure.AI.Projects.SkillReference","com.azure.ai.agents.models.SkillReferenceParameter":"OpenAI.SkillReferenceParam","com.azure.ai.agents.models.SteeringPromptOptimizationContext":"Azure.AI.Projects.SteeringPromptOptimizationContext","com.azure.ai.agents.models.StructuredInputDefinition":"Azure.AI.Projects.StructuredInputDefinition","com.azure.ai.agents.models.StructuredOutputDefinition":"Azure.AI.Projects.StructuredOutputDefinition","com.azure.ai.agents.models.TargetAttribute":"Azure.AI.Projects.TargetAttribute","com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBinding":"Azure.AI.Projects.TeamsPhoneExtensibilityTelephonyBinding","com.azure.ai.agents.models.TeamsPhoneExtensibilityTelephonyBindingListItem":"Azure.AI.Projects.TeamsPhoneExtensibilityTelephonyBindingListItem","com.azure.ai.agents.models.TelemetryConfig":"Azure.AI.Projects.TelemetryConfig","com.azure.ai.agents.models.TelemetryDataKind":"Azure.AI.Projects.TelemetryDataKind","com.azure.ai.agents.models.TelemetryEndpoint":"Azure.AI.Projects.TelemetryEndpoint","com.azure.ai.agents.models.TelemetryEndpointAuth":"Azure.AI.Projects.TelemetryEndpointAuth","com.azure.ai.agents.models.TelemetryEndpointAuthType":"Azure.AI.Projects.TelemetryEndpointAuthType","com.azure.ai.agents.models.TelemetryEndpointKind":"Azure.AI.Projects.TelemetryEndpointKind","com.azure.ai.agents.models.TelemetryTransportProtocol":"Azure.AI.Projects.TelemetryTransportProtocol","com.azure.ai.agents.models.TelephonyAddress":"Azure.AI.Projects.TelephonyAddress","com.azure.ai.agents.models.TelephonyAddressType":"Azure.AI.Projects.TelephonyAddressType","com.azure.ai.agents.models.TelephonyBinding":"Azure.AI.Projects.TelephonyBinding","com.azure.ai.agents.models.TelephonyBindingListItem":"Azure.AI.Projects.TelephonyBindingListItem","com.azure.ai.agents.models.TelephonyCallDurationBasis":"Azure.AI.Projects.TelephonyCallDurationBasis","com.azure.ai.agents.models.TelephonyCallEndReason":"Azure.AI.Projects.TelephonyCallEndReason","com.azure.ai.agents.models.TelephonyCallJob":"Azure.AI.Projects.TelephonyCallJob","com.azure.ai.agents.models.TelephonyCallJobCancellation":"Azure.AI.Projects.TelephonyCallJobCancellation","com.azure.ai.agents.models.TelephonyCallJobCreate":"Azure.AI.Projects.TelephonyCallJobCreate","com.azure.ai.agents.models.TelephonyCallJobSchedule":"Azure.AI.Projects.TelephonyCallJobSchedule","com.azure.ai.agents.models.TelephonyCallJobStatus":"Azure.AI.Projects.TelephonyCallJobStatus","com.azure.ai.agents.models.TelephonyCallJobTerminalReason":"Azure.AI.Projects.TelephonyCallJobTerminalReason","com.azure.ai.agents.models.TelephonyCallLifecycleEvent":"Azure.AI.Projects.TelephonyCallLifecycleEvent","com.azure.ai.agents.models.TelephonyCallLifecycleEventName":"Azure.AI.Projects.TelephonyCallLifecycleEventName","com.azure.ai.agents.models.TelephonyCallLifecycleEventOutcome":"Azure.AI.Projects.TelephonyCallLifecycleEventOutcome","com.azure.ai.agents.models.TelephonyCallLifecycleEventReason":"Azure.AI.Projects.TelephonyCallLifecycleEventReason","com.azure.ai.agents.models.TelephonyCallLifecycleEventSource":"Azure.AI.Projects.TelephonyCallLifecycleEventSource","com.azure.ai.agents.models.TelephonyCallPhase":"Azure.AI.Projects.TelephonyCallPhase","com.azure.ai.agents.models.TelephonyCallRecord":"Azure.AI.Projects.TelephonyCallRecord","com.azure.ai.agents.models.TelephonyCallStatus":"Azure.AI.Projects.TelephonyCallStatus","com.azure.ai.agents.models.TelephonyCallSummary":"Azure.AI.Projects.TelephonyCallSummary","com.azure.ai.agents.models.TelephonyCallTimestampSource":"Azure.AI.Projects.TelephonyCallTimestampSource","com.azure.ai.agents.models.TelephonyCallTiming":"Azure.AI.Projects.TelephonyCallTiming","com.azure.ai.agents.models.TelephonyCallTrace":"Azure.AI.Projects.TelephonyCallTrace","com.azure.ai.agents.models.TelephonyCallTraceMode":"Azure.AI.Projects.TelephonyCallTraceMode","com.azure.ai.agents.models.TelephonyCallTraceStatus":"Azure.AI.Projects.TelephonyCallTraceStatus","com.azure.ai.agents.models.TelephonyCampaign":"Azure.AI.Projects.TelephonyCampaign","com.azure.ai.agents.models.TelephonyCampaignAtTimeSchedule":"Azure.AI.Projects.AtTimeSchedule","com.azure.ai.agents.models.TelephonyCampaignImmediateSchedule":"Azure.AI.Projects.ImmediateSchedule","com.azure.ai.agents.models.TelephonyCampaignOperation":"Azure.AI.Projects.TelephonyCampaignOperation","com.azure.ai.agents.models.TelephonyCampaignOperationKind":"Azure.AI.Projects.TelephonyCampaignOperationKind","com.azure.ai.agents.models.TelephonyCampaignPerRecipientSchedule":"Azure.AI.Projects.PerRecipientSchedule","com.azure.ai.agents.models.TelephonyCampaignProgress":"Azure.AI.Projects.TelephonyCampaignProgress","com.azure.ai.agents.models.TelephonyCampaignSchedule":"Azure.AI.Projects.TelephonyCampaignSchedule","com.azure.ai.agents.models.TelephonyCampaignScheduleType":"Azure.AI.Projects.TelephonyCampaignScheduleType","com.azure.ai.agents.models.TelephonyCampaignStatus":"Azure.AI.Projects.TelephonyCampaignStatus","com.azure.ai.agents.models.TelephonyCampaignValidationError":"Azure.AI.Projects.TelephonyCampaignValidationError","com.azure.ai.agents.models.TelephonyFixedIntervalRetryPolicy":"Azure.AI.Projects.FixedIntervalRetryPolicy","com.azure.ai.agents.models.TelephonyOutboundRetryPolicy":"Azure.AI.Projects.TelephonyOutboundRetryPolicy","com.azure.ai.agents.models.TelephonyOutboundRetryPolicyType":"Azure.AI.Projects.TelephonyOutboundRetryPolicyType","com.azure.ai.agents.models.TelephonyPhoneNumber":"Azure.AI.Projects.PhoneNumber","com.azure.ai.agents.models.TelephonyProvider":"Azure.AI.Projects.TelephonyProvider","com.azure.ai.agents.models.TelephonyRecipient":"Azure.AI.Projects.TelephonyRecipient","com.azure.ai.agents.models.TelephonySipAddress":"Azure.AI.Projects.SipAddress","com.azure.ai.agents.models.TelephonyTeamsAddress":"Azure.AI.Projects.TeamsAddress","com.azure.ai.agents.models.TelephonyTransferTarget":"Azure.AI.Projects.TelephonyTransferTarget","com.azure.ai.agents.models.TelephonyTransferTargets":"Azure.AI.Projects.TelephonyTransferTargets","com.azure.ai.agents.models.TextResponseFormatConfiguration":"OpenAI.TextResponseFormatConfiguration","com.azure.ai.agents.models.TextResponseFormatConfigurationResponseFormatJsonObject":"OpenAI.TextResponseFormatConfigurationResponseFormatJsonObject","com.azure.ai.agents.models.TextResponseFormatConfigurationResponseFormatText":"OpenAI.TextResponseFormatConfigurationResponseFormatText","com.azure.ai.agents.models.TextResponseFormatConfigurationType":"OpenAI.TextResponseFormatConfigurationType","com.azure.ai.agents.models.TextResponseFormatJsonSchema":"OpenAI.TextResponseFormatJsonSchema","com.azure.ai.agents.models.Tool":"OpenAI.Tool","com.azure.ai.agents.models.ToolCallStatus":"Azure.AI.Projects.ToolCallStatus","com.azure.ai.agents.models.ToolConfig":"Azure.AI.Projects.ToolConfig","com.azure.ai.agents.models.ToolFunctionToolType3":null,"com.azure.ai.agents.models.ToolProjectConnection":"Azure.AI.Projects.ToolProjectConnection","com.azure.ai.agents.models.ToolSearchExecutionType":"OpenAI.ToolSearchExecutionType","com.azure.ai.agents.models.ToolSearchTool":"OpenAI.ToolToolSearchToolParam","com.azure.ai.agents.models.ToolSearchToolboxTool":"Azure.AI.Projects.ToolSearchToolboxTool","com.azure.ai.agents.models.ToolType":"OpenAI.ToolType","com.azure.ai.agents.models.ToolboxDetails":"Azure.AI.Projects.ToolboxObject","com.azure.ai.agents.models.ToolboxPolicies":"Azure.AI.Projects.ToolboxPolicies","com.azure.ai.agents.models.ToolboxSearchPreviewToolboxTool":"Azure.AI.Projects.ToolboxSearchPreviewToolboxTool","com.azure.ai.agents.models.ToolboxShellContainerAutoEnvironment":"Azure.AI.Projects.ToolboxShellContainerAutoEnvironment","com.azure.ai.agents.models.ToolboxShellContainerReferenceEnvironment":"Azure.AI.Projects.ToolboxShellContainerReferenceEnvironment","com.azure.ai.agents.models.ToolboxShellEnvironment":"Azure.AI.Projects.ToolboxShellEnvironment","com.azure.ai.agents.models.ToolboxShellNetworkPolicy":"Azure.AI.Projects.ToolboxShellNetworkPolicy","com.azure.ai.agents.models.ToolboxShellNetworkPolicyDisabled":"Azure.AI.Projects.ToolboxShellNetworkPolicyDisabled","com.azure.ai.agents.models.ToolboxSkill":"Azure.AI.Projects.ToolboxSkill","com.azure.ai.agents.models.ToolboxSkillReference":"Azure.AI.Projects.ToolboxSkillReference","com.azure.ai.agents.models.ToolboxTool":"Azure.AI.Projects.ToolboxTool","com.azure.ai.agents.models.ToolboxToolType":"Azure.AI.Projects.ToolboxToolType","com.azure.ai.agents.models.ToolboxVersionDetails":"Azure.AI.Projects.ToolboxVersionObject","com.azure.ai.agents.models.ToolboxVersions":"Azure.AI.Projects.ToolboxVersions","com.azure.ai.agents.models.TwilioTelephonyBinding":"Azure.AI.Projects.TwilioTelephonyBinding","com.azure.ai.agents.models.TwilioTelephonyBindingListItem":"Azure.AI.Projects.TwilioTelephonyBindingListItem","com.azure.ai.agents.models.UpdateAgentDetailsOptions":"Azure.AI.Projects.patchAgentObject.Request.anonymous","com.azure.ai.agents.models.UpdateTelephonyBindingInput":"Azure.AI.Projects.UpdateTelephonyBindingRequest","com.azure.ai.agents.models.UserConversationSimulationAudioEffect":"Azure.AI.Projects.UserConversationSimulationAudioEffect","com.azure.ai.agents.models.UserConversationSimulationAudioEffectsConfiguration":"Azure.AI.Projects.UserConversationSimulationAudioEffectsConfiguration","com.azure.ai.agents.models.UserConversationSimulationConfiguration":"Azure.AI.Projects.UserConversationSimulationConfiguration","com.azure.ai.agents.models.UserConversationSimulationDefaultInterruptionConfiguration":"Azure.AI.Projects.UserConversationSimulationDefaultInterruptionConfiguration","com.azure.ai.agents.models.UserConversationSimulationInterruptionConfiguration":"Azure.AI.Projects.UserConversationSimulationInterruptionConfiguration","com.azure.ai.agents.models.UserConversationSimulationTestCase":"Azure.AI.Projects.UserConversationSimulationTestCase","com.azure.ai.agents.models.UserConversationSimulationUserBehaviorConfiguration":"Azure.AI.Projects.UserConversationSimulationUserBehaviorConfiguration","com.azure.ai.agents.models.UserProfileMemoryItem":"Azure.AI.Projects.UserProfileMemoryItem","com.azure.ai.agents.models.VersionIndicator":"Azure.AI.Projects.VersionIndicator","com.azure.ai.agents.models.VersionIndicatorType":"Azure.AI.Projects.VersionIndicatorType","com.azure.ai.agents.models.VersionRefIndicator":"Azure.AI.Projects.VersionRefIndicator","com.azure.ai.agents.models.VersionSelectionRule":"Azure.AI.Projects.VersionSelectionRule","com.azure.ai.agents.models.VersionSelector":"Azure.AI.Projects.VersionSelector","com.azure.ai.agents.models.VersionSelectorType":"Azure.AI.Projects.VersionSelectorType","com.azure.ai.agents.models.VoiceAgentAnimationConfiguration":"Azure.AI.Projects.VoiceAgentAnimationConfig","com.azure.ai.agents.models.VoiceAgentAnimationOutputType":"Azure.AI.Projects.VoiceAgentAnimationOutputType","com.azure.ai.agents.models.VoiceAgentAudioConfiguration":"Azure.AI.Projects.VoiceAgentAudioConfig","com.azure.ai.agents.models.VoiceAgentAudioInputConfiguration":"Azure.AI.Projects.VoiceAgentAudioInputConfig","com.azure.ai.agents.models.VoiceAgentAudioOutputConfiguration":"Azure.AI.Projects.VoiceAgentAudioOutputConfig","com.azure.ai.agents.models.VoiceAgentAudioTimestampType":"Azure.AI.Projects.VoiceAgentAudioTimestampType","com.azure.ai.agents.models.VoiceAgentAvatarConfiguration":"Azure.AI.Projects.VoiceAgentAvatarConfig","com.azure.ai.agents.models.VoiceAgentAvatarIceServer":"Azure.AI.Projects.VoiceAgentAvatarIceServer","com.azure.ai.agents.models.VoiceAgentAvatarOutputProtocol":"Azure.AI.Projects.VoiceAgentAvatarOutputProtocol","com.azure.ai.agents.models.VoiceAgentAvatarScene":"Azure.AI.Projects.VoiceAgentAvatarScene","com.azure.ai.agents.models.VoiceAgentAvatarType":"Azure.AI.Projects.VoiceAgentAvatarType","com.azure.ai.agents.models.VoiceAgentAvatarVideoBackground":"Azure.AI.Projects.VoiceAgentAvatarVideoBackground","com.azure.ai.agents.models.VoiceAgentAvatarVideoCrop":"Azure.AI.Projects.VoiceAgentAvatarVideoCrop","com.azure.ai.agents.models.VoiceAgentAvatarVideoParameters":"Azure.AI.Projects.VoiceAgentAvatarVideoParams","com.azure.ai.agents.models.VoiceAgentAvatarVideoResolution":"Azure.AI.Projects.VoiceAgentAvatarVideoResolution","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadEnglishTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadEnTurnDetection","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadMultilingualTurnDetection","com.azure.ai.agents.models.VoiceAgentAzureSemanticVadTurnDetection":"Azure.AI.Projects.VoiceAgentAzureSemanticVadTurnDetection","com.azure.ai.agents.models.VoiceAgentBaseDefinition":"Azure.AI.Projects.VoiceAgentBaseDefinition","com.azure.ai.agents.models.VoiceAgentCollectDtmfSystemTool":"Azure.AI.Projects.VoiceAgentCollectDtmfSystemTool","com.azure.ai.agents.models.VoiceAgentCollectSmsSystemTool":"Azure.AI.Projects.VoiceAgentCollectSmsSystemTool","com.azure.ai.agents.models.VoiceAgentDefinition":"Azure.AI.Projects.VoiceAgentDefinition","com.azure.ai.agents.models.VoiceAgentDelegateSubagentConfiguration":"Azure.AI.Projects.VoiceAgentDelegateSubagentConfig","com.azure.ai.agents.models.VoiceAgentDigitRecognitionSystemTool":"Azure.AI.Projects.VoiceAgentDigitRecognitionSystemTool","com.azure.ai.agents.models.VoiceAgentEchoCancellation":"Azure.AI.Projects.VoiceAgentEchoCancellation","com.azure.ai.agents.models.VoiceAgentEchoCancellationReferenceSource":"Azure.AI.Projects.VoiceAgentEchoCancellationReferenceSource","com.azure.ai.agents.models.VoiceAgentEndConversationSystemTool":"Azure.AI.Projects.VoiceAgentEndConversationSystemTool","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetection":"Azure.AI.Projects.VoiceAgentEndOfUtteranceDetection","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceDetectionModel":"Azure.AI.Projects.VoiceAgentEndOfUtteranceDetectionModel","com.azure.ai.agents.models.VoiceAgentEndOfUtteranceThresholdLevel":"Azure.AI.Projects.VoiceAgentEndOfUtteranceThresholdLevel","com.azure.ai.agents.models.VoiceAgentEventGridPostCallDestination":"Azure.AI.Projects.VoiceAgentEventGridPostCallDestination","com.azure.ai.agents.models.VoiceAgentFunctionTool":"Azure.AI.Projects.VoiceAgentFunctionTool","com.azure.ai.agents.models.VoiceAgentGreetingConfiguration":"Azure.AI.Projects.VoiceAgentGreetingConfig","com.azure.ai.agents.models.VoiceAgentGreetingMode":"Azure.AI.Projects.VoiceAgentGreetingMode","com.azure.ai.agents.models.VoiceAgentHandoffAbortReason":"Azure.AI.Projects.VoiceAgentHandoffAbortReason","com.azure.ai.agents.models.VoiceAgentHandoffCondition":"Azure.AI.Projects.VoiceAgentHandoffCondition","com.azure.ai.agents.models.VoiceAgentHandoffEdgeState":"Azure.AI.Projects.VoiceAgentHandoffEdgeState","com.azure.ai.agents.models.VoiceAgentHandoffNodeState":"Azure.AI.Projects.VoiceAgentHandoffNodeState","com.azure.ai.agents.models.VoiceAgentHandoffPipelineFamily":"Azure.AI.Projects.VoiceAgentHandoffPipelineFamily","com.azure.ai.agents.models.VoiceAgentHandoffPolicy":"Azure.AI.Projects.VoiceAgentHandoffPolicy","com.azure.ai.agents.models.VoiceAgentHandoffReasoningEffort":"Azure.AI.Projects.VoiceAgentHandoffReasoningEffort","com.azure.ai.agents.models.VoiceAgentHandoffState":"Azure.AI.Projects.VoiceAgentHandoffState","com.azure.ai.agents.models.VoiceAgentHandoffTargetResponse":"Azure.AI.Projects.VoiceAgentHandoffTargetResponse","com.azure.ai.agents.models.VoiceAgentHandoffVoiceAdaptation":"Azure.AI.Projects.VoiceAgentHandoffVoiceAdaptation","com.azure.ai.agents.models.VoiceAgentInlineSubagentConfiguration":"Azure.AI.Projects.VoiceAgentInlineSubagentConfig","com.azure.ai.agents.models.VoiceAgentInputCollectionChannel":"Azure.AI.Projects.VoiceAgentInputCollectionChannel","com.azure.ai.agents.models.VoiceAgentInputCollectionStatus":"Azure.AI.Projects.VoiceAgentInputCollectionStatus","com.azure.ai.agents.models.VoiceAgentInputCollectionStatusEvent":"Azure.AI.Projects.VoiceAgentServerEventInputCollectionStatus","com.azure.ai.agents.models.VoiceAgentInputTranscription":"Azure.AI.Projects.VoiceAgentInputTranscription","com.azure.ai.agents.models.VoiceAgentInputTranscriptionModel":"Azure.AI.Projects.VoiceAgentInputTranscriptionModel","com.azure.ai.agents.models.VoiceAgentInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentInterimResponseTrigger":"Azure.AI.Projects.VoiceAgentInterimResponseTrigger","com.azure.ai.agents.models.VoiceAgentInterimResponseType":"Azure.AI.Projects.VoiceAgentInterimResponseType","com.azure.ai.agents.models.VoiceAgentLanguageDetectionSystemTool":"Azure.AI.Projects.VoiceAgentLanguageDetectionSystemTool","com.azure.ai.agents.models.VoiceAgentLiveClientDelegation":"Azure.AI.Projects.VoiceAgentLiveClientDelegation","com.azure.ai.agents.models.VoiceAgentLiveClientDelegationConversationItem":"Azure.AI.Projects.VoiceAgentLiveClientDelegationConversationItem","com.azure.ai.agents.models.VoiceAgentLiveConversation":"Azure.AI.Projects.VoiceAgentLiveConversation","com.azure.ai.agents.models.VoiceAgentLiveConversationItem":"Azure.AI.Projects.VoiceAgentLiveConversationItem","com.azure.ai.agents.models.VoiceAgentLiveConversationItemType":"Azure.AI.Projects.VoiceAgentLiveConversationItemType","com.azure.ai.agents.models.VoiceAgentLiveDefinition":"Azure.AI.Projects.VoiceAgentLiveDefinition","com.azure.ai.agents.models.VoiceAgentLiveDelegation":"Azure.AI.Projects.VoiceAgentLiveDelegation","com.azure.ai.agents.models.VoiceAgentLiveDelegationConversationItem":"Azure.AI.Projects.VoiceAgentLiveDelegationConversationItem","com.azure.ai.agents.models.VoiceAgentLiveDelegationResultItem":"Azure.AI.Projects.VoiceAgentLiveDelegationResultItem","com.azure.ai.agents.models.VoiceAgentLiveDelegationStatus":"Azure.AI.Projects.VoiceAgentLiveDelegationStatus","com.azure.ai.agents.models.VoiceAgentLiveDelegationTarget":"Azure.AI.Projects.VoiceAgentLiveDelegationTarget","com.azure.ai.agents.models.VoiceAgentLiveDelegationType":"Azure.AI.Projects.VoiceAgentLiveDelegationType","com.azure.ai.agents.models.VoiceAgentLiveFoundryManagedAgentDelegationItem":"Azure.AI.Projects.VoiceAgentLiveFoundryManagedAgentDelegationItem","com.azure.ai.agents.models.VoiceAgentLiveInputConversationItem":"Azure.AI.Projects.VoiceAgentLiveInputConversationItem","com.azure.ai.agents.models.VoiceAgentLiveManagedAgentDelegation":"Azure.AI.Projects.VoiceAgentLiveManagedAgentDelegation","com.azure.ai.agents.models.VoiceAgentLiveOutputConversationItem":"Azure.AI.Projects.VoiceAgentLiveOutputConversationItem","com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegation":"Azure.AI.Projects.VoiceAgentLiveResponsesDelegation","com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegationConversationItem":"Azure.AI.Projects.VoiceAgentLiveResponsesDelegationConversationItem","com.azure.ai.agents.models.VoiceAgentLlmGeneratedGreetingConfiguration":"Azure.AI.Projects.VoiceAgentLlmGeneratedGreetingConfig","com.azure.ai.agents.models.VoiceAgentLlmInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentLlmInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentMcpTool":"Azure.AI.Projects.VoiceAgentMcpTool","com.azure.ai.agents.models.VoiceAgentNoiseReduction":"Azure.AI.Projects.VoiceAgentNoiseReduction","com.azure.ai.agents.models.VoiceAgentNoiseReductionType":"Azure.AI.Projects.VoiceAgentNoiseReductionType","com.azure.ai.agents.models.VoiceAgentPostCallConfiguration":"Azure.AI.Projects.VoiceAgentPostCallConfig","com.azure.ai.agents.models.VoiceAgentPostCallDestination":"Azure.AI.Projects.VoiceAgentPostCallDestination","com.azure.ai.agents.models.VoiceAgentPostCallDestinationType":"Azure.AI.Projects.VoiceAgentPostCallDestinationType","com.azure.ai.agents.models.VoiceAgentPostCallIncludeOption":"Azure.AI.Projects.VoiceAgentPostCallIncludeOption","com.azure.ai.agents.models.VoiceAgentProfanityFilterMode":"Azure.AI.Projects.VoiceAgentProfanityFilterMode","com.azure.ai.agents.models.VoiceAgentRealtimeResponse":"Azure.AI.Projects.VoiceAgentRealtimeResponse","com.azure.ai.agents.models.VoiceAgentResponseAnimationBlendshapeDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDelta","com.azure.ai.agents.models.VoiceAgentResponseAnimationBlendshapeDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDone","com.azure.ai.agents.models.VoiceAgentResponseAnimationVisemeDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDelta","com.azure.ai.agents.models.VoiceAgentResponseAnimationVisemeDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDone","com.azure.ai.agents.models.VoiceAgentResponseAudioConfig":"TypeSpec.PickProperties","com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDelta","com.azure.ai.agents.models.VoiceAgentResponseAudioTimestampDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDone","com.azure.ai.agents.models.VoiceAgentResponseCreateOptions":"Azure.AI.Projects.VoiceAgentResponseCreateParams","com.azure.ai.agents.models.VoiceAgentResponseVideoDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventResponseVideoDelta","com.azure.ai.agents.models.VoiceAgentRoutinePostCallDestination":"Azure.AI.Projects.VoiceAgentRoutinePostCallDestination","com.azure.ai.agents.models.VoiceAgentRtcCallErrorDetails":"Azure.AI.Projects.VoiceAgentRtcCallErrorDetails","com.azure.ai.agents.models.VoiceAgentRtcCallErrorEvent":"Azure.AI.Projects.VoiceAgentServerEventRtcCallError","com.azure.ai.agents.models.VoiceAgentRtcCallErrorType":"Azure.AI.Projects.VoiceAgentRtcCallErrorType","com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreateEvent":"Azure.AI.Projects.VoiceAgentClientEventRtcCallSdpCreate","com.azure.ai.agents.models.VoiceAgentRtcCallSdpCreatedEvent":"Azure.AI.Projects.VoiceAgentServerEventRtcCallSdpCreated","com.azure.ai.agents.models.VoiceAgentSemanticVadTurnDetection":"Azure.AI.Projects.VoiceAgentSemanticVadTurnDetection","com.azure.ai.agents.models.VoiceAgentSendDtmfSystemTool":"Azure.AI.Projects.VoiceAgentSendDtmfSystemTool","com.azure.ai.agents.models.VoiceAgentSendSmsSystemTool":"Azure.AI.Projects.VoiceAgentSendSmsSystemTool","com.azure.ai.agents.models.VoiceAgentServerVadTurnDetection":"Azure.AI.Projects.VoiceAgentServerVadTurnDetection","com.azure.ai.agents.models.VoiceAgentSessionAvatarConfiguration":"Azure.AI.Projects.VoiceAgentSessionAvatarConfig","com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectEvent":"Azure.AI.Projects.VoiceAgentClientEventSessionAvatarConnect","com.azure.ai.agents.models.VoiceAgentSessionAvatarConnectingEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarConnecting","com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToIdleEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToIdle","com.azure.ai.agents.models.VoiceAgentSessionAvatarSwitchToSpeakingEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToSpeaking","com.azure.ai.agents.models.VoiceAgentSessionHandoffAbortedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionHandoffAborted","com.azure.ai.agents.models.VoiceAgentSessionHandoffCompletedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionHandoffCompleted","com.azure.ai.agents.models.VoiceAgentSessionHandoffStartedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionHandoffStarted","com.azure.ai.agents.models.VoiceAgentSessionIncludeOption":"Azure.AI.Projects.VoiceAgentSessionIncludeOption","com.azure.ai.agents.models.VoiceAgentSessionResponseConfiguration":"Azure.AI.Projects.VoiceAgentSessionResponseConfig","com.azure.ai.agents.models.VoiceAgentSessionSubagentAbortedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentAborted","com.azure.ai.agents.models.VoiceAgentSessionSubagentCompletedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentCompleted","com.azure.ai.agents.models.VoiceAgentSessionSubagentStartedEvent":"Azure.AI.Projects.VoiceAgentServerEventSessionSubagentStarted","com.azure.ai.agents.models.VoiceAgentSessionUpdateConfiguration":"Azure.AI.Projects.VoiceAgentSessionUpdateConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeSound":"Azure.AI.Projects.VoiceAgentSoundscapeSound","com.azure.ai.agents.models.VoiceAgentSoundscapeSourceConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeSourceConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeTrackConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeTrackConfig","com.azure.ai.agents.models.VoiceAgentSoundscapeWorkingTrackConfiguration":"Azure.AI.Projects.VoiceAgentSoundscapeWorkingTrackConfig","com.azure.ai.agents.models.VoiceAgentStaticInterimResponseConfiguration":"Azure.AI.Projects.VoiceAgentStaticInterimResponseConfig","com.azure.ai.agents.models.VoiceAgentSubProtocol":"Azure.AI.Projects.VoiceAgentSubProtocol","com.azure.ai.agents.models.VoiceAgentSubagent":"Azure.AI.Projects.VoiceAgentSubagent","com.azure.ai.agents.models.VoiceAgentSubagentAbortReason":"Azure.AI.Projects.VoiceAgentSubagentAbortReason","com.azure.ai.agents.models.VoiceAgentSubagentConfiguration":"Azure.AI.Projects.VoiceAgentSubagentConfig","com.azure.ai.agents.models.VoiceAgentSubagentResponsePolicy":"Azure.AI.Projects.VoiceAgentSubagentResponsePolicy","com.azure.ai.agents.models.VoiceAgentSubagentType":"Azure.AI.Projects.VoiceAgentSubagentType","com.azure.ai.agents.models.VoiceAgentSystemTool":"Azure.AI.Projects.VoiceAgentSystemTool","com.azure.ai.agents.models.VoiceAgentSystemToolArgumentsDeltaEvent":"Azure.AI.Projects.VoiceAgentServerEventSystemToolArgumentsDelta","com.azure.ai.agents.models.VoiceAgentSystemToolArgumentsDoneEvent":"Azure.AI.Projects.VoiceAgentServerEventSystemToolArgumentsDone","com.azure.ai.agents.models.VoiceAgentSystemToolItem":"Azure.AI.Projects.VoiceAgentSystemToolItem","com.azure.ai.agents.models.VoiceAgentSystemToolItemObjectType":null,"com.azure.ai.agents.models.VoiceAgentSystemToolItemStatus":"Azure.AI.Projects.VoiceAgentSystemToolItemStatus","com.azure.ai.agents.models.VoiceAgentSystemToolName":"Azure.AI.Projects.VoiceAgentSystemToolName","com.azure.ai.agents.models.VoiceAgentTemplateGreetingConfiguration":"Azure.AI.Projects.VoiceAgentTemplateGreetingConfig","com.azure.ai.agents.models.VoiceAgentTool":"Azure.AI.Projects.VoiceAgentTool","com.azure.ai.agents.models.VoiceAgentToolResponseScheduling":"Azure.AI.Projects.VoiceAgentToolResponseScheduling","com.azure.ai.agents.models.VoiceAgentToolType":"Azure.AI.Projects.VoiceAgentToolType","com.azure.ai.agents.models.VoiceAgentToolboxTool":"Azure.AI.Projects.VoiceAgentToolboxTool","com.azure.ai.agents.models.VoiceAgentTranscriptionPhrase":"Azure.AI.Projects.VoiceAgentTranscriptionPhrase","com.azure.ai.agents.models.VoiceAgentTranscriptionWord":"Azure.AI.Projects.VoiceAgentTranscriptionWord","com.azure.ai.agents.models.VoiceAgentTransferDestination":"Azure.AI.Projects.VoiceAgentTransferDestination","com.azure.ai.agents.models.VoiceAgentTransferDestinationType":"Azure.AI.Projects.VoiceAgentTransferDestinationType","com.azure.ai.agents.models.VoiceAgentTransferRouting":"Azure.AI.Projects.VoiceAgentTransferRouting","com.azure.ai.agents.models.VoiceAgentTransferStrategy":"Azure.AI.Projects.VoiceAgentTransferStrategy","com.azure.ai.agents.models.VoiceAgentTransferSystemTool":"Azure.AI.Projects.VoiceAgentTransferSystemTool","com.azure.ai.agents.models.VoiceAgentTransferTarget":"Azure.AI.Projects.VoiceAgentTransferTarget","com.azure.ai.agents.models.VoiceAgentTransport":"Azure.AI.Projects.VoiceAgentTransport","com.azure.ai.agents.models.VoiceAgentTurnDetectionConfiguration":"Azure.AI.Projects.VoiceAgentTurnDetectionConfig","com.azure.ai.agents.models.VoiceAgentTurnDetectionType":"Azure.AI.Projects.VoiceAgentTurnDetectionType","com.azure.ai.agents.models.VoiceAgentVoiceConfiguration":"Azure.AI.Projects.VoiceAgentVoiceConfig","com.azure.ai.agents.models.VoiceAgentWarningDetails":"Azure.AI.Projects.VoiceAgentServerEventWarningDetails","com.azure.ai.agents.models.VoiceAgentWarningEvent":"Azure.AI.Projects.VoiceAgentServerEventWarning","com.azure.ai.agents.models.VoiceAudioCodec":"Azure.AI.Projects.VoiceAudioCodec","com.azure.ai.agents.models.VoiceAudioContainerFormat":"Azure.AI.Projects.VoiceAudioContainerFormat","com.azure.ai.agents.models.VoiceAudioItem":"Azure.AI.Projects.VoiceAudioItem","com.azure.ai.agents.models.VoiceAudioRole":"Azure.AI.Projects.VoiceAudioRole","com.azure.ai.agents.models.VoiceConversation":"Azure.AI.Projects.VoiceConversation","com.azure.ai.agents.models.VoiceConversationEngine":"Azure.AI.Projects.VoiceConversationEngine","com.azure.ai.agents.models.VoiceConversationEngineType":"Azure.AI.Projects.VoiceConversationEngineType","com.azure.ai.agents.models.VoiceConversationStatus":"Azure.AI.Projects.VoiceConversationStatus","com.azure.ai.agents.models.VoiceGeneratedAudioItem":"Azure.AI.Projects.VoiceGeneratedAudioItem","com.azure.ai.agents.models.VoiceHostedAgentConversationEngine":"Azure.AI.Projects.VoiceHostedAgentConversationEngine","com.azure.ai.agents.models.VoiceModelType":"Azure.AI.Projects.VoiceModelType","com.azure.ai.agents.models.VoiceOutputModality":"Azure.AI.Projects.VoiceOutputModality","com.azure.ai.agents.models.VoiceRecording":"Azure.AI.Projects.VoiceRecording","com.azure.ai.agents.models.VoiceRecordingChannelLayout":"Azure.AI.Projects.VoiceRecordingChannelLayout","com.azure.ai.agents.models.VoiceResponse":"Azure.AI.Projects.VoiceResponse","com.azure.ai.agents.models.VoiceResponseAudio":"Azure.AI.Projects.VoiceResponseAudio","com.azure.ai.agents.models.VoiceResponseAudioOutput":"Azure.AI.Projects.VoiceResponseAudioOutput","com.azure.ai.agents.models.VoiceResponseObjectType":null,"com.azure.ai.agents.models.VoiceType":"Azure.AI.Projects.VoiceType","com.azure.ai.agents.models.WebIqPreviewTool":"Azure.AI.Projects.WebIQPreviewTool","com.azure.ai.agents.models.WebIqPreviewToolboxTool":"Azure.AI.Projects.WebIQPreviewToolboxTool","com.azure.ai.agents.models.WebSearchApproximateLocation":"OpenAI.WebSearchApproximateLocation","com.azure.ai.agents.models.WebSearchConfiguration":"Azure.AI.Projects.WebSearchConfiguration","com.azure.ai.agents.models.WebSearchPreviewTool":"OpenAI.ToolWebSearchPreviewTool","com.azure.ai.agents.models.WebSearchTool":"OpenAI.ToolWebSearchTool","com.azure.ai.agents.models.WebSearchToolFilters":"OpenAI.WebSearchToolFilters","com.azure.ai.agents.models.WebSearchToolSearchContextSize":"WebSearchToolSearchContextSizeExpandable","com.azure.ai.agents.models.WebSearchToolboxTool":"Azure.AI.Projects.WebSearchToolboxTool","com.azure.ai.agents.models.WorkIqPreviewTool":"Azure.AI.Projects.WorkIQPreviewTool","com.azure.ai.agents.models.WorkIqPreviewToolboxTool":"Azure.AI.Projects.WorkIQPreviewToolboxTool","com.azure.ai.agents.models.WorkflowAgentDefinition":"Azure.AI.Projects.WorkflowAgentDefinition"},"generatedFiles":["src/main/java/com/azure/ai/agents/AgentsAsyncClient.java","src/main/java/com/azure/ai/agents/AgentsClient.java","src/main/java/com/azure/ai/agents/AgentsClientBuilder.java","src/main/java/com/azure/ai/agents/AgentsServiceVersion.java","src/main/java/com/azure/ai/agents/BetaAgentsAsyncClient.java","src/main/java/com/azure/ai/agents/BetaAgentsClient.java","src/main/java/com/azure/ai/agents/BetaMemoryStoresAsyncClient.java","src/main/java/com/azure/ai/agents/BetaMemoryStoresClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsAsyncClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsConversationsClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsAsyncClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsLiveConversationsClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyAsyncClient.java","src/main/java/com/azure/ai/agents/BetaVoiceAgentsTelephonyClient.java","src/main/java/com/azure/ai/agents/ToolboxesAsyncClient.java","src/main/java/com/azure/ai/agents/ToolboxesClient.java","src/main/java/com/azure/ai/agents/implementation/AgentsClientImpl.java","src/main/java/com/azure/ai/agents/implementation/AgentsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaAgentsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaMemoryStoresImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsConversationsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsLiveConversationsImpl.java","src/main/java/com/azure/ai/agents/implementation/BetaVoiceAgentsTelephoniesImpl.java","src/main/java/com/azure/ai/agents/implementation/JsonMergePatchHelper.java","src/main/java/com/azure/ai/agents/implementation/MultipartFormDataHelper.java","src/main/java/com/azure/ai/agents/implementation/OperationLocationPollingStrategy.java","src/main/java/com/azure/ai/agents/implementation/PollingUtils.java","src/main/java/com/azure/ai/agents/implementation/SyncOperationLocationPollingStrategy.java","src/main/java/com/azure/ai/agents/implementation/ToolboxesImpl.java","src/main/java/com/azure/ai/agents/implementation/models/AgentDefinitionOptInKeys.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentFromCodeContent.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentOptions.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentVersionFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateAgentVersionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateMemoryRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateMemoryStoreRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateSessionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/CreateToolboxVersionRequest.java","src/main/java/com/azure/ai/agents/implementation/models/FoundryFeaturesOptInKeys.java","src/main/java/com/azure/ai/agents/implementation/models/GetMicrosoft365AppPackageRequest.java","src/main/java/com/azure/ai/agents/implementation/models/ListMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/PublishAgentToMicrosoft365Request.java","src/main/java/com/azure/ai/agents/implementation/models/ReplaceTelephonyTransferTargetsRequest.java","src/main/java/com/azure/ai/agents/implementation/models/SearchMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/TransferTelephonyCallRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateAgentFromManifestRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateAgentRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoriesRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoryRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateMemoryStoreRequest.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateToolboxInput.java","src/main/java/com/azure/ai/agents/implementation/models/UpdateToolboxRequest.java","src/main/java/com/azure/ai/agents/implementation/models/package-info.java","src/main/java/com/azure/ai/agents/implementation/package-info.java","src/main/java/com/azure/ai/agents/models/A2APreviewTool.java","src/main/java/com/azure/ai/agents/models/A2APreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/A2AProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/A2AProtocolVersion.java","src/main/java/com/azure/ai/agents/models/A2ATool.java","src/main/java/com/azure/ai/agents/models/A2AToolCall.java","src/main/java/com/azure/ai/agents/models/A2AToolCallOutput.java","src/main/java/com/azure/ai/agents/models/A2AToolboxTool.java","src/main/java/com/azure/ai/agents/models/AISearchIndexResource.java","src/main/java/com/azure/ai/agents/models/ActivityProtocolAccessBoundary.java","src/main/java/com/azure/ai/agents/models/ActivityProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentBlueprintReference.java","src/main/java/com/azure/ai/agents/models/AgentBlueprintReferenceType.java","src/main/java/com/azure/ai/agents/models/AgentCard.java","src/main/java/com/azure/ai/agents/models/AgentCardSkill.java","src/main/java/com/azure/ai/agents/models/AgentDefinition.java","src/main/java/com/azure/ai/agents/models/AgentDetails.java","src/main/java/com/azure/ai/agents/models/AgentDetailsVersions.java","src/main/java/com/azure/ai/agents/models/AgentEndpointAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/AgentEndpointAuthorizationSchemeType.java","src/main/java/com/azure/ai/agents/models/AgentEndpointConfig.java","src/main/java/com/azure/ai/agents/models/AgentEndpointProtocol.java","src/main/java/com/azure/ai/agents/models/AgentHarness.java","src/main/java/com/azure/ai/agents/models/AgentIdentity.java","src/main/java/com/azure/ai/agents/models/AgentIdentityStatus.java","src/main/java/com/azure/ai/agents/models/AgentKind.java","src/main/java/com/azure/ai/agents/models/AgentObjectType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationAgentCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationBaselineAgentConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateEvaluation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateExpand.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidatePromotionInfo.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCandidateStatus.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfigurationBase.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationConfigurationType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationCostEstimate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationDataSourceType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateBand.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateInputs.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEstimateResult.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluationSetType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationEvaluatorReference.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationFoundryAgentTargetConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationGoal.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationInstructionsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJob.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobLatency.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobResult.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationJobTokenUsage.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationModelConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationModelMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationPromptCandidateOutput.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationResultCandidateSummary.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSkill.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSkillsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationSpace.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationStage.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationStageEstimate.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionDatasetReferenceDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionInlineDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetCompletionTestCase.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetConfiguration.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTargetConfigurationType.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationTerminationReason.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationToolsMutation.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationDatasetReferenceDataSource.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationEvaluationSet.java","src/main/java/com/azure/ai/agents/models/AgentOptimizationUserConversationSimulationInlineDataSource.java","src/main/java/com/azure/ai/agents/models/AgentReference.java","src/main/java/com/azure/ai/agents/models/AgentSessionResource.java","src/main/java/com/azure/ai/agents/models/AgentSessionStatus.java","src/main/java/com/azure/ai/agents/models/AgentState.java","src/main/java/com/azure/ai/agents/models/AgentStateSource.java","src/main/java/com/azure/ai/agents/models/AgentVersionDetails.java","src/main/java/com/azure/ai/agents/models/AgentVersionStatus.java","src/main/java/com/azure/ai/agents/models/ApiError.java","src/main/java/com/azure/ai/agents/models/ApplyPatchToolParameter.java","src/main/java/com/azure/ai/agents/models/ApproximateLocation.java","src/main/java/com/azure/ai/agents/models/AutoCodeInterpreterToolParameter.java","src/main/java/com/azure/ai/agents/models/AzureAISearchQueryType.java","src/main/java/com/azure/ai/agents/models/AzureAISearchTool.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolCall.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolCallOutput.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolResource.java","src/main/java/com/azure/ai/agents/models/AzureAISearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/AzureCreateResponseDetails.java","src/main/java/com/azure/ai/agents/models/AzureCreateResponseOptions.java","src/main/java/com/azure/ai/agents/models/AzureFunctionBinding.java","src/main/java/com/azure/ai/agents/models/AzureFunctionDefinition.java","src/main/java/com/azure/ai/agents/models/AzureFunctionDefinitionDetails.java","src/main/java/com/azure/ai/agents/models/AzureFunctionStorageQueue.java","src/main/java/com/azure/ai/agents/models/AzureFunctionTool.java","src/main/java/com/azure/ai/agents/models/AzureFunctionToolCall.java","src/main/java/com/azure/ai/agents/models/AzureFunctionToolCallOutput.java","src/main/java/com/azure/ai/agents/models/AzureUserSecurityContext.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolCall.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BingCustomSearchToolParameters.java","src/main/java/com/azure/ai/agents/models/BingGroundingSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/BingGroundingSearchToolParameters.java","src/main/java/com/azure/ai/agents/models/BingGroundingTool.java","src/main/java/com/azure/ai/agents/models/BingGroundingToolCall.java","src/main/java/com/azure/ai/agents/models/BingGroundingToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BotServiceAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BotServiceRbacAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BotServiceTenantAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationPreviewTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationTool.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolCall.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolCallOutput.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolConnectionParameters.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolParameters.java","src/main/java/com/azure/ai/agents/models/BrowserAutomationToolboxTool.java","src/main/java/com/azure/ai/agents/models/CallableToolAllowedCaller.java","src/main/java/com/azure/ai/agents/models/CaptureStructuredOutputsTool.java","src/main/java/com/azure/ai/agents/models/ChatSummaryMemoryItem.java","src/main/java/com/azure/ai/agents/models/CodeConfiguration.java","src/main/java/com/azure/ai/agents/models/CodeDependencyResolution.java","src/main/java/com/azure/ai/agents/models/CodeFileDetails.java","src/main/java/com/azure/ai/agents/models/CodeInterpreterTool.java","src/main/java/com/azure/ai/agents/models/CodeInterpreterToolboxTool.java","src/main/java/com/azure/ai/agents/models/ComputerEnvironment.java","src/main/java/com/azure/ai/agents/models/ComputerTool.java","src/main/java/com/azure/ai/agents/models/ComputerUsePreviewTool.java","src/main/java/com/azure/ai/agents/models/ContainerAutoParameter.java","src/main/java/com/azure/ai/agents/models/ContainerConfiguration.java","src/main/java/com/azure/ai/agents/models/ContainerMemoryLimit.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyAllowlistParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyDisabledParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyDomainSecretParameter.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyParamType.java","src/main/java/com/azure/ai/agents/models/ContainerNetworkPolicyParameter.java","src/main/java/com/azure/ai/agents/models/ContainerSkill.java","src/main/java/com/azure/ai/agents/models/ContainerSkillType.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionFromCodeContent.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionFromCodeMetadata.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionInput.java","src/main/java/com/azure/ai/agents/models/CreateAgentVersionOptions.java","src/main/java/com/azure/ai/agents/models/CustomGrammarFormatParameter.java","src/main/java/com/azure/ai/agents/models/CustomTextFormatParameter.java","src/main/java/com/azure/ai/agents/models/CustomToolParamFormat.java","src/main/java/com/azure/ai/agents/models/CustomToolParamFormatType.java","src/main/java/com/azure/ai/agents/models/CustomToolParameter.java","src/main/java/com/azure/ai/agents/models/DatasetReference.java","src/main/java/com/azure/ai/agents/models/DigitalWorkerType.java","src/main/java/com/azure/ai/agents/models/EntraAuthorizationScheme.java","src/main/java/com/azure/ai/agents/models/EvaluationAzureStandardVoiceModelConfiguration.java","src/main/java/com/azure/ai/agents/models/EvaluationModelConfiguration.java","src/main/java/com/azure/ai/agents/models/EvaluationVoiceModelConfiguration.java","src/main/java/com/azure/ai/agents/models/ExternalAgentDefinition.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolCall.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolCallOutput.java","src/main/java/com/azure/ai/agents/models/FabricDataAgentToolParameters.java","src/main/java/com/azure/ai/agents/models/FabricIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/FabricIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/FileSearchTool.java","src/main/java/com/azure/ai/agents/models/FileSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/FixedRatioVersionSelectionRule.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParamEnvironment.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParamEnvironmentType.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameter.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameterEnvironmentContainerReferenceParameter.java","src/main/java/com/azure/ai/agents/models/FunctionShellToolParameterEnvironmentLocalEnvironmentParameter.java","src/main/java/com/azure/ai/agents/models/FunctionTool.java","src/main/java/com/azure/ai/agents/models/GetMicrosoft365AppPackageOptions.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotBuiltInTool.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotHarness.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetConfig.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetDefaultConfig.java","src/main/java/com/azure/ai/agents/models/GitHubCopilotToolsetPreview.java","src/main/java/com/azure/ai/agents/models/GrammarSyntax.java","src/main/java/com/azure/ai/agents/models/HeaderTelemetryEndpointAuth.java","src/main/java/com/azure/ai/agents/models/HostedAgentDefinition.java","src/main/java/com/azure/ai/agents/models/HybridSearchOptions.java","src/main/java/com/azure/ai/agents/models/ImageGenActionEnum.java","src/main/java/com/azure/ai/agents/models/ImageGenTool.java","src/main/java/com/azure/ai/agents/models/ImageGenToolBackground.java","src/main/java/com/azure/ai/agents/models/ImageGenToolInputImageMask.java","src/main/java/com/azure/ai/agents/models/ImageGenToolModel.java","src/main/java/com/azure/ai/agents/models/ImageGenToolModeration.java","src/main/java/com/azure/ai/agents/models/ImageGenToolOutputFormat.java","src/main/java/com/azure/ai/agents/models/ImageGenToolQuality.java","src/main/java/com/azure/ai/agents/models/ImageGenToolSize.java","src/main/java/com/azure/ai/agents/models/IncludeEnum.java","src/main/java/com/azure/ai/agents/models/InlineSkillParameter.java","src/main/java/com/azure/ai/agents/models/InlineSkillSourceParameter.java","src/main/java/com/azure/ai/agents/models/InlineVoiceSubagent.java","src/main/java/com/azure/ai/agents/models/InputFidelity.java","src/main/java/com/azure/ai/agents/models/InvocationsProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/InvocationsWsProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/JobStatus.java","src/main/java/com/azure/ai/agents/models/ListMemoriesOptions.java","src/main/java/com/azure/ai/agents/models/LocalShellToolParameter.java","src/main/java/com/azure/ai/agents/models/LocalSkillParameter.java","src/main/java/com/azure/ai/agents/models/ManagedAgentIdentityBlueprintReference.java","src/main/java/com/azure/ai/agents/models/McpProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/McpTool.java","src/main/java/com/azure/ai/agents/models/McpToolConnectorId.java","src/main/java/com/azure/ai/agents/models/McpToolFilter.java","src/main/java/com/azure/ai/agents/models/McpToolRequireApproval.java","src/main/java/com/azure/ai/agents/models/McpToolboxTool.java","src/main/java/com/azure/ai/agents/models/MemoryCommandToolCall.java","src/main/java/com/azure/ai/agents/models/MemoryCommandToolCallOutput.java","src/main/java/com/azure/ai/agents/models/MemoryItem.java","src/main/java/com/azure/ai/agents/models/MemoryItemKind.java","src/main/java/com/azure/ai/agents/models/MemoryOperation.java","src/main/java/com/azure/ai/agents/models/MemoryOperationKind.java","src/main/java/com/azure/ai/agents/models/MemorySearchItem.java","src/main/java/com/azure/ai/agents/models/MemorySearchOptions.java","src/main/java/com/azure/ai/agents/models/MemorySearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/MemorySearchToolCall.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefaultDefinition.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefaultOptions.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDefinition.java","src/main/java/com/azure/ai/agents/models/MemoryStoreDetails.java","src/main/java/com/azure/ai/agents/models/MemoryStoreKind.java","src/main/java/com/azure/ai/agents/models/MemoryStoreObjectType.java","src/main/java/com/azure/ai/agents/models/MemoryStoreOperationUsage.java","src/main/java/com/azure/ai/agents/models/MemoryStoreSearchResponse.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateCompletedResult.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateResponse.java","src/main/java/com/azure/ai/agents/models/MemoryStoreUpdateStatus.java","src/main/java/com/azure/ai/agents/models/Microsoft365PermissionScopes.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishDefaults.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishResult.java","src/main/java/com/azure/ai/agents/models/Microsoft365PublishScope.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotBuiltInTool.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotHarness.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetConfiguration.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetDefaultConfiguration.java","src/main/java/com/azure/ai/agents/models/MicrosoftCopilotToolsetPreview.java","src/main/java/com/azure/ai/agents/models/MicrosoftFabricPreviewTool.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttempt.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttemptError.java","src/main/java/com/azure/ai/agents/models/ModelRouterAttemptResult.java","src/main/java/com/azure/ai/agents/models/ModelRouterDetails.java","src/main/java/com/azure/ai/agents/models/ModelRouterMode.java","src/main/java/com/azure/ai/agents/models/ModelSamplingParameters.java","src/main/java/com/azure/ai/agents/models/ModelSelectionDetails.java","src/main/java/com/azure/ai/agents/models/NamespaceTool.java","src/main/java/com/azure/ai/agents/models/OpenApiAnonymousAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiAuthType.java","src/main/java/com/azure/ai/agents/models/OpenApiFunctionDefinition.java","src/main/java/com/azure/ai/agents/models/OpenApiFunctionDefinitionFunction.java","src/main/java/com/azure/ai/agents/models/OpenApiManagedAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiManagedSecurityScheme.java","src/main/java/com/azure/ai/agents/models/OpenApiProjectConnectionAuthDetails.java","src/main/java/com/azure/ai/agents/models/OpenApiProjectConnectionSecurityScheme.java","src/main/java/com/azure/ai/agents/models/OpenApiTool.java","src/main/java/com/azure/ai/agents/models/OpenApiToolCall.java","src/main/java/com/azure/ai/agents/models/OpenApiToolCallOutput.java","src/main/java/com/azure/ai/agents/models/OpenApiToolboxTool.java","src/main/java/com/azure/ai/agents/models/OptimizationContext.java","src/main/java/com/azure/ai/agents/models/OptimizationContextType.java","src/main/java/com/azure/ai/agents/models/OtlpTelemetryEndpoint.java","src/main/java/com/azure/ai/agents/models/PageOrder.java","src/main/java/com/azure/ai/agents/models/ProceduralMemoryItem.java","src/main/java/com/azure/ai/agents/models/ProgrammaticToolCallingParameter.java","src/main/java/com/azure/ai/agents/models/PromptAgentDefinition.java","src/main/java/com/azure/ai/agents/models/PromptAgentDefinitionTextOptions.java","src/main/java/com/azure/ai/agents/models/PromptOptimizationConfiguration.java","src/main/java/com/azure/ai/agents/models/ProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/ProtocolVersionRecord.java","src/main/java/com/azure/ai/agents/models/PublishAgentToMicrosoft365Options.java","src/main/java/com/azure/ai/agents/models/PublishApprovalStatus.java","src/main/java/com/azure/ai/agents/models/RaiConfig.java","src/main/java/com/azure/ai/agents/models/RaiInvocationContentType.java","src/main/java/com/azure/ai/agents/models/RaiInvocationModeration.java","src/main/java/com/azure/ai/agents/models/RaiInvocationResponseMode.java","src/main/java/com/azure/ai/agents/models/RaiSseTextSelector.java","src/main/java/com/azure/ai/agents/models/RankerVersionType.java","src/main/java/com/azure/ai/agents/models/RankingOptions.java","src/main/java/com/azure/ai/agents/models/RealtimeClientEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeClientEventType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItem.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemAssistantMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemCreateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDeleteEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDeletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCall.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemFunctionCallOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionSegmentEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemMessageType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemObjectType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemRetrieveEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemRetrievedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemSystemMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemTruncateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemTruncatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemType.java","src/main/java/com/azure/ai/agents/models/RealtimeConversationItemUserMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeErrorEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferAppendEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferClearEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferClearedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferCommitEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferCommittedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferDtmfReceivedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferSpeechStartedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferSpeechStoppedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeInputAudioBufferTimeoutTriggeredEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpApprovalInput.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpApprovalOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListTools.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpListToolsInProgressEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeMcpToolCall.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferClearEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferClearedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferStartedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeOutputAudioBufferStoppedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeRateLimitsUpdatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioTranscriptDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseAudioTranscriptDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCancelEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPart.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPartAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseContentPartDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCreateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseFunctionCallArgumentsDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseFunctionCallArgumentsDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputAudio.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputFunctionCall.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputFunctionCallOutput.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputImage.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputItemStatus.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessage.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageAssistant.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageAssistantContent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageDeveloper.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageSystem.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageType.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputMessageUser.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseInputText.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseItemReference.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallArgumentsDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallArgumentsDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallCompletedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallFailedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseMcpCallInProgressEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseOutputItemAddedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseOutputItemDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseTextDeltaEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeResponseTextDoneEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeServerEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeServerEventType.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionCreatedEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdateEvent.java","src/main/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEvent.java","src/main/java/com/azure/ai/agents/models/ReminderPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/ResponseFormatJsonSchemaInner.java","src/main/java/com/azure/ai/agents/models/ResponseUsageInputTokensDetails.java","src/main/java/com/azure/ai/agents/models/ResponseUsageOutputTokensDetails.java","src/main/java/com/azure/ai/agents/models/ResponsesProtocolConfiguration.java","src/main/java/com/azure/ai/agents/models/RoutingConfiguration.java","src/main/java/com/azure/ai/agents/models/RoutingTraceEntry.java","src/main/java/com/azure/ai/agents/models/SearchContentType.java","src/main/java/com/azure/ai/agents/models/SearchContextSize.java","src/main/java/com/azure/ai/agents/models/SessionAffinityConfiguration.java","src/main/java/com/azure/ai/agents/models/SessionAffinityDecision.java","src/main/java/com/azure/ai/agents/models/SessionAffinityDetails.java","src/main/java/com/azure/ai/agents/models/SessionAffinityMode.java","src/main/java/com/azure/ai/agents/models/SessionAffinityRequestMode.java","src/main/java/com/azure/ai/agents/models/SessionAffinitySource.java","src/main/java/com/azure/ai/agents/models/SessionConfiguration.java","src/main/java/com/azure/ai/agents/models/SessionDirectoryEntry.java","src/main/java/com/azure/ai/agents/models/SessionFileWriteResult.java","src/main/java/com/azure/ai/agents/models/SessionLogEvent.java","src/main/java/com/azure/ai/agents/models/SessionLogEventType.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolCall.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolCallOutput.java","src/main/java/com/azure/ai/agents/models/SharepointGroundingToolParameters.java","src/main/java/com/azure/ai/agents/models/SharepointPreviewTool.java","src/main/java/com/azure/ai/agents/models/ShellToolboxTool.java","src/main/java/com/azure/ai/agents/models/SipTelephonyBinding.java","src/main/java/com/azure/ai/agents/models/SipTelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/SkillReference.java","src/main/java/com/azure/ai/agents/models/SkillReferenceParameter.java","src/main/java/com/azure/ai/agents/models/SteeringPromptOptimizationContext.java","src/main/java/com/azure/ai/agents/models/StructuredInputDefinition.java","src/main/java/com/azure/ai/agents/models/StructuredOutputDefinition.java","src/main/java/com/azure/ai/agents/models/TargetAttribute.java","src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TeamsPhoneExtensibilityTelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/TelemetryConfig.java","src/main/java/com/azure/ai/agents/models/TelemetryDataKind.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpoint.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointAuth.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointAuthType.java","src/main/java/com/azure/ai/agents/models/TelemetryEndpointKind.java","src/main/java/com/azure/ai/agents/models/TelemetryTransportProtocol.java","src/main/java/com/azure/ai/agents/models/TelephonyAddress.java","src/main/java/com/azure/ai/agents/models/TelephonyAddressType.java","src/main/java/com/azure/ai/agents/models/TelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/TelephonyCallDurationBasis.java","src/main/java/com/azure/ai/agents/models/TelephonyCallEndReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJob.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobCancellation.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobCreate.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCallJobTerminalReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEvent.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventName.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventOutcome.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventReason.java","src/main/java/com/azure/ai/agents/models/TelephonyCallLifecycleEventSource.java","src/main/java/com/azure/ai/agents/models/TelephonyCallPhase.java","src/main/java/com/azure/ai/agents/models/TelephonyCallRecord.java","src/main/java/com/azure/ai/agents/models/TelephonyCallStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCallSummary.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTimestampSource.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTiming.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTrace.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTraceMode.java","src/main/java/com/azure/ai/agents/models/TelephonyCallTraceStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaign.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignAtTimeSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignImmediateSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperation.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignOperationKind.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignPerRecipientSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignProgress.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignSchedule.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignScheduleType.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignStatus.java","src/main/java/com/azure/ai/agents/models/TelephonyCampaignValidationError.java","src/main/java/com/azure/ai/agents/models/TelephonyFixedIntervalRetryPolicy.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicy.java","src/main/java/com/azure/ai/agents/models/TelephonyOutboundRetryPolicyType.java","src/main/java/com/azure/ai/agents/models/TelephonyPhoneNumber.java","src/main/java/com/azure/ai/agents/models/TelephonyProvider.java","src/main/java/com/azure/ai/agents/models/TelephonyRecipient.java","src/main/java/com/azure/ai/agents/models/TelephonySipAddress.java","src/main/java/com/azure/ai/agents/models/TelephonyTeamsAddress.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferTarget.java","src/main/java/com/azure/ai/agents/models/TelephonyTransferTargets.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfiguration.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationResponseFormatJsonObject.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationResponseFormatText.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatConfigurationType.java","src/main/java/com/azure/ai/agents/models/TextResponseFormatJsonSchema.java","src/main/java/com/azure/ai/agents/models/Tool.java","src/main/java/com/azure/ai/agents/models/ToolCallStatus.java","src/main/java/com/azure/ai/agents/models/ToolConfig.java","src/main/java/com/azure/ai/agents/models/ToolFunctionToolType3.java","src/main/java/com/azure/ai/agents/models/ToolProjectConnection.java","src/main/java/com/azure/ai/agents/models/ToolSearchExecutionType.java","src/main/java/com/azure/ai/agents/models/ToolSearchTool.java","src/main/java/com/azure/ai/agents/models/ToolSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolType.java","src/main/java/com/azure/ai/agents/models/ToolboxDetails.java","src/main/java/com/azure/ai/agents/models/ToolboxPolicies.java","src/main/java/com/azure/ai/agents/models/ToolboxSearchPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolboxShellContainerAutoEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellContainerReferenceEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellEnvironment.java","src/main/java/com/azure/ai/agents/models/ToolboxShellNetworkPolicy.java","src/main/java/com/azure/ai/agents/models/ToolboxShellNetworkPolicyDisabled.java","src/main/java/com/azure/ai/agents/models/ToolboxSkill.java","src/main/java/com/azure/ai/agents/models/ToolboxSkillReference.java","src/main/java/com/azure/ai/agents/models/ToolboxTool.java","src/main/java/com/azure/ai/agents/models/ToolboxToolType.java","src/main/java/com/azure/ai/agents/models/ToolboxVersionDetails.java","src/main/java/com/azure/ai/agents/models/ToolboxVersions.java","src/main/java/com/azure/ai/agents/models/TwilioTelephonyBinding.java","src/main/java/com/azure/ai/agents/models/TwilioTelephonyBindingListItem.java","src/main/java/com/azure/ai/agents/models/UpdateAgentDetailsOptions.java","src/main/java/com/azure/ai/agents/models/UpdateTelephonyBindingInput.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationAudioEffect.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationAudioEffectsConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationDefaultInterruptionConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationInterruptionConfiguration.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationTestCase.java","src/main/java/com/azure/ai/agents/models/UserConversationSimulationUserBehaviorConfiguration.java","src/main/java/com/azure/ai/agents/models/UserProfileMemoryItem.java","src/main/java/com/azure/ai/agents/models/VersionIndicator.java","src/main/java/com/azure/ai/agents/models/VersionIndicatorType.java","src/main/java/com/azure/ai/agents/models/VersionRefIndicator.java","src/main/java/com/azure/ai/agents/models/VersionSelectionRule.java","src/main/java/com/azure/ai/agents/models/VersionSelector.java","src/main/java/com/azure/ai/agents/models/VersionSelectorType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAnimationConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAnimationOutputType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioInputConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioOutputConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAudioTimestampType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarIceServer.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarOutputProtocol.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarScene.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoBackground.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoCrop.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoParameters.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAvatarVideoResolution.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadEnglishTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadMultilingualTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentAzureSemanticVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentBaseDefinition.java","src/main/java/com/azure/ai/agents/models/VoiceAgentCollectDtmfSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentCollectSmsSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentDefinition.java","src/main/java/com/azure/ai/agents/models/VoiceAgentDelegateSubagentConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentDigitRecognitionSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEchoCancellation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEchoCancellationReferenceSource.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndConversationSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceDetectionModel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEndOfUtteranceThresholdLevel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentEventGridPostCallDestination.java","src/main/java/com/azure/ai/agents/models/VoiceAgentFunctionTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentGreetingMode.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffAbortReason.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffCondition.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffEdgeState.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffNodeState.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPipelineFamily.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffPolicy.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffReasoningEffort.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffState.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffTargetResponse.java","src/main/java/com/azure/ai/agents/models/VoiceAgentHandoffVoiceAdaptation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInlineSubagentConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionChannel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatus.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputCollectionStatusEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscription.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInputTranscriptionModel.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseTrigger.java","src/main/java/com/azure/ai/agents/models/VoiceAgentInterimResponseType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLanguageDetectionSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveClientDelegationConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveConversationItemType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDefinition.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationResultItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationStatus.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationTarget.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveDelegationType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveFoundryManagedAgentDelegationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveInputConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveManagedAgentDelegation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveOutputConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegation.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationConversationItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentLlmInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentMcpTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentNoiseReduction.java","src/main/java/com/azure/ai/agents/models/VoiceAgentNoiseReductionType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestination.java","src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallDestinationType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentPostCallIncludeOption.java","src/main/java/com/azure/ai/agents/models/VoiceAgentProfanityFilterMode.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponse.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationBlendshapeDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationBlendshapeDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationVisemeDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAnimationVisemeDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioConfig.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseAudioTimestampDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptions.java","src/main/java/com/azure/ai/agents/models/VoiceAgentResponseVideoDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRoutinePostCallDestination.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorDetails.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallErrorType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallSdpCreateEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentRtcCallSdpCreatedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSemanticVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSendDtmfSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSendSmsSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentServerVadTurnDetection.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConnectEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarConnectingEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarSwitchToIdleEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionAvatarSwitchToSpeakingEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffAbortedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffCompletedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionHandoffStartedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionIncludeOption.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentAbortedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentCompletedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionSubagentStartedEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeSound.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeSourceConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeTrackConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSoundscapeWorkingTrackConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentStaticInterimResponseConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubProtocol.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentAbortReason.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentResponsePolicy.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSubagentType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDeltaEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolArgumentsDoneEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItem.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemObjectType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolItemStatus.java","src/main/java/com/azure/ai/agents/models/VoiceAgentSystemToolName.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTemplateGreetingConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentToolResponseScheduling.java","src/main/java/com/azure/ai/agents/models/VoiceAgentToolType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentToolboxTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTranscriptionPhrase.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTranscriptionWord.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestination.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferDestinationType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferRouting.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferStrategy.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferSystemTool.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransferTarget.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTransport.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTurnDetectionConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentTurnDetectionType.java","src/main/java/com/azure/ai/agents/models/VoiceAgentVoiceConfiguration.java","src/main/java/com/azure/ai/agents/models/VoiceAgentWarningDetails.java","src/main/java/com/azure/ai/agents/models/VoiceAgentWarningEvent.java","src/main/java/com/azure/ai/agents/models/VoiceAudioCodec.java","src/main/java/com/azure/ai/agents/models/VoiceAudioContainerFormat.java","src/main/java/com/azure/ai/agents/models/VoiceAudioItem.java","src/main/java/com/azure/ai/agents/models/VoiceAudioRole.java","src/main/java/com/azure/ai/agents/models/VoiceConversation.java","src/main/java/com/azure/ai/agents/models/VoiceConversationEngine.java","src/main/java/com/azure/ai/agents/models/VoiceConversationEngineType.java","src/main/java/com/azure/ai/agents/models/VoiceConversationStatus.java","src/main/java/com/azure/ai/agents/models/VoiceGeneratedAudioItem.java","src/main/java/com/azure/ai/agents/models/VoiceHostedAgentConversationEngine.java","src/main/java/com/azure/ai/agents/models/VoiceModelType.java","src/main/java/com/azure/ai/agents/models/VoiceOutputModality.java","src/main/java/com/azure/ai/agents/models/VoiceRecording.java","src/main/java/com/azure/ai/agents/models/VoiceRecordingChannelLayout.java","src/main/java/com/azure/ai/agents/models/VoiceResponse.java","src/main/java/com/azure/ai/agents/models/VoiceResponseAudio.java","src/main/java/com/azure/ai/agents/models/VoiceResponseAudioOutput.java","src/main/java/com/azure/ai/agents/models/VoiceResponseObjectType.java","src/main/java/com/azure/ai/agents/models/VoiceType.java","src/main/java/com/azure/ai/agents/models/WebIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/WebIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/WebSearchApproximateLocation.java","src/main/java/com/azure/ai/agents/models/WebSearchConfiguration.java","src/main/java/com/azure/ai/agents/models/WebSearchPreviewTool.java","src/main/java/com/azure/ai/agents/models/WebSearchTool.java","src/main/java/com/azure/ai/agents/models/WebSearchToolFilters.java","src/main/java/com/azure/ai/agents/models/WebSearchToolSearchContextSize.java","src/main/java/com/azure/ai/agents/models/WebSearchToolboxTool.java","src/main/java/com/azure/ai/agents/models/WorkIqPreviewTool.java","src/main/java/com/azure/ai/agents/models/WorkIqPreviewToolboxTool.java","src/main/java/com/azure/ai/agents/models/WorkflowAgentDefinition.java","src/main/java/com/azure/ai/agents/models/package-info.java","src/main/java/com/azure/ai/agents/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/ReadmeSamples.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/ReadmeSamples.java index f7884be7b05e1..4cf121f591473 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/ReadmeSamples.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/ReadmeSamples.java @@ -10,6 +10,7 @@ import com.azure.ai.agents.models.RawRealtimeServerEvent; import com.azure.ai.agents.models.RealtimeServerEvent; import com.azure.ai.agents.models.SessionLogEvent; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; import com.azure.ai.agents.models.VoiceAgentWebSocketOverflowStrategy; import com.azure.core.util.BinaryData; @@ -25,16 +26,45 @@ import com.openai.models.responses.Response; import com.openai.models.responses.ResponseCreateParams; import com.openai.services.blocking.ConversationService; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ResponseCreateEvent; +import com.openai.models.live.ServerEvent; +import java.time.Duration; public final class ReadmeSamples { - public void realtimeForwardCompatibility(BetaVoiceAgentWebSocketClient realtimeClient, String agentName) { + public void liveConnectionOptions(AgentsClientBuilder builder, String agentName) { + // BEGIN: readme-sample-com.azure.ai.agents.live_connection_options + BetaVoiceAgentsLiveWebSocketClient liveClient = builder.beta().buildBetaVoiceAgentsLiveWebSocketClient(); + VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions() + .setReceiveBufferCapacity(512) + .setMaxMessageSize(8 * 1024 * 1024) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR) + .setHandshakeTimeout(Duration.ofSeconds(30)) + .setCloseTimeout(Duration.ofSeconds(10)) + .setStoreEnabled(false); + + try (BetaVoiceAgentsLiveWebSocketSessionClient session = liveClient.openWebSocketSession(agentName, options)) { + for (ServerEvent event : session.receiveEvents()) { + if (event.isSessionStarted()) { + session.sendEvent(ClientEvent.ofResponseCreate(ResponseCreateEvent.builder().build())); + } else if (event.isSessionOutputTranscriptDelta()) { + System.out.print(event.asSessionOutputTranscriptDelta().delta()); + } else if (event.isSessionClosed() || event.isErrorEvent()) { + break; + } + } + } + // END: readme-sample-com.azure.ai.agents.live_connection_options + } + + public void realtimeForwardCompatibility(BetaVoiceAgentsWebSocketClient realtimeClient, String agentName) { // BEGIN: com.azure.ai.agents.realtime_forward_compatibility VoiceAgentWebSocketConnectionOptions options = new VoiceAgentWebSocketConnectionOptions() .setReceiveBufferCapacity(512) .setMaxMessageSize(8 * 1024 * 1024) .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR); - try (BetaVoiceAgentWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName, options)) { + try (BetaVoiceAgentsWebSocketSessionClient session = realtimeClient.openWebSocketSession(agentName, options)) { session.sendEvent(BinaryData.fromString( "{\"type\":\"response.create\",\"event_id\":\"response-1\"}")); for (RealtimeServerEvent event : session.receiveEvents()) { diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveAudioConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveAudioConversationAsyncSample.java new file mode 100644 index 0000000000000..0052dc75718ba --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveAudioConversationAsyncSample.java @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionAsyncClient; +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; +import com.openai.models.live.ServerEvent; +import java.io.InputStream; +import java.util.concurrent.atomic.AtomicBoolean; +import reactor.core.publisher.Sinks; + + +/** + * Streams microphone and speaker audio over a native GPT Live WebSocket. + * Requires Java Sound devices supporting 24-kHz mono PCM16LE. Press Enter to finish. + * Audio capture and playback run on dedicated threads, not the WebSocket receive thread. + * Playback is bounded to 60 seconds; overflow and device failures terminate the call explicitly. + * The uniquely named agent is deleted unless FOUNDRY_KEEP_GPT_LIVE_AGENT=true. + * Requests an opening greeting and labels spoken transcripts by speaker. + * The standalone main method shuts down shared Reactor schedulers on exit; do not invoke it inside a shared application. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - The Azure AI Project endpoint.
  • + *
  • {@code FOUNDRY_GPT_LIVE_MODEL} - Optional. The GPT Live deployment name. Defaults to {@code gpt-live-1}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_BACKEND_MODEL} - Optional. The Responses backend deployment name in the Live + * resource. Defaults to {@code gpt-5.6-terra}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_STORE} - Optional. Set to {@code true} to persist conversation content and audio + * and request a Foundry conversation ID. Defaults to {@code false}. Also keep the agent for later REST reads.
  • + *
  • {@code FOUNDRY_KEEP_GPT_LIVE_AGENT} - Optional. Set to {@code true} to keep the agent after the sample. + * Defaults to {@code false}.
  • + *
+ */ +public class GptLiveAudioConversationAsyncSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = configuration.get("FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + boolean store = Boolean.parseBoolean(configuration.get("FOUNDRY_GPT_LIVE_STORE", "false")); + + if (endpoint == null || endpoint.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_PROJECT_ENDPOINT before running this sample."); + } + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_MODEL before running this sample."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_BACKEND_MODEL before running this sample."); + } + + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .allowPreview(true); + try (GptLiveSampleUtils.AgentResource agent + = GptLiveSampleUtils.createAgent(builder, model, backendModel, "audio-async", false, keepAgent)) { + Mono.usingWhen(agent.builder.beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession(agent.name, new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store)), + GptLiveAudioConversationAsyncSample::runAudioConversationAsync, + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync, + (session, error) -> session.closeAsync(), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync).block(); + } finally { + Schedulers.shutdownNow(); + } + } + + static Mono runAudioConversationAsync(BetaVoiceAgentsLiveWebSocketSessionAsyncClient session) { + return Mono.defer(() -> runAudioConversationAsync(session, + new GptLiveSampleUtils.AudioProcessor( + null, null, pcm -> session.sendEvent(GptLiveSampleUtils.audio(pcm.toBytes()))), System.in)); + } + + static Mono runAudioConversationAsync(BetaVoiceAgentsLiveWebSocketSessionAsyncClient session, + GptLiveSampleUtils.AudioProcessor processor, InputStream input) { + return Mono.usingWhen(Mono.just(processor), + audio -> Mono.firstWithSignal(runAudioSession(session, audio, input), audio.failureSignalAsync()), + GptLiveAudioConversationAsyncSample::closeAudioAsync, + (audio, error) -> closeAudioAsync(audio), GptLiveAudioConversationAsyncSample::closeAudioAsync); + } + + private static Mono closeAudioAsync(GptLiveSampleUtils.AudioProcessor audio) { + return Mono.fromRunnable(audio::close).subscribeOn(Schedulers.boundedElastic()); + } + + private static Mono runAudioSession(BetaVoiceAgentsLiveWebSocketSessionAsyncClient session, + GptLiveSampleUtils.AudioProcessor audio, InputStream input) { + return Mono.defer(() -> { + GptLiveSampleUtils.AudioTranscriptPrinter transcripts = new GptLiveSampleUtils.AudioTranscriptPrinter(false, false); + Sinks.Empty ready = Sinks.empty(); + Sinks.Empty closed = Sinks.empty(); + AtomicBoolean started = new AtomicBoolean(); + AtomicBoolean finalized = new AtomicBoolean(); + Mono receive = session.receiveEvents() + .publishOn(Schedulers.boundedElastic(), 1) + .takeUntil(ServerEvent::isSessionClosed) + .doOnNext(event -> { + transcripts.print(event); + if (event.isSessionOutputAudioDelta()) { + audio.queueAudio(GptLiveSampleUtils.decodeAudio(event)); + } + if (event.isSessionStarted()) { + if (!started.compareAndSet(false, true)) { + throw new IllegalStateException("Duplicate session.started event."); + } + audio.start(); + ready.tryEmitEmpty(); + } else if (event.isResponseEvent() && !started.get() + && GptLiveSampleUtils.backendEvent(event).isCompleted()) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } else if (event.isSessionClosed()) { + finalized.set(true); + System.out.println("Live session closed (" + event.asSessionClosed().reason() + ")."); + closed.tryEmitEmpty(); + } + }).then(Mono.defer(() -> finalized.get() ? Mono.empty() + : Mono.error(new IllegalStateException("GPT Live disconnected without session.closed.")))); + Mono conversation = ready.asMono().timeout(GptLiveSampleUtils.TIMEOUT) + .then(Mono.defer(() -> session.sendEvent(GptLiveSampleUtils.userMessage( + "Greet me briefly with: Hi, how can I help you today?")) + .then(session.sendEvent(GptLiveSampleUtils.responseCreate())) + .timeout(GptLiveSampleUtils.TIMEOUT))) + .then(Mono.fromRunnable(() -> System.out.println( + "Opening greeting requested. Speak into the microphone. Press Enter to end the call."))) + .then(VoiceAgentLiveAudioConversationAsyncSample.waitForEnter(input)) + .then(closeAudioAsync(audio)) + .then(Mono.defer(() -> session.sendEvent(GptLiveSampleUtils.closeSession()) + .then(closed.asMono()).timeout(GptLiveSampleUtils.TIMEOUT))); + return Mono.firstWithSignal(receive, conversation); + }); + } + +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveFunctionToolSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveFunctionToolSample.java new file mode 100644 index 0000000000000..beb84b53d35f2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveFunctionToolSample.java @@ -0,0 +1,201 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionClient; +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.openai.core.JsonValue; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.FunctionTool; +import com.openai.models.live.ResponseItemCreateEvent; +import com.openai.models.live.ServerEvent; +import com.openai.models.responses.ResponseInputItem; +import com.openai.models.responses.ResponseFunctionToolCall; +import com.openai.models.responses.ResponseStreamEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; + +/** + * Executes a sample weather function requested by the GPT Live Responses backend. + * Weather results are explicitly simulated, not a call to a weather service. + * Uses response.event envelopes and native response.item.create function_call_output items. + * This is Responses delegation, not Foundry-managed-agent tool-result routing. + * The uniquely named agent is deleted unless FOUNDRY_KEEP_GPT_LIVE_AGENT=true. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - The Azure AI Project endpoint.
  • + *
  • {@code FOUNDRY_GPT_LIVE_MODEL} - Optional. The GPT Live deployment name. Defaults to {@code gpt-live-1}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_BACKEND_MODEL} - Optional. The Responses backend deployment name in the Live + * resource. Defaults to {@code gpt-5.6-terra}.
  • + *
  • {@code FOUNDRY_KEEP_GPT_LIVE_AGENT} - Optional. Set to {@code true} to keep the agent after the sample. + * Defaults to {@code false}.
  • + *
+ */ +public class GptLiveFunctionToolSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = configuration.get("FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + + if (endpoint == null || endpoint.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_PROJECT_ENDPOINT before running this sample."); + } + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_MODEL before running this sample."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_BACKEND_MODEL before running this sample."); + } + + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .allowPreview(true); + try (GptLiveSampleUtils.AgentResource agent + = GptLiveSampleUtils.createAgent(builder, model, backendModel, "tools", true, keepAgent); + BetaVoiceAgentsLiveWebSocketSessionClient session = agent.builder.beta() + .buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession(agent.name)) { + runConversation(session, + Collections.singletonList(args.length == 0 ? "What is the weather in Seattle?" : args[0]), + GptLiveFunctionToolSample::toolResult); + } + } + + static void runConversation(BetaVoiceAgentsLiveWebSocketSessionClient session, List prompts, + Function toolHandler) { + Iterator pending = prompts.iterator(); + List results = new ArrayList<>(); + boolean started = false; + boolean awaitingResponse = false; + boolean closing = false; + int continuations = 0; + for (ServerEvent event : session.receiveEvents(GptLiveSampleUtils.TIMEOUT)) { + GptLiveSampleUtils.printEvent(event); + boolean nextTurn = false; + if (event.isSessionStarted()) { + if (started) { + throw new IllegalStateException("Duplicate session.started event."); + } + started = true; + nextTurn = true; + } else if (event.isResponseEvent()) { + ResponseStreamEvent response = GptLiveSampleUtils.backendEvent(event); + if (response.isOutputItemDone() && response.asOutputItemDone().item().isFunctionCall()) { + ResponseFunctionToolCall call = response.asOutputItemDone().item().asFunctionCall(); + results.add(toolHandler.apply(call)); + } else if (response.isCompleted()) { + if (!started || !awaitingResponse || closing) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } + if (!results.isEmpty()) { + if (++continuations > 8) { + throw new IllegalStateException("Sample tool continuation limit exceeded."); + } + for (ClientEvent result : results) { + session.sendEvent(result); + } + results.clear(); + session.sendEvent(GptLiveSampleUtils.responseCreate()); + } else { + continuations = 0; + awaitingResponse = false; + System.out.println(); + nextTurn = true; + } + } + } else if (event.isSessionClosed()) { + String reason = event.asSessionClosed().reason().toString(); + if (!(started && "remote_hangup".equals(reason)) + && !(closing && "close_requested".equals(reason))) { + throw new IllegalStateException("GPT Live closed before all turns completed. Event: " + event + + "; transport close code=" + session.getCloseCode() + ", reason=" + session.getCloseReason()); + } + System.out.println("Live session closed (" + reason + ")."); + return; + } + if (nextTurn) { + if (pending.hasNext()) { + String prompt = pending.next(); + System.out.println("You: " + prompt); + System.out.print("Assistant: "); + awaitingResponse = true; + session.sendEvent(GptLiveSampleUtils.userMessage(prompt)); + session.sendEvent(GptLiveSampleUtils.responseCreate()); + } else { + closing = true; + session.sendEvent(GptLiveSampleUtils.closeSession()); + } + } + } + throw new IllegalStateException("GPT Live disconnected without session.closed."); + } + + static FunctionTool weatherTool() { + FunctionTool.Parameters schema = FunctionTool.Parameters.builder() + .putAdditionalProperty("type", JsonValue.from("object")) + .putAdditionalProperty("properties", JsonValue.from( + Collections.singletonMap("city", Collections.singletonMap("type", "string")))) + .putAdditionalProperty("required", JsonValue.from(Collections.singletonList("city"))) + .putAdditionalProperty("additionalProperties", JsonValue.from(false)) + .build(); + return FunctionTool.builder().name("get_weather") + .description("Get simulated weather for a city. This sample returns demonstration data only.") + .parameters(schema) + .strict(true) + .build(); + } + + static ClientEvent toolResult(ResponseFunctionToolCall call) { + if (!"get_weather".equals(call.name())) { + throw new IllegalArgumentException("Unsupported sample tool: " + call.name()); + } + Map arguments = object( + BinaryData.fromString(call.arguments())); + Map result = new LinkedHashMap<>(); + result.put("city", string(arguments, "city")); + result.put("condition", "sunny"); + result.put("temperature_f", 72); + result.put("simulated", true); + return ClientEvent.ofResponseItemCreate(ResponseItemCreateEvent.builder() + .item(ResponseInputItem.FunctionCallOutput.builder() + .callId(call.callId()) + .output(BinaryData.fromObject(result).toString()) + .build()) + .build()); + } + + static Map object(BinaryData data) { + return data.toObject(Map.class); + } + + static Map object(Object value) { + if (!(value instanceof Map)) { + throw new IllegalArgumentException("Expected a native Live JSON object: " + value); + } + return (Map) value; + } + + static String string(Map event, String field) { + Object value = event.get(field); + if (!(value instanceof String)) { + throw new IllegalArgumentException("Missing or invalid Live event field: " + field); + } + return (String) value; + } + +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationAsyncSample.java new file mode 100644 index 0000000000000..73bace02e2a3b --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationAsyncSample.java @@ -0,0 +1,195 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionAsyncClient; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ServerEvent; +import com.openai.models.responses.ResponseStreamEvent; +import java.io.BufferedReader; +import java.io.Console; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; +import reactor.core.scheduler.Schedulers; + +/** + * Advanced asynchronous console conversation with speaker playback and frontend transcripts. + * Uses the same settings as {@link GptLiveTextConversationAsyncSample}. Blocking device and console work runs + * off the WebSocket thread. Silent PCM input while typing consumes voice-session usage. + * Greeting completion uses a one-second speech-inactivity heuristic and speaker drain. + * Blank input, EOF, exit, or quit requests graceful closure. A noninterruptible console read may require Enter + * after remote closure. Standard input is not closed. The standalone main shuts down shared Reactor schedulers. + */ +public class GptLiveInteractiveTextConversationAsyncSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("FOUNDRY_GPT_LIVE_MODEL must not be blank."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("FOUNDRY_GPT_LIVE_BACKEND_MODEL must not be blank."); + } + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + boolean store = Boolean.parseBoolean(configuration.get("FOUNDRY_GPT_LIVE_STORE", "false")); + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()).allowPreview(true); + Console console = System.console(); + try (GptLiveSampleUtils.AgentResource agent + = GptLiveSampleUtils.createAgent(builder, model, backendModel, "interactive-async", false, keepAgent)) { + Mono.usingWhen(builder.beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession(agent.name, new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store)), + session -> Mono.usingWhen( + Mono.fromCallable(VoiceAgentRealtimeSampleUtils.SpeakerPlayer::new) + .subscribeOn(Schedulers.boundedElastic()), + player -> runInteractiveConversationAsync(session, + console == null ? new InputStreamReader(System.in) : console.reader(), player::play, player::drain), + player -> Mono.fromRunnable(player::close).subscribeOn(Schedulers.boundedElastic())), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync, + (session, error) -> session.closeAsync(), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync).block(); + } finally { + Schedulers.shutdownNow(); + } + } + + static Mono runInteractiveConversationAsync(BetaVoiceAgentsLiveWebSocketSessionAsyncClient session, Reader input, + Consumer playAudio, Runnable drainAudio) { + return Mono.defer(() -> runInteractiveConversationAsync(session.receiveEvents(), session::sendEvent, + () -> "transport close code=" + session.getCloseCode() + ", reason=" + session.getCloseReason(), + input, playAudio, drainAudio)); + } + + static Mono runInteractiveConversationAsync(Flux events, + Function> sendEvent, Supplier closeDetails, Reader input, + Consumer playAudio, Runnable drainAudio) { + return Mono.defer(() -> { + System.out.println("Type a message and press Enter. Blank line, 'exit' or 'quit' ends the session."); + System.out.println("Interactive voice streams silent audio while you type; voice usage is billable."); + BufferedReader console = input instanceof BufferedReader ? (BufferedReader) input : new BufferedReader(input); + GptLiveSampleUtils.AudioTranscriptPrinter transcripts + = new GptLiveSampleUtils.AudioTranscriptPrinter(System.console() != null, true); + GptLiveSampleUtils.Greeting greeting = new GptLiveSampleUtils.Greeting(); + Sinks.Empty ready = Sinks.empty(); + Sinks.Empty closed = Sinks.empty(); + Sinks.Empty audioStarted = Sinks.empty(); + Sinks.Empty stopAudio = Sinks.empty(); + Sinks.Empty audioStopped = Sinks.empty(); + AtomicBoolean started = new AtomicBoolean(); + AtomicBoolean closing = new AtomicBoolean(); + AtomicBoolean finalized = new AtomicBoolean(); + AtomicBoolean remoteHangup = new AtomicBoolean(); + AtomicReference> responseCompleted = new AtomicReference<>(); + Mono receive = events.publishOn(Schedulers.boundedElastic(), 1) + .takeUntil(ServerEvent::isSessionClosed) + .doOnNext(event -> { + transcripts.print(event); + if (event.isSessionOutputAudioDelta()) { + byte[] pcm = GptLiveSampleUtils.decodeAudio(event); + playAudio.accept(pcm); + greeting.onAudio(pcm); + } else if (event.isSessionOutputTranscriptDelta() + && !event.asSessionOutputTranscriptDelta().delta().trim().isEmpty()) { + greeting.onTranscript(); + } + if (event.isSessionStarted()) { + if (!started.compareAndSet(false, true)) { + throw new IllegalStateException("Duplicate session.started event."); + } + ready.tryEmitEmpty(); + } else if (event.isResponseEvent()) { + ResponseStreamEvent response = GptLiveSampleUtils.backendEvent(event); + if (response.isCompleted()) { + Sinks.Empty completion = responseCompleted.getAndSet(null); + if (!started.get() || (completion != null && closing.get())) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } + if (completion != null) { + completion.tryEmitEmpty(); + } + } + } else if (event.isSessionClosed()) { + String reason = event.asSessionClosed().reason().toString(); + remoteHangup.set(started.get() && "remote_hangup".equals(reason)); + if (!remoteHangup.get() && !(closing.get() && "close_requested".equals(reason))) { + throw new IllegalStateException("GPT Live closed before all turns completed. Event: " + + event + "; " + closeDetails.get()); + } + finalized.set(true); + System.out.println("Live session closed (" + reason + ")."); + closed.tryEmitEmpty(); + } + }) + .then(Mono.defer(() -> { + if (!finalized.get()) { + return Mono.error(new IllegalStateException("GPT Live disconnected without session.closed.")); + } + return remoteHangup.get() ? Mono.empty() : Mono.never(); + })); + Mono audio = ready.asMono() + .thenMany(GptLiveSampleUtils.silenceFramesAsync().takeUntilOther(stopAudio.asMono()) + .concatMap(frame -> sendEvent.apply(frame).doOnSuccess(ignored -> audioStarted.tryEmitEmpty()), 1)) + .then().doOnSuccess(ignored -> audioStopped.tryEmitEmpty()).then(Mono.never()); + Mono renderTranscripts = greeting.quietPeriodsAsync() + .doOnNext(ignored -> transcripts.endUtterance()).then(); + Mono conversation = ready.asMono().timeout(GptLiveSampleUtils.TIMEOUT) + .then(audioStarted.asMono().timeout(GptLiveSampleUtils.TIMEOUT)) + .then(Mono.defer(() -> sendEvent.apply(GptLiveSampleUtils.commentary("Hi, how can I help you today?")))) + .timeout(GptLiveSampleUtils.TIMEOUT) + .then(greeting.awaitPlaybackAsync(drainAudio)) + .then(Mono.fromRunnable(transcripts::endUtterance)) + .then(Mono.defer(() -> readTurns(console, transcripts, sendEvent, responseCompleted))) + .then(Mono.defer(() -> { + closing.set(true); + stopAudio.tryEmitEmpty(); + return audioStopped.asMono().then(sendEvent.apply(GptLiveSampleUtils.closeSession())) + .then(closed.asMono()).timeout(GptLiveSampleUtils.TIMEOUT); + })); + return Mono.firstWithSignal(receive, audio, renderTranscripts, conversation) + .doFinally(ignored -> transcripts.endInput()); + }); + } + + static Mono readPromptAsync(Reader input) { + return readPromptAsync(input, new GptLiveSampleUtils.AudioTranscriptPrinter()); + } + + private static Mono readPromptAsync(Reader input, GptLiveSampleUtils.AudioTranscriptPrinter transcripts) { + return Mono.defer(() -> { + BufferedReader reader = input instanceof BufferedReader ? (BufferedReader) input : new BufferedReader(input); + return Mono.fromCallable(() -> GptLiveSampleUtils.readPromptBlocking(reader, transcripts)) + .subscribeOn(Schedulers.boundedElastic()).doOnCancel(transcripts::endInput); + }); + } + + private static Mono readTurns(Reader input, GptLiveSampleUtils.AudioTranscriptPrinter transcripts, + Function> sendEvent, AtomicReference> responseCompleted) { + return readPromptAsync(input, transcripts).flatMap(text -> { + Sinks.Empty completion = Sinks.empty(); + responseCompleted.set(completion); + return sendEvent.apply(GptLiveSampleUtils.userMessage(text)) + .then(sendEvent.apply(GptLiveSampleUtils.responseCreate())) + .then(completion.asMono()).timeout(GptLiveSampleUtils.TIMEOUT) + .then(Mono.defer(() -> readTurns(input, transcripts, sendEvent, responseCompleted))); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationSample.java new file mode 100644 index 0000000000000..4a7c0790e43e2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveInteractiveTextConversationSample.java @@ -0,0 +1,217 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionClient; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ServerEvent; +import com.openai.models.responses.ResponseStreamEvent; +import java.io.BufferedReader; +import java.io.Console; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import reactor.core.scheduler.Schedulers; + +/** + * Advanced synchronous console conversation with spoken greetings, speaker playback, and frontend transcripts. + * Uses the same environment variables as {@link GptLiveTextConversationSample}. + * Silent PCM input keeps the voice session active while typing and consumes voice-session usage. + * Greeting and transcript boundaries use a one-second speech-inactivity heuristic, not a service completion event. + * Blank input, EOF, exit, or quit requests graceful closure. A noninterruptible console read may require Enter + * after remote closure. Standard input is not closed. The standalone main shuts down shared Reactor schedulers. + */ +public class GptLiveInteractiveTextConversationSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("FOUNDRY_GPT_LIVE_MODEL must not be blank."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("FOUNDRY_GPT_LIVE_BACKEND_MODEL must not be blank."); + } + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + boolean store = Boolean.parseBoolean(configuration.get("FOUNDRY_GPT_LIVE_STORE", "false")); + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()).allowPreview(true); + Console console = System.console(); + try (GptLiveSampleUtils.AgentResource agent + = GptLiveSampleUtils.createAgent(builder, model, backendModel, "interactive", false, keepAgent); + BetaVoiceAgentsLiveWebSocketSessionClient session = builder.beta() + .buildBetaVoiceAgentsLiveWebSocketClient() + .openWebSocketSession(agent.name, new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store)); + VoiceAgentRealtimeSampleUtils.SpeakerPlayer player = new VoiceAgentRealtimeSampleUtils.SpeakerPlayer()) { + runInteractiveConversation(session, console == null ? new InputStreamReader(System.in) : console.reader(), + player::play, player::drain); + player.drain(); + } finally { + Schedulers.shutdownNow(); + } + } + + static void runInteractiveConversation(BetaVoiceAgentsLiveWebSocketSessionClient session, Reader input, + Consumer playAudio, Runnable drainAudio) { + System.out.println("Type a message and press Enter. Blank line, 'exit' or 'quit' ends the session."); + System.out.println("Interactive voice streams silent audio while you type; voice usage is billable."); + BufferedReader console = input instanceof BufferedReader ? (BufferedReader) input : new BufferedReader(input); + ExecutorService workers = Executors.newFixedThreadPool(2, task -> { + Thread thread = new Thread(task, "gpt-live-interactive-text"); + thread.setDaemon(true); + return thread; + }); + BlockingQueue pending = new LinkedBlockingQueue<>(256); + AtomicReference receiveFailure = new AtomicReference<>(); + AtomicBoolean receiveEnded = new AtomicBoolean(); + GptLiveSampleUtils.AudioTranscriptPrinter transcripts + = new GptLiveSampleUtils.AudioTranscriptPrinter(System.console() != null, true); + Future receiver = workers.submit(() -> { + try { + for (ServerEvent event : session.receiveEvents(GptLiveSampleUtils.TIMEOUT)) { + pending.put(event); + if (event.isSessionClosed()) { + break; + } + } + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + } catch (RuntimeException error) { + receiveFailure.set(error); + } finally { + receiveEnded.set(true); + } + }); + Future prompt = null; + boolean started = false; + boolean awaitingResponse = false; + boolean closing = false; + boolean greetingComplete = false; + boolean greetingAudio = false; + boolean greetingTranscript = false; + long deadline = System.nanoTime() + GptLiveSampleUtils.TIMEOUT.toNanos(); + long nextAudio = 0; + long quietSince = 0; + ClientEvent silence = GptLiveSampleUtils.audio(new byte[960]); + try { + while (true) { + ServerEvent event = pending.poll(20, TimeUnit.MILLISECONDS); + long now = System.nanoTime(); + if (event != null) { + transcripts.print(event); + if (event.isSessionOutputAudioDelta()) { + byte[] pcm = GptLiveSampleUtils.decodeAudio(event); + playAudio.accept(pcm); + if (GptLiveSampleUtils.hasSpeech(pcm)) { + greetingAudio = true; + quietSince = now; + } + } else if (event.isSessionOutputTranscriptDelta() + && !event.asSessionOutputTranscriptDelta().delta().trim().isEmpty()) { + greetingTranscript = true; + quietSince = now; + } + if (event.isSessionStarted()) { + if (started) { + throw new IllegalStateException("Duplicate session.started event."); + } + started = true; + session.sendEvent(silence); + nextAudio = now + TimeUnit.MILLISECONDS.toNanos(20); + session.sendEvent(GptLiveSampleUtils.commentary("Hi, how can I help you today?")); + } else if (event.isResponseEvent()) { + ResponseStreamEvent response = GptLiveSampleUtils.backendEvent(event); + if (response.isCompleted()) { + if (!started || (awaitingResponse && closing)) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } + awaitingResponse = false; + } + } else if (event.isSessionClosed()) { + String reason = event.asSessionClosed().reason().toString(); + if (!(started && "remote_hangup".equals(reason)) + && !(closing && "close_requested".equals(reason))) { + throw new IllegalStateException("GPT Live closed before all turns completed. Event: " + + event + "; transport close code=" + session.getCloseCode() + + ", reason=" + session.getCloseReason()); + } + System.out.println("Live session closed (" + reason + ")."); + return; + } + } else if (receiveEnded.get()) { + if (receiveFailure.get() != null) { + throw receiveFailure.get(); + } + throw new IllegalStateException("GPT Live disconnected without session.closed."); + } + if (started && !closing && now >= nextAudio) { + session.sendEvent(silence); + nextAudio = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(20); + } + if (greetingAudio && greetingTranscript && quietSince != 0 + && now - quietSince >= TimeUnit.SECONDS.toNanos(1)) { + transcripts.endUtterance(); + quietSince = 0; + if (!greetingComplete) { + drainAudio.run(); + greetingComplete = true; + } + } + boolean canReadPrompt = started && greetingComplete && !awaitingResponse && !closing; + if (canReadPrompt && prompt == null) { + prompt = workers.submit(() -> GptLiveSampleUtils.readPromptBlocking(console, transcripts)); + } + if (prompt != null && prompt.isDone()) { + String text = prompt.get(); + prompt = null; + deadline = System.nanoTime() + GptLiveSampleUtils.TIMEOUT.toNanos(); + if (text == null) { + closing = true; + session.sendEvent(GptLiveSampleUtils.closeSession()); + } else { + awaitingResponse = true; + session.sendEvent(GptLiveSampleUtils.userMessage(text)); + session.sendEvent(GptLiveSampleUtils.responseCreate()); + } + } + if (!canReadPrompt && now >= deadline) { + throw new IllegalStateException("Timed out waiting for the GPT Live conversation."); + } + } + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("GPT Live conversation interrupted.", error); + } catch (ExecutionException error) { + if (error.getCause() instanceof RuntimeException) { + throw (RuntimeException) error.getCause(); + } + throw new IllegalStateException("Unable to read console input.", error.getCause()); + } finally { + receiver.cancel(true); + if (prompt != null) { + prompt.cancel(true); + } + transcripts.endInput(); + workers.shutdownNow(); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAsyncSample.java new file mode 100644 index 0000000000000..b5c267619953c --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAsyncSample.java @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient; +import com.azure.ai.agents.models.PageOrder; +import com.azure.ai.agents.models.VoiceAgentLiveConversation; +import com.azure.ai.agents.models.VoiceAgentLiveConversationItem; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Asynchronously reads persisted GPT Live conversations and transcript items. + * The session must have used {@code store=true}. The agent and conversation must still exist. + * Like {@link GptLiveReadConversationSample}, this sample prints sensitive stored content without modifying data. + * Blocking occurs only at the standalone main method boundary. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - Required. The Azure AI Project endpoint. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_AGENT_NAME} - Required. The existing GPT Live agent's name. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_CONVERSATION_ID} - Required. The persisted Foundry conversation ID from + * {@code session.started.conversation_id}, not the native session ID. No default.
  • + *
+ * + *

Authenticates with {@code DefaultAzureCredential}. Run without command-line arguments. + * Model deployment settings are not needed because this sample reads an existing conversation.

+ */ +public class GptLiveReadConversationAsyncSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String agentName = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_AGENT_NAME"); + String conversationId + = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_CONVERSATION_ID"); + BetaVoiceAgentsLiveConversationsAsyncClient client = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .addPolicy(GptLiveReadConversationSample.previewHeaders()) + .beta().buildBetaVoiceAgentsLiveConversationsAsyncClient(); + readConversation(client, agentName, conversationId).block(); + } + + static Mono readConversation(BetaVoiceAgentsLiveConversationsAsyncClient client, String agentName, + String conversationId) { + return listConversations(client, agentName, null) + .doOnNext(conversation -> System.out.printf("Available conversation: %s (%s)%n", + conversation.getId(), conversation.getStatus())) + .then(Mono.defer(() -> client.getAgentConversation(agentName, conversationId) + .doOnNext(GptLiveReadConversationSample::printConversation))) + .thenMany(listItems(client, agentName, conversationId, null)) + .concatMap(item -> client.getAgentConversationItem(agentName, conversationId, item.getId()), 0) + .doOnNext(GptLiveReadConversationSample::printItem) + .then(); + } + + private static Flux listConversations(BetaVoiceAgentsLiveConversationsAsyncClient client, + String agentName, String after) { + return client.listAgentConversations(agentName, 100, PageOrder.ASC, after, null).collectList() + .flatMapMany(page -> { + if (page.isEmpty()) { + return Flux.empty(); + } + String next = GptLiveReadConversationSample.nextCursor(page.get(page.size() - 1).getId(), after); + return Flux.fromIterable(page).concatWith(Flux.defer(() -> listConversations(client, agentName, next))); + }); + } + + private static Flux listItems(BetaVoiceAgentsLiveConversationsAsyncClient client, + String agentName, String conversationId, String after) { + return client.listAgentConversationItems(agentName, conversationId, 100, PageOrder.ASC, after, null).collectList() + .flatMapMany(page -> { + if (page.isEmpty()) { + return Flux.empty(); + } + String next = GptLiveReadConversationSample.nextCursor(page.get(page.size() - 1).getId(), after); + return Flux.fromIterable(page) + .concatWith(Flux.defer(() -> listItems(client, agentName, conversationId, next))); + }); + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioAsyncSample.java new file mode 100644 index 0000000000000..83325b3f132c9 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioAsyncSample.java @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveConversationsAsyncClient; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import java.nio.file.Path; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +/** + * Asynchronously downloads persisted GPT Live merged audio and optionally a speech item's WAV to new files. + * The session must have used {@code store=true}. The agent and conversation must still exist. + * Wait for recording finalization after the session ends. Like {@link GptLiveReadConversationAudioSample}, + * HTTP errors propagate and BYOS audio requires separate Azure Storage credentials. + * File writes run on boundedElastic, not an HTTP I/O thread. + * Blocking occurs only at the standalone main method boundary. Global Reactor schedulers are not shut down. + * No agent or persisted data is modified or deleted. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - Required. The Azure AI Project endpoint. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_AGENT_NAME} - Required. The existing GPT Live agent's name. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_CONVERSATION_ID} - Required. The persisted Foundry conversation ID from + * {@code session.started.conversation_id}, not the native session ID. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_ITEM_ID} - Optional. A speech item's ID, not a delegation item. + * Defaults to unset, downloading only the merged conversation audio. Explicitly blank values are invalid.
  • + *
+ * + *

To download an individual speech item's audio:

+ *
    + *
  1. Run {@link GptLiveReadConversationSample} with the same project endpoint, agent name, and conversation ID.
  2. + *
  3. Find the desired transcript in its output and copy the ID from the preceding + * {@code Item : type=input} or {@code Item : type=output} line. Do not select a delegation item.
  4. + *
  5. Set {@code FOUNDRY_GPT_LIVE_ITEM_ID} to that ID, then run this sample with an existing output directory + * as its sole command-line argument. It downloads both the merged call audio and the selected item's WAV.
  6. + *
+ *

For merged call audio only, skip the item lookup and leave {@code FOUNDRY_GPT_LIVE_ITEM_ID} unset.

+ * + *

Authenticates with {@code DefaultAzureCredential}. Pass one existing output directory as the sole + * command-line argument; there is no default directory. Treat downloaded audio as sensitive data. + * Model deployment settings are not needed because this sample reads an existing conversation.

+ */ +public class GptLiveReadConversationAudioAsyncSample { + public static void main(String[] args) { + Path directory = GptLiveReadConversationAudioSample.outputDirectory(args); + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String agentName = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_AGENT_NAME"); + String conversationId + = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_CONVERSATION_ID"); + String itemId = configuration.get("FOUNDRY_GPT_LIVE_ITEM_ID"); + BetaVoiceAgentsLiveConversationsAsyncClient client = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .addPolicy(GptLiveReadConversationSample.previewHeaders()) + .beta().buildBetaVoiceAgentsLiveConversationsAsyncClient(); + downloadAudio(client, agentName, conversationId, itemId, directory).block(); + } + + static Mono downloadAudio(BetaVoiceAgentsLiveConversationsAsyncClient client, String agentName, + String conversationId, String itemId, Path directory) { + if (itemId != null && itemId.trim().isEmpty()) { + return Mono.error(new IllegalArgumentException("FOUNDRY_GPT_LIVE_ITEM_ID must not be blank when set.")); + } + Mono merged = client.getAgentConversationAudio(agentName, conversationId).flatMap(recording -> { + GptLiveReadConversationAudioSample.printRecording(recording); + return GptLiveReadConversationAudioSample.isFoundryManaged(recording.getBlobUri()) + ? client.downloadAgentConversationAudio(agentName, conversationId) + .flatMap(audio -> saveAudio(audio, directory, "gpt-live-call-")) + : Mono.empty(); + }); + return merged.then(Mono.defer(() -> itemId == null ? Mono.empty() + : client.getAgentConversationAudioItem(agentName, conversationId, itemId).flatMap(item -> { + System.out.printf("Item %s: format=%s, rate=%d%n", itemId, item.getFormat(), item.getSampleRate()); + return GptLiveReadConversationAudioSample.isFoundryManaged(item.getBlobUri()) + ? client.downloadAgentConversationAudioItem(agentName, conversationId, itemId) + .flatMap(audio -> saveAudio(audio, directory, "gpt-live-item-")) + : Mono.empty(); + }))); + } + + private static Mono saveAudio(BinaryData audio, Path directory, String prefix) { + return Mono.fromCallable(() -> GptLiveReadConversationAudioSample.saveAudio(audio, directory, prefix)) + .subscribeOn(Schedulers.boundedElastic()) + .then(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioSample.java new file mode 100644 index 0000000000000..8a28f0dc81b38 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationAudioSample.java @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient; +import com.azure.ai.agents.models.VoiceAudioItem; +import com.azure.ai.agents.models.VoiceRecording; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Downloads persisted GPT Live merged audio and optionally a speech item's WAV to new files. + * The session must have used {@code store=true}. The agent and conversation must still exist. + * Wait for recording finalization after the session ends. HTTP errors propagate: inspect Retry-After on + * recording_not_ready (409), and distinguish missing audio (404) from recording_unavailable (409). + * BYOS audio requires separate Azure Storage credentials; this sample does not download it. + * No agent or persisted data is modified or deleted. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - Required. The Azure AI Project endpoint. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_AGENT_NAME} - Required. The existing GPT Live agent's name. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_CONVERSATION_ID} - Required. The persisted Foundry conversation ID from + * {@code session.started.conversation_id}, not the native session ID. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_ITEM_ID} - Optional. A speech item's ID, not a delegation item. + * Defaults to unset, downloading only the merged conversation audio. Explicitly blank values are invalid.
  • + *
+ * + *

To download an individual speech item's audio:

+ *
    + *
  1. Run {@link GptLiveReadConversationSample} with the same project endpoint, agent name, and conversation ID.
  2. + *
  3. Find the desired transcript in its output and copy the ID from the preceding + * {@code Item : type=input} or {@code Item : type=output} line. Do not select a delegation item.
  4. + *
  5. Set {@code FOUNDRY_GPT_LIVE_ITEM_ID} to that ID, then run this sample with an existing output directory + * as its sole command-line argument. It downloads both the merged call audio and the selected item's WAV.
  6. + *
+ *

For merged call audio only, skip the item lookup and leave {@code FOUNDRY_GPT_LIVE_ITEM_ID} unset.

+ * + *

Authenticates with {@code DefaultAzureCredential}. Pass one existing output directory as the sole + * command-line argument; there is no default directory. Treat downloaded audio as sensitive data. + * Model deployment settings are not needed because this sample reads an existing conversation.

+ */ +public class GptLiveReadConversationAudioSample { + public static void main(String[] args) throws IOException { + Path directory = outputDirectory(args); + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String agentName = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_AGENT_NAME"); + String conversationId + = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_CONVERSATION_ID"); + String itemId = configuration.get("FOUNDRY_GPT_LIVE_ITEM_ID"); + BetaVoiceAgentsLiveConversationsClient client = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .addPolicy(GptLiveReadConversationSample.previewHeaders()) + .beta().buildBetaVoiceAgentsLiveConversationsClient(); + downloadAudio(client, agentName, conversationId, itemId, directory); + } + + static void downloadAudio(BetaVoiceAgentsLiveConversationsClient client, String agentName, + String conversationId, String itemId, Path directory) throws IOException { + if (itemId != null && itemId.trim().isEmpty()) { + throw new IllegalArgumentException("FOUNDRY_GPT_LIVE_ITEM_ID must not be blank when set."); + } + VoiceRecording recording = client.getAgentConversationAudio(agentName, conversationId); + printRecording(recording); + if (isFoundryManaged(recording.getBlobUri())) { + saveAudio(client.downloadAgentConversationAudio(agentName, conversationId), directory, "gpt-live-call-"); + } + if (itemId != null) { + VoiceAudioItem item = client.getAgentConversationAudioItem(agentName, conversationId, itemId); + System.out.printf("Item %s: format=%s, rate=%d%n", itemId, item.getFormat(), item.getSampleRate()); + if (isFoundryManaged(item.getBlobUri())) { + saveAudio(client.downloadAgentConversationAudioItem(agentName, conversationId, itemId), + directory, "gpt-live-item-"); + } + } + } + + static void printRecording(VoiceRecording recording) { + System.out.printf("Recording: format=%s, rate=%d, channels=%d, durationMs=%s%n", + recording.getFormat(), recording.getSampleRate(), recording.getChannels(), recording.getDurationMs()); + } + + static boolean isFoundryManaged(String blobUri) { + if (blobUri == null || blobUri.isEmpty()) { + return true; + } + System.out.println("BYOS audio: use metadata.getBlobUri() with your own Azure Storage credentials."); + return false; + } + + static Path saveAudio(BinaryData audio, Path directory, String prefix) throws IOException { + Path output = Files.createTempFile(directory, prefix, ".wav"); + try (OutputStream stream = Files.newOutputStream(output)) { + audio.writeTo(stream); + } catch (IOException | RuntimeException error) { + try { + Files.deleteIfExists(output); + } catch (IOException cleanupError) { + error.addSuppressed(cleanupError); + } + throw error; + } + System.out.println("Saved WAV: " + output.toAbsolutePath()); + return output; + } + + static Path outputDirectory(String[] args) { + if (args.length != 1 || !Files.isDirectory(Paths.get(args[0]))) { + throw new IllegalArgumentException("Pass one existing output directory as the command-line argument."); + } + return Paths.get(args[0]); + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationSample.java new file mode 100644 index 0000000000000..00b5260e64b0d --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveReadConversationSample.java @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveConversationsClient; +import com.azure.ai.agents.models.PageOrder; +import com.azure.ai.agents.models.VoiceAgentLiveConversation; +import com.azure.ai.agents.models.VoiceAgentLiveConversationItem; +import com.azure.ai.agents.models.VoiceAgentLiveDelegationConversationItem; +import com.azure.ai.agents.models.VoiceAgentLiveInputConversationItem; +import com.azure.ai.agents.models.VoiceAgentLiveOutputConversationItem; +import com.azure.core.http.HttpHeaders; +import com.azure.core.http.policy.AddHeadersPolicy; +import com.azure.core.util.Configuration; +import com.azure.identity.DefaultAzureCredentialBuilder; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Lists persisted GPT Live conversations and reads one conversation's status, usage, and transcript items. + * The session must have used {@code store=true}. Use {@code session.started.conversation_id}, not the native session ID. + * Stored speech segments are not native turns or proof of playback; delegation results are not spoken transcripts. + * This sample prints sensitive stored content. It does not create sessions, modify agents, or delete data. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - Required. The Azure AI Project endpoint. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_AGENT_NAME} - Required. The existing GPT Live agent's name. No default.
  • + *
  • {@code FOUNDRY_GPT_LIVE_CONVERSATION_ID} - Required. The persisted Foundry conversation ID from + * {@code session.started.conversation_id}. No default.
  • + *
+ * + *

Authenticates with {@code DefaultAzureCredential}. Run without command-line arguments. + * Model deployment settings are not needed because this sample reads an existing conversation.

+ */ +public class GptLiveReadConversationSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_PROJECT_ENDPOINT"); + String agentName = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_AGENT_NAME"); + String conversationId = GptLiveSampleUtils.requireSetting(configuration, "FOUNDRY_GPT_LIVE_CONVERSATION_ID"); + BetaVoiceAgentsLiveConversationsClient client = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .addPolicy(previewHeaders()) + .beta() + .buildBetaVoiceAgentsLiveConversationsClient(); + readConversation(client, agentName, conversationId); + } + + static AddHeadersPolicy previewHeaders() { + // The generated Live REST builder methods do not automatically opt in to the voice preview. + return new AddHeadersPolicy(new HttpHeaders().set("Foundry-Features", "VoiceAgents=V1Preview")); + } + + static void readConversation(BetaVoiceAgentsLiveConversationsClient client, String agentName, + String conversationId) { + // Generated paging exposes cursor parameters but no automatic continuation token. + String after = null; + while (true) { + List page = client + .listAgentConversations(agentName, 100, PageOrder.ASC, after, null).stream().collect(Collectors.toList()); + if (page.isEmpty()) { + break; + } + for (VoiceAgentLiveConversation conversation : page) { + System.out.printf("Available conversation: %s (%s)%n", conversation.getId(), conversation.getStatus()); + } + after = nextCursor(page.get(page.size() - 1).getId(), after); + } + printConversation(client.getAgentConversation(agentName, conversationId)); + after = null; + while (true) { + List page = client + .listAgentConversationItems(agentName, conversationId, 100, PageOrder.ASC, after, null) + .stream().collect(Collectors.toList()); + if (page.isEmpty()) { + break; + } + for (VoiceAgentLiveConversationItem item : page) { + printItem(client.getAgentConversationItem(agentName, conversationId, item.getId())); + } + after = nextCursor(page.get(page.size() - 1).getId(), after); + } + } + + static String nextCursor(String id, String previous) { + if (id == null || id.isEmpty() || id.equals(previous)) { + throw new IllegalStateException("The service returned a missing or non-advancing pagination cursor."); + } + return id; + } + + static void printConversation(VoiceAgentLiveConversation conversation) { + System.out.printf("Conversation %s: status=%s, created=%s, completed=%s, usageSeconds=%s%n", + conversation.getId(), conversation.getStatus(), conversation.getCreatedAt(), conversation.getCompletedAt(), + conversation.getUsage() == null ? null : conversation.getUsage().seconds()); + } + + static void printItem(VoiceAgentLiveConversationItem item) { + System.out.printf("Item %s: type=%s%n", item.getId(), item.getType()); + if (item instanceof VoiceAgentLiveInputConversationItem) { + System.out.println("User transcript: " + ((VoiceAgentLiveInputConversationItem) item).getTranscription()); + } else if (item instanceof VoiceAgentLiveOutputConversationItem) { + System.out.println("Assistant transcript: " + ((VoiceAgentLiveOutputConversationItem) item).getTranscription()); + } else if (item instanceof VoiceAgentLiveDelegationConversationItem) { + VoiceAgentLiveDelegationConversationItem delegation = (VoiceAgentLiveDelegationConversationItem) item; + System.out.printf("Delegation target=%s, response=%s%n", delegation.getTarget(), delegation.getResponseId()); + } + } + +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveSampleUtils.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveSampleUtils.java new file mode 100644 index 0000000000000..aed920db6ea89 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveSampleUtils.java @@ -0,0 +1,573 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClient; +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.models.CreateAgentVersionInput; +import com.azure.ai.agents.models.VoiceAgentLiveDefinition; +import com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegation; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.openai.core.JsonValue; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.CommentaryAppendEvent; +import com.openai.models.live.InputAudioAppendEvent; +import com.openai.models.live.ResponseCreateEvent; +import com.openai.models.live.ResponseItemCreateEvent; +import com.openai.models.live.ResponsesDelegationConfig; +import com.openai.models.live.ServerEvent; +import com.openai.models.live.SessionCloseEvent; +import com.openai.models.live.SessionConfig; +import com.openai.models.responses.EasyInputMessage; +import com.openai.models.responses.ResponseInputContent; +import com.openai.models.responses.ResponseInputText; +import com.openai.models.responses.ResponseStreamEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.time.Duration; +import java.util.Arrays; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; +import reactor.core.scheduler.Schedulers; + +final class GptLiveSampleUtils { + static final Duration TIMEOUT = Duration.ofSeconds(60); + + private GptLiveSampleUtils() { + } + + static String requireSetting(Configuration configuration, String name) { + String value = configuration.get(name); + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable " + name + " before running this sample."); + } + return value; + } + + static String readPromptBlocking(BufferedReader reader, AudioTranscriptPrinter transcripts) throws IOException { + transcripts.beginInput(); + try { + String line = reader.readLine(); + if (line == null) { + return null; + } + String text = line.trim(); + return text.isEmpty() || "exit".equalsIgnoreCase(text) || "quit".equalsIgnoreCase(text) ? null : text; + } finally { + transcripts.endInput(); + } + } + + static Flux silenceFramesAsync() { + // Twenty milliseconds of 24-kHz mono PCM16LE. + ClientEvent silence = audio(new byte[960]); + return Mono.just(silence) + .concatWith(Mono.just(silence).delayElement(Duration.ofMillis(20)).repeat()); + } + + static final class Greeting { + // PCM16 peak levels up to 256 (about -42 dBFS) are treated as silence for this heuristic. + static final int SILENCE_PEAK_THRESHOLD = 256; + private final Sinks.Many progress = Sinks.many().replay().latest(); + private int received; + + void onAudio(byte[] pcm) { + if (hasSpeech(pcm)) { + received |= 1; + progress.tryEmitNext(received); + } + } + + void onTranscript() { + received |= 2; + progress.tryEmitNext(received); + } + + Mono awaitPlaybackAsync(Runnable drainAudio) { + // Output can continue with silent PCM after speaking; only speech activity restarts this timer. + return quietPeriodsAsync().next() + .timeout(TIMEOUT) + .then(Mono.fromRunnable(drainAudio).subscribeOn(Schedulers.boundedElastic())); + } + + Flux quietPeriodsAsync() { + return progress.asFlux().filter(parts -> parts == 3) + .switchMap(parts -> Mono.delay(Duration.ofSeconds(1))); + } + } + + static byte[] decodeAudio(ServerEvent event) { + byte[] pcm = Base64.getDecoder().decode(event.asSessionOutputAudioDelta().delta()); + if (pcm.length % 2 != 0) { + throw new IllegalArgumentException("GPT Live PCM16 audio must contain complete two-byte samples."); + } + return pcm; + } + + static boolean hasSpeech(byte[] pcm) { + for (int offset = 0; offset < pcm.length; offset += 2) { + int sample = (short) ((pcm[offset] & 0xff) | (pcm[offset + 1] << 8)); + if (sample < -Greeting.SILENCE_PEAK_THRESHOLD || sample > Greeting.SILENCE_PEAK_THRESHOLD) { + return true; + } + } + return false; + } + + static BinaryData event(String type, String field, Object value) { + Map event = new LinkedHashMap<>(); + event.put("type", type); + if (field != null) { + event.put(field, value); + } + return BinaryData.fromObject(event); + } + + static ClientEvent userMessage(String text) { + return ClientEvent.ofResponseItemCreate(ResponseItemCreateEvent.builder() + .item(EasyInputMessage.builder() + .role(EasyInputMessage.Role.USER) + .type(EasyInputMessage.Type.MESSAGE) + .contentOfResponseInputMessageContentList(java.util.Collections.singletonList( + ResponseInputContent.ofInputText(ResponseInputText.builder().text(text).build()))) + .build()) + .build()); + } + + static ClientEvent audio(byte[] pcm) { + return ClientEvent.ofSessionInputAudioAppend(InputAudioAppendEvent.builder() + .audio(Base64.getEncoder().encodeToString(pcm)).build()); + } + + static ClientEvent commentary(String content) { + return ClientEvent.ofSessionCommentaryAppend(CommentaryAppendEvent.builder() + .content(content) + .delegationId(java.util.Optional.empty()) + .build()); + } + + static ClientEvent responseCreate() { + return ClientEvent.ofResponseCreate(ResponseCreateEvent.builder().build()); + } + + static ClientEvent closeSession() { + return ClientEvent.ofSessionClose(SessionCloseEvent.builder().build()); + } + + static ResponseStreamEvent backendEvent(ServerEvent event) { + return event.isResponseEvent() + ? JsonValue.from(event.asResponseEvent().event()._additionalProperties()).convert(ResponseStreamEvent.class) + : null; + } + + static void checkError(ServerEvent event) { + if (event.isErrorEvent()) { + com.openai.models.live.Error error = event.asErrorEvent().error(); + boolean moderated = "content_filter".equals(error._code().asString().orElse(null)) + || "content_filter".equals(error._type().asString().orElse(null)); + throw new IllegalStateException(moderated + ? "GPT Live service error: generation stopped by service moderation " + + "(content_filter). The call has ended; review the conversation and service diagnostics. Event: " + + event + : "GPT Live service error: " + event); + } + if (event.isResponseEvent()) { + checkError(backendEvent(event)); + } else if (event._json().isPresent()) { + checkError(event._json().get().convert(ResponseStreamEvent.class)); + } + } + + static void checkError(ResponseStreamEvent event) { + if (event.isError() || event.isFailed() || event.isIncomplete()) { + Object error = JsonValue.from(event).convert(Map.class).get("error"); + if (error instanceof Map && ("content_filter".equals(((Map) error).get("code")) + || "content_filter".equals(((Map) error).get("type")))) { + throw new IllegalStateException("GPT Live service error: generation stopped by service moderation " + + "(content_filter). The call has ended; review the conversation and service diagnostics. Event: " + + event); + } + throw new IllegalStateException("GPT Live service error: " + event); + } + } + + static void printEvent(ServerEvent event) { + checkError(event); + if (event.isSessionStarted()) { + JsonValue conversationId = event.asSessionStarted()._additionalProperties().get("conversation_id"); + System.out.println(conversationId == null + || !conversationId.asString().isPresent() + ? "Live session started; conversation_id not provided (persistence may be disabled)." + : "Live session started; conversation_id=" + conversationId.asString().get()); + } else if (event.isSessionInputTranscriptDelta()) { + System.out.print(event.asSessionInputTranscriptDelta().delta()); + } else if (event.isSessionOutputTranscriptDelta()) { + System.out.print(event.asSessionOutputTranscriptDelta().delta()); + } else if (event.isResponseEvent()) { + ResponseStreamEvent backend = backendEvent(event); + if (backend.isOutputTextDelta()) { + System.out.print(backend.asOutputTextDelta().delta()); + } + } + } + + static final class AudioProcessor implements AutoCloseable { + private static final Duration SEND_TIMEOUT = Duration.ofSeconds(10); + private static final int CHUNK_BYTES = 2400; + static final int MAX_PLAYBACK_BYTES = VoiceAgentRealtimeSampleUtils.SAMPLE_RATE * 2 * 60; + private static final byte[] STOP = new byte[0]; + private final Function> sendAudio; + private final AudioFormat format = new AudioFormat(VoiceAgentRealtimeSampleUtils.SAMPLE_RATE, 16, 1, true, false); + private final BlockingQueue playback = new LinkedBlockingQueue<>(MAX_PLAYBACK_BYTES / 2); + private int queuedPlaybackBytes; + private final AtomicBoolean running = new AtomicBoolean(); + private final Sinks.Empty failure = Sinks.empty(); + private boolean closed; + private TargetDataLine microphone; + private SourceDataLine speaker; + private Thread captureThread; + private Thread playbackThread; + + AudioProcessor(TargetDataLine microphone, SourceDataLine speaker, Function> sendAudio) { + this.sendAudio = sendAudio; + this.microphone = microphone; + this.speaker = speaker; + } + + Mono failureSignalAsync() { + return failure.asMono(); + } + + synchronized void start() { + if (closed) { + throw new IllegalStateException("Audio processor is already closed."); + } + try { + if (microphone == null) { + microphone = AudioSystem.getTargetDataLine(format); + } + microphone.open(format, CHUNK_BYTES * 4); + if (speaker == null) { + speaker = AudioSystem.getSourceDataLine(format); + } + speaker.open(format); + microphone.start(); + speaker.start(); + } catch (LineUnavailableException | IllegalArgumentException error) { + close(); + throw new IllegalStateException("A 24-kHz mono PCM16 microphone and speaker are required.", error); + } + + running.set(true); + captureThread = new Thread(this::capture, "voice-agent-microphone"); + playbackThread = new Thread(this::playback, "voice-agent-speaker"); + captureThread.setDaemon(true); + playbackThread.setDaemon(true); + captureThread.start(); + playbackThread.start(); + } + + private void capture() { + byte[] buffer = new byte[CHUNK_BYTES]; + try { + while (running.get()) { + int read = microphone.read(buffer, 0, buffer.length); + if (read > 0 && running.get()) { + sendAudio.apply(BinaryData.fromBytes(Arrays.copyOf(buffer, read))).block(SEND_TIMEOUT); + } + } + } catch (RuntimeException error) { + fail(error); + } + } + + private void playback() { + try { + while (running.get()) { + byte[] pcm = playback.take(); + if (pcm == STOP) { + break; + } + synchronized (playback) { + queuedPlaybackBytes -= pcm.length; + } + speaker.write(pcm, 0, pcm.length); + } + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + fail(error); + } catch (RuntimeException error) { + fail(error); + } + } + + void queueAudio(byte[] pcm) { + if (pcm == null || pcm.length == 0) { + return; + } + if (pcm.length % 2 != 0) { + fail(new IllegalArgumentException("PCM16 audio must contain complete two-byte samples.")); + return; + } + synchronized (playback) { + if (!running.get()) { + return; + } + if (pcm.length <= MAX_PLAYBACK_BYTES - queuedPlaybackBytes && playback.offer(pcm)) { + queuedPlaybackBytes += pcm.length; + return; + } + } + fail(new IllegalStateException("Audio playback backlog exceeded 60 seconds.")); + } + + private void fail(Throwable error) { + if (running.compareAndSet(true, false)) { + failure.tryEmitError(error); + } + } + + @Override + public synchronized void close() { + if (closed) { + return; + } + closed = true; + running.set(false); + clearPlayback(); + playback.offer(STOP); + try { + closeLine(microphone); + } finally { + try { + closeLine(speaker); + } finally { + if (captureThread != null) { + captureThread.interrupt(); + } + if (playbackThread != null) { + playbackThread.interrupt(); + } + join(captureThread); + join(playbackThread); + } + } + } + + private void clearPlayback() { + synchronized (playback) { + byte[] discarded; + while ((discarded = playback.poll()) != null) { + queuedPlaybackBytes -= discarded.length; + } + } + } + + private static void closeLine(javax.sound.sampled.DataLine line) { + if (line != null) { + try { + line.stop(); + } finally { + line.close(); + } + } + } + + private static void join(Thread thread) { + if (thread != null && thread != Thread.currentThread()) { + try { + thread.join(SEND_TIMEOUT.toMillis()); + if (thread.isAlive()) { + System.err.println("Audio thread did not stop: " + thread.getName()); + } + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + } + } + } + } + + static final class AudioTranscriptPrinter { + static final int MAX_BUFFERED_TRANSCRIPT_CHARACTERS = 65536; + private String speaker; + private boolean readingInput; + private boolean lineOpen; + private final boolean inputEchoed; + private final boolean completeUtterances; + private final StringBuilder pending = new StringBuilder(); + private final StringBuilder utterance = new StringBuilder(); + + AudioTranscriptPrinter() { + this(false); + } + + AudioTranscriptPrinter(boolean inputEchoed) { + this(inputEchoed, false); + } + + AudioTranscriptPrinter(boolean inputEchoed, boolean completeUtterances) { + this.inputEchoed = inputEchoed; + this.completeUtterances = completeUtterances; + } + + synchronized void beginInput() { + if (readingInput) { + throw new IllegalStateException("A console read is already active."); + } + if (lineOpen) { + System.out.println(); + } + speaker = null; + lineOpen = false; + readingInput = true; + System.out.print("You: "); + System.out.flush(); + } + + synchronized void endInput() { + if (!readingInput) { + return; + } + readingInput = false; + if (!inputEchoed) { + System.out.println(); + } + if (pending.length() > 0) { + System.out.print(pending); + pending.setLength(0); + } + speaker = null; + } + + synchronized void beginTurn() { + speaker = null; + } + + synchronized void endUtterance() { + if (utterance.length() == 0) { + return; + } + String spokenText = utterance.toString().trim(); + if (spokenText.isEmpty()) { + utterance.setLength(0); + return; + } + String text = (lineOpen ? System.lineSeparator() : "") + "Assistant: " + spokenText + + System.lineSeparator(); + if (readingInput && text.length() > MAX_BUFFERED_TRANSCRIPT_CHARACTERS - pending.length()) { + throw new IllegalStateException("Buffered transcript exceeded 65536 characters while reading input."); + } + utterance.setLength(0); + speaker = null; + write(text); + } + + synchronized void print(ServerEvent event) { + checkError(event); + if (event.isSessionInputTranscriptDelta() || event.isSessionOutputTranscriptDelta()) { + String delta = event.isSessionInputTranscriptDelta() + ? event.asSessionInputTranscriptDelta().delta() : event.asSessionOutputTranscriptDelta().delta(); + if (completeUtterances && event.isSessionOutputTranscriptDelta()) { + if (delta.length() > MAX_BUFFERED_TRANSCRIPT_CHARACTERS - pending.length() - utterance.length()) { + throw new IllegalStateException("Buffered transcript exceeded 65536 characters."); + } + utterance.append(delta); + return; + } + String nextSpeaker = event.isSessionInputTranscriptDelta() ? "You" : "Assistant"; + if (!nextSpeaker.equals(speaker)) { + write((lineOpen ? System.lineSeparator() : "") + nextSpeaker + ": "); + speaker = nextSpeaker; + } + write(delta); + } else if (event.isSessionStarted()) { + printEvent(event); + } else if (event.isSessionClosed()) { + endUtterance(); + if (lineOpen) { + write(System.lineSeparator()); + } + speaker = null; + } + } + + private void write(String text) { + if (readingInput) { + if (text.length() > MAX_BUFFERED_TRANSCRIPT_CHARACTERS - pending.length() - utterance.length()) { + throw new IllegalStateException("Buffered transcript exceeded 65536 characters while reading input."); + } + pending.append(text); + } else { + System.out.print(text); + } + if (!text.isEmpty()) { + lineOpen = !text.endsWith("\n"); + } + } + } + + static AgentResource createAgent(AgentsClientBuilder builder, String model, String backendModel, + String scenario, boolean tools, boolean keepAgent) { + ResponsesDelegationConfig.Builder responses = ResponsesDelegationConfig.builder().model(backendModel) + .instructions(tools + ? "Use get_weather for weather requests. After receiving its result, answer briefly." + : "Answer the user briefly and helpfully."); + if (tools) { + responses.addTool(GptLiveFunctionToolSample.weatherTool()); + } + VoiceAgentLiveDefinition definition = new VoiceAgentLiveDefinition(model) + .setInstructions("You are a helpful voice assistant. Delegate requests to your Responses backend.") + .setAudio(SessionConfig.Audio.builder() + .audioPcmFormat(com.openai.models.live.AudioFormat.AudioPcm.Rate._24000).build()) + .setDelegation(new VoiceAgentLiveResponsesDelegation(responses.build())); + String agentName = createAgentName(scenario); + AgentsClient agents = builder.buildAgentsClient(); + agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)); + System.out.println("Created GPT Live agent: " + agentName); + return new AgentResource(builder, agents, agentName, keepAgent); + } + + static String createAgentName(String scenario) { + return "gpt-live-" + scenario + "-" + UUID.randomUUID(); + } + + static final class AgentResource implements AutoCloseable { + final AgentsClientBuilder builder; + final String name; + private final AgentsClient agents; + private final boolean keep; + + AgentResource(AgentsClientBuilder builder, AgentsClient agents, String name, boolean keep) { + this.builder = builder; + this.agents = agents; + this.name = name; + this.keep = keep; + } + + @Override + public void close() { + if (keep) { + System.out.println("Kept GPT Live agent: " + name); + } else { + agents.deleteAgent(name); + System.out.println("Deleted GPT Live agent: " + name); + } + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationAsyncSample.java new file mode 100644 index 0000000000000..2837066a826f4 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationAsyncSample.java @@ -0,0 +1,196 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionAsyncClient; +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.AgentsClient; +import com.azure.ai.agents.models.CreateAgentVersionInput; +import com.azure.ai.agents.models.VoiceAgentLiveDefinition; +import com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegation; +import com.openai.models.live.ResponsesDelegationConfig; +import com.openai.models.live.SessionConfig; +import com.openai.core.JsonValue; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ResponseCreateEvent; +import com.openai.models.live.ResponseItemCreateEvent; +import com.openai.models.live.SessionCloseEvent; +import com.openai.models.responses.EasyInputMessage; +import com.openai.models.responses.ResponseInputContent; +import com.openai.models.responses.ResponseInputText; +import com.azure.core.util.Configuration; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.openai.models.live.ServerEvent; +import com.openai.models.responses.ResponseStreamEvent; +import java.util.Arrays; +import java.util.Collections; +import java.util.UUID; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; +import reactor.core.scheduler.Schedulers; + + +/** + * Runs a nonblocking, multi-turn GPT Live text conversation using Responses delegation. + * Pass each prompt as a command-line argument, or run without arguments for one example question. + * Prints backend text without console input, audio devices, or silent PCM. + * See {@link GptLiveInteractiveTextConversationAsyncSample} for the advanced console-and-speaker scenario. + * Agent creation/deletion run outside the asynchronous session on the main thread. + * The uniquely named agent is deleted unless FOUNDRY_KEEP_GPT_LIVE_AGENT=true. + * The standalone main method shuts down shared Reactor schedulers on exit; do not invoke it inside a shared application. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - The Azure AI Project endpoint.
  • + *
  • {@code FOUNDRY_GPT_LIVE_MODEL} - Optional. The GPT Live deployment name. Defaults to {@code gpt-live-1}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_BACKEND_MODEL} - Optional. The Responses backend deployment name in the Live + * resource. Defaults to {@code gpt-5.6-terra}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_STORE} - Optional. Set to {@code true} to persist conversation content and audio + * and request a Foundry conversation ID. Defaults to {@code false}. Also keep the agent for later REST reads.
  • + *
  • {@code FOUNDRY_KEEP_GPT_LIVE_AGENT} - Optional. Set to {@code true} to keep the agent after the sample. + * Defaults to {@code false}.
  • + *
+ */ +public class GptLiveTextConversationAsyncSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = configuration.get("FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + boolean store = Boolean.parseBoolean(configuration.get("FOUNDRY_GPT_LIVE_STORE", "false")); + + if (endpoint == null || endpoint.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_PROJECT_ENDPOINT before running this sample."); + } + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_MODEL before running this sample."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_BACKEND_MODEL before running this sample."); + } + + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .allowPreview(true); + VoiceAgentLiveDefinition definition = new VoiceAgentLiveDefinition(model) + .setInstructions("You are a helpful voice assistant. Delegate requests to your Responses backend.") + .setAudio(SessionConfig.Audio.builder() + .audioPcmFormat(com.openai.models.live.AudioFormat.AudioPcm.Rate._24000).build()) + .setDelegation(new VoiceAgentLiveResponsesDelegation(ResponsesDelegationConfig.builder() + .model(backendModel).instructions("Answer the user briefly and helpfully.").build())); + String agentName = "gpt-live-text-async-" + UUID.randomUUID(); + AgentsClient agents = builder.buildAgentsClient(); + agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)); + System.out.println("Created GPT Live agent: " + agentName); + try { + Mono.usingWhen(builder.beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession(agentName, new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store)), + session -> runConversation(session, + Arrays.asList(args.length == 0 ? new String[] { "What can you help me with?" } : args)), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync, + (session, error) -> session.closeAsync(), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync).block(); + } finally { + try { + if (!keepAgent) { + agents.deleteAgent(agentName); + } + } finally { + Schedulers.shutdownNow(); + } + } + } + + static Mono runConversation(BetaVoiceAgentsLiveWebSocketSessionAsyncClient session, List prompts) { + return Mono.defer(() -> { + Sinks.Empty ready = Sinks.empty(); + Sinks.Empty closed = Sinks.empty(); + AtomicBoolean started = new AtomicBoolean(); + AtomicBoolean closing = new AtomicBoolean(); + AtomicBoolean finalized = new AtomicBoolean(); + AtomicBoolean remoteHangup = new AtomicBoolean(); + AtomicReference> responseCompleted = new AtomicReference<>(); + Mono receive = session.receiveEvents() + .publishOn(Schedulers.boundedElastic(), 1) + .takeUntil(ServerEvent::isSessionClosed) + .doOnNext(event -> { + GptLiveSampleUtils.checkError(event); + if (event.isSessionStarted()) { + if (!started.compareAndSet(false, true)) { + throw new IllegalStateException("Duplicate session.started event."); + } + JsonValue conversationId = event.asSessionStarted()._additionalProperties().get("conversation_id"); + System.out.println(conversationId != null && conversationId.asString().isPresent() + ? "Live session started; conversation_id=" + conversationId.asString().get() + : "Live session started; conversation_id not provided (persistence may be disabled)."); + ready.tryEmitEmpty(); + } else if (event.isResponseEvent()) { + ResponseStreamEvent response = JsonValue.from(event.asResponseEvent().event()._additionalProperties()) + .convert(ResponseStreamEvent.class); + if (response.isOutputTextDelta()) { + System.out.print(response.asOutputTextDelta().delta()); + } + if (response.isCompleted()) { + Sinks.Empty completion = responseCompleted.getAndSet(null); + if (!started.get() || completion == null || closing.get()) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } + System.out.println(); + completion.tryEmitEmpty(); + } + } else if (event.isSessionClosed()) { + String reason = event.asSessionClosed().reason().toString(); + remoteHangup.set(started.get() && "remote_hangup".equals(reason)); + if (!remoteHangup.get() && !(closing.get() && "close_requested".equals(reason))) { + throw new IllegalStateException("GPT Live closed before all turns completed. Event: " + + event + "; transport close code=" + session.getCloseCode() + + ", reason=" + session.getCloseReason()); + } + finalized.set(true); + System.out.println("Live session closed (" + reason + ")."); + closed.tryEmitEmpty(); + } + }) + .then(Mono.defer(() -> { + if (!finalized.get()) { + return Mono.error(new IllegalStateException("GPT Live disconnected without session.closed.")); + } + return remoteHangup.get() ? Mono.empty() : Mono.never(); + })); + Mono conversation = ready.asMono().timeout(Duration.ofSeconds(60)) + .thenMany(Flux.fromIterable(prompts).concatMap(prompt -> Mono.defer(() -> { + Sinks.Empty completion = Sinks.empty(); + responseCompleted.set(completion); + System.out.println("You: " + prompt); + System.out.print("Assistant: "); + return session.sendEvent(ClientEvent.ofResponseItemCreate(ResponseItemCreateEvent.builder() + .item(EasyInputMessage.builder().role(EasyInputMessage.Role.USER) + .type(EasyInputMessage.Type.MESSAGE) + .contentOfResponseInputMessageContentList(Collections.singletonList( + ResponseInputContent.ofInputText(ResponseInputText.builder().text(prompt).build()))) + .build()).build())) + .then(session.sendEvent(ClientEvent.ofResponseCreate(ResponseCreateEvent.builder().build()))) + .then(completion.asMono()).timeout(Duration.ofSeconds(60)); + }), 1)) + .then(Mono.defer(() -> { + closing.set(true); + return session.sendEvent(ClientEvent.ofSessionClose(SessionCloseEvent.builder().build())) + .then(closed.asMono()).timeout(Duration.ofSeconds(60)); + })); + return Mono.firstWithSignal(receive, conversation); + }); + } + +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationSample.java new file mode 100644 index 0000000000000..e04d1ce55b07f --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/GptLiveTextConversationSample.java @@ -0,0 +1,179 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionClient; +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.AgentsClient; +import com.azure.ai.agents.models.CreateAgentVersionInput; +import com.azure.ai.agents.models.VoiceAgentLiveDefinition; +import com.azure.ai.agents.models.VoiceAgentLiveResponsesDelegation; +import com.azure.core.util.Configuration; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.openai.models.live.ClientEvent; +import com.openai.core.JsonValue; +import com.openai.models.live.ResponseCreateEvent; +import com.openai.models.live.ResponseItemCreateEvent; +import com.openai.models.live.SessionCloseEvent; +import com.openai.models.responses.EasyInputMessage; +import com.openai.models.responses.ResponseInputContent; +import com.openai.models.responses.ResponseInputText; +import com.openai.models.live.ServerEvent; +import com.openai.models.live.ResponsesDelegationConfig; +import com.openai.models.live.SessionConfig; +import com.openai.models.responses.ResponseStreamEvent; +import java.util.Arrays; +import java.util.Collections; +import java.util.UUID; +import java.time.Duration; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; +import reactor.core.scheduler.Schedulers; + + +/** + * Runs a synchronous, multi-turn GPT Live text conversation using Responses delegation. + * Pass each prompt as a command-line argument, or run without arguments for one example question. + * Prints backend text without console input, audio devices, background conversation workers, or silent PCM. + * See {@link GptLiveInteractiveTextConversationSample} for the advanced console-and-speaker scenario. + * A uniquely named agent is deleted on exit unless FOUNDRY_KEEP_GPT_LIVE_AGENT=true. + * The standalone main method shuts down shared Reactor schedulers on exit; do not invoke it inside a shared application. + * + *

Before running the sample, set these environment variables:

+ *
    + *
  • {@code FOUNDRY_PROJECT_ENDPOINT} - The Azure AI Project endpoint.
  • + *
  • {@code FOUNDRY_GPT_LIVE_MODEL} - Optional. The GPT Live deployment name. Defaults to {@code gpt-live-1}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_BACKEND_MODEL} - Optional. The Responses backend deployment name in the Live + * resource. Defaults to {@code gpt-5.6-terra}.
  • + *
  • {@code FOUNDRY_GPT_LIVE_STORE} - Optional. Set to {@code true} to persist conversation content and audio + * and request a Foundry conversation ID. Defaults to {@code false}. Also keep the agent for later REST reads.
  • + *
  • {@code FOUNDRY_KEEP_GPT_LIVE_AGENT} - Optional. Set to {@code true} to keep the agent after the sample. + * Defaults to {@code false}.
  • + *
+ */ +public class GptLiveTextConversationSample { + public static void main(String[] args) { + Configuration configuration = Configuration.getGlobalConfiguration(); + String endpoint = configuration.get("FOUNDRY_PROJECT_ENDPOINT"); + String model = configuration.get("FOUNDRY_GPT_LIVE_MODEL"); + String backendModel = configuration.get("FOUNDRY_GPT_LIVE_BACKEND_MODEL"); + boolean keepAgent = Boolean.parseBoolean(configuration.get("FOUNDRY_KEEP_GPT_LIVE_AGENT", "false")); + boolean store = Boolean.parseBoolean(configuration.get("FOUNDRY_GPT_LIVE_STORE", "false")); + + if (endpoint == null || endpoint.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_PROJECT_ENDPOINT before running this sample."); + } + if (model == null) { + model = "gpt-live-1"; + } else if (model.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_MODEL before running this sample."); + } + if (backendModel == null) { + backendModel = "gpt-5.6-terra"; + } else if (backendModel.trim().isEmpty()) { + throw new IllegalArgumentException("Set environment variable FOUNDRY_GPT_LIVE_BACKEND_MODEL before running this sample."); + } + + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint) + .credential(new DefaultAzureCredentialBuilder().build()) + .allowPreview(true); + VoiceAgentLiveDefinition definition = new VoiceAgentLiveDefinition(model) + .setInstructions("You are a helpful voice assistant. Delegate requests to your Responses backend.") + .setAudio(SessionConfig.Audio.builder() + .audioPcmFormat(com.openai.models.live.AudioFormat.AudioPcm.Rate._24000).build()) + .setDelegation(new VoiceAgentLiveResponsesDelegation(ResponsesDelegationConfig.builder() + .model(backendModel).instructions("Answer the user briefly and helpfully.").build())); + String agentName = "gpt-live-text-" + UUID.randomUUID(); + AgentsClient agents = builder.buildAgentsClient(); + agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)); + System.out.println("Created GPT Live agent: " + agentName); + try (BetaVoiceAgentsLiveWebSocketSessionClient session = builder.beta() + .buildBetaVoiceAgentsLiveWebSocketClient() + .openWebSocketSession(agentName, new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store))) { + runConversation(session, Arrays.asList(args.length == 0 ? new String[] { "What can you help me with?" } : args)); + } finally { + try { + if (!keepAgent) { + agents.deleteAgent(agentName); + } + } finally { + Schedulers.shutdownNow(); + } + } + } + + static void runConversation(BetaVoiceAgentsLiveWebSocketSessionClient session, List prompts) { + runConversation(session.receiveEvents(Duration.ofSeconds(60)), session::sendEvent, + () -> "transport close code=" + session.getCloseCode() + ", reason=" + session.getCloseReason(), prompts); + } + + static void runConversation(Iterable events, Consumer sendEvent, + Supplier closeDetails, List prompts) { + Iterator pending = prompts.iterator(); + boolean started = false; + boolean awaitingResponse = false; + boolean closing = false; + for (ServerEvent event : events) { + GptLiveSampleUtils.checkError(event); + boolean nextTurn = false; + if (event.isSessionStarted()) { + if (started) { + throw new IllegalStateException("Duplicate session.started event."); + } + started = true; + JsonValue conversationId = event.asSessionStarted()._additionalProperties().get("conversation_id"); + System.out.println(conversationId != null && conversationId.asString().isPresent() + ? "Live session started; conversation_id=" + conversationId.asString().get() + : "Live session started; conversation_id not provided (persistence may be disabled)."); + nextTurn = true; + } else if (event.isResponseEvent()) { + ResponseStreamEvent response = JsonValue.from(event.asResponseEvent().event()._additionalProperties()) + .convert(ResponseStreamEvent.class); + if (response.isOutputTextDelta()) { + System.out.print(response.asOutputTextDelta().delta()); + } + if (response.isCompleted()) { + if (!started || !awaitingResponse || closing) { + throw new IllegalStateException("Unexpected GPT Live response lifecycle event."); + } + awaitingResponse = false; + System.out.println(); + nextTurn = true; + } + } else if (event.isSessionClosed()) { + String reason = event.asSessionClosed().reason().toString(); + if (!(started && "remote_hangup".equals(reason)) + && !(closing && "close_requested".equals(reason))) { + throw new IllegalStateException("GPT Live closed before all turns completed. Event: " + event + + "; " + closeDetails.get()); + } + System.out.println("Live session closed (" + reason + ")."); + return; + } + if (nextTurn) { + if (pending.hasNext()) { + String prompt = pending.next(); + System.out.println("You: " + prompt); + System.out.print("Assistant: "); + awaitingResponse = true; + sendEvent.accept(ClientEvent.ofResponseItemCreate(ResponseItemCreateEvent.builder() + .item(EasyInputMessage.builder().role(EasyInputMessage.Role.USER) + .type(EasyInputMessage.Type.MESSAGE) + .contentOfResponseInputMessageContentList(Collections.singletonList( + ResponseInputContent.ofInputText(ResponseInputText.builder().text(prompt).build()))) + .build()).build())); + sendEvent.accept(ClientEvent.ofResponseCreate(ResponseCreateEvent.builder().build())); + } else { + closing = true; + sendEvent.accept(ClientEvent.ofSessionClose(SessionCloseEvent.builder().build())); + } + } + } + throw new IllegalStateException("GPT Live disconnected without session.closed."); + } + +} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicAsyncSample.java index d5ee1ea3e8e86..849da1d764423 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicAsyncSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicAsyncSample.java @@ -39,7 +39,7 @@ public static void main(String[] args) { .buildAgentsAsyncClient(); client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a friendly voice assistant. Keep replies short and natural."))) .doOnNext(created -> System.out.printf("Created voice agent %s, version %s%n", created.getName(), created.getVersion())) @@ -49,7 +49,7 @@ public static void main(String[] args) { .thenMany(client.listAgents(AgentKind.VOICE, null, null, null, null)) .doOnNext(agent -> System.out.println("Voice agent: " + agent.getName())) .then(client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a friendly voice assistant. Always greet the caller warmly.")) .setDescription("Updated voice-agent instructions."))) .doOnNext(updated -> System.out.println("Created updated version: " + updated.getVersion())) diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicSample.java index e03ab19962386..e5128424c3660 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentBasicSample.java @@ -40,7 +40,7 @@ public static void main(String[] args) { .buildAgentsClient(); try { AgentVersionDetails created = client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a friendly voice assistant. Keep replies short and natural."))); System.out.printf("Created voice agent %s, version %s%n", created.getName(), created.getVersion()); @@ -51,7 +51,7 @@ public static void main(String[] args) { } AgentVersionDetails updated = client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a friendly voice assistant. Always greet the caller warmly.")) .setDescription("Updated voice-agent instructions.")); System.out.println("Created updated version: " + updated.getVersion()); diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveAudioConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveAudioConversationAsyncSample.java index 2a80cc060fbae..b0c48a48d127c 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveAudioConversationAsyncSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveAudioConversationAsyncSample.java @@ -7,8 +7,8 @@ import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient; import com.azure.ai.agents.BetaAgentsAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.RealtimeConversationItemInputAudioTranscriptionCompletedEvent; import com.azure.ai.agents.models.RealtimeInputAudioBufferSpeechStartedEvent; @@ -42,6 +42,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; /** * Demonstrates an asynchronous hands-free voice conversation using Java Sound and server-side VAD. @@ -81,7 +82,7 @@ public static void main(String[] args) { .allowPreview(true); AgentsAsyncClient agents = builder.buildAgentsAsyncClient(); BetaAgentsAsyncClient betaAgents = builder.beta().buildBetaAgentsAsyncClient(); - BetaVoiceAgentWebSocketAsyncClient realtime = builder.beta().buildBetaVoiceAgentWebSocketAsyncClient(); + BetaVoiceAgentsWebSocketAsyncClient realtime = builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient(); BetaVoiceAgentsConversationsAsyncClient conversations = builder.beta().buildBetaVoiceAgentsConversationsAsyncClient(); @@ -99,9 +100,9 @@ public static void main(String[] args) { }) .then(Mono.usingWhen(realtime.openWebSocketSession(agentName), session -> runConversation(session, conversationId), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync, + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync)) + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync)) .then(Mono.defer(() -> conversationId.get() == null ? Mono.fromRunnable(() -> System.out.println("No persisted conversation ID was returned.")) : VoiceAgentRealtimeSampleUtils.readConversation(conversations, agentName, conversationId.get()))) @@ -120,7 +121,7 @@ private static Mono cleanupAgent(AgentsAsyncClient agents, String agentNam .doOnSuccess(ignored -> System.out.println("Deleted voice agent: " + agentName)); } - private static Mono runConversation(BetaVoiceAgentWebSocketSessionAsyncClient session, + private static Mono runConversation(BetaVoiceAgentsWebSocketSessionAsyncClient session, AtomicReference conversationId) { AudioProcessor processor = new AudioProcessor(session); AtomicBoolean responseActive = new AtomicBoolean(); @@ -195,7 +196,7 @@ static final class AudioProcessor implements AutoCloseable { private static final int CHUNK_BYTES = 2400; static final int MAX_PLAYBACK_BYTES = VoiceAgentRealtimeSampleUtils.SAMPLE_RATE * 2 * 60; private static final byte[] STOP = new byte[0]; - private final BetaVoiceAgentWebSocketSessionAsyncClient session; + private final Function> sendAudio; private final AudioFormat format = new AudioFormat(VoiceAgentRealtimeSampleUtils.SAMPLE_RATE, 16, 1, true, false); private final BlockingQueue playback = new LinkedBlockingQueue<>(MAX_PLAYBACK_BYTES / 2); private int queuedPlaybackBytes; @@ -207,16 +208,24 @@ static final class AudioProcessor implements AutoCloseable { private Thread captureThread; private Thread playbackThread; - AudioProcessor(BetaVoiceAgentWebSocketSessionAsyncClient session) { + AudioProcessor(BetaVoiceAgentsWebSocketSessionAsyncClient session) { this(session, null, null); } - AudioProcessor(BetaVoiceAgentWebSocketSessionAsyncClient session, TargetDataLine microphone, SourceDataLine speaker) { - this.session = session; + AudioProcessor(BetaVoiceAgentsWebSocketSessionAsyncClient session, TargetDataLine microphone, SourceDataLine speaker) { + this(microphone, speaker, pcm -> session.appendInputAudio(pcm)); + } + + AudioProcessor(TargetDataLine microphone, SourceDataLine speaker, Function> sendAudio) { + this.sendAudio = sendAudio; this.microphone = microphone; this.speaker = speaker; } + Mono failureSignal() { + return failure.asMono(); + } + synchronized void start() { if (closed) { throw new IllegalStateException("Audio processor is already closed."); @@ -252,7 +261,7 @@ private void capture() { while (running.get()) { int read = microphone.read(buffer, 0, buffer.length); if (read > 0 && running.get()) { - session.appendInputAudio(BinaryData.fromBytes(Arrays.copyOf(buffer, read))).block(SEND_TIMEOUT); + sendAudio.apply(BinaryData.fromBytes(Arrays.copyOf(buffer, read))).block(SEND_TIMEOUT); } } } catch (RuntimeException error) { diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveFunctionToolSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveFunctionToolSample.java index f51801608fb3d..9ed04a93c7d21 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveFunctionToolSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveFunctionToolSample.java @@ -5,8 +5,8 @@ import com.azure.ai.agents.AgentsClient; import com.azure.ai.agents.AgentsClientBuilder; -import com.azure.ai.agents.BetaVoiceAgentWebSocketClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.RealtimeConversationItem; import com.azure.ai.agents.models.RealtimeConversationItemType; @@ -64,7 +64,7 @@ public static void main(String[] args) { .endpoint(endpoint) .allowPreview(true); AgentsClient agents = builder.buildAgentsClient(); - BetaVoiceAgentWebSocketClient realtime = builder.beta().buildBetaVoiceAgentWebSocketClient(); + BetaVoiceAgentsWebSocketClient realtime = builder.beta().buildBetaVoiceAgentsWebSocketClient(); Map cityProperty = new LinkedHashMap<>(); cityProperty.put("type", "string"); @@ -89,7 +89,7 @@ public static void main(String[] args) { try { agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)); System.out.println("Created voice agent: " + agentName); - try (BetaVoiceAgentWebSocketSessionClient session = realtime.openWebSocketSession(agentName)) { + try (BetaVoiceAgentsWebSocketSessionClient session = realtime.openWebSocketSession(agentName)) { ExecutorService receiver = Executors.newSingleThreadExecutor(); Future response = receiver.submit(() -> receiveResponse(session)); try { @@ -114,7 +114,7 @@ public static void main(String[] args) { } } - private static void receiveResponse(BetaVoiceAgentWebSocketSessionClient session) { + private static void receiveResponse(BetaVoiceAgentsWebSocketSessionClient session) { for (RealtimeServerEvent event : session.receiveEvents()) { if (event instanceof RealtimeResponseFunctionCallArgumentsDoneEvent) { RealtimeResponseFunctionCallArgumentsDoneEvent call diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationAsyncSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationAsyncSample.java index c054427a5cc3a..caaf3e36a0c2d 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationAsyncSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationAsyncSample.java @@ -7,8 +7,8 @@ import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient; import com.azure.ai.agents.BetaAgentsAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.VoiceAgentDefinition; import com.azure.core.util.BinaryData; @@ -59,7 +59,7 @@ public static void main(String[] args) { .allowPreview(true); AgentsAsyncClient agents = builder.buildAgentsAsyncClient(); BetaAgentsAsyncClient betaAgents = builder.beta().buildBetaAgentsAsyncClient(); - BetaVoiceAgentWebSocketAsyncClient realtime = builder.beta().buildBetaVoiceAgentWebSocketAsyncClient(); + BetaVoiceAgentsWebSocketAsyncClient realtime = builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient(); BetaVoiceAgentsConversationsAsyncClient conversations = builder.beta().buildBetaVoiceAgentsConversationsAsyncClient(); @@ -80,9 +80,9 @@ public static void main(String[] args) { }) .then(Mono.usingWhen(realtime.openWebSocketSession(agentName), session -> runConversation(session, scanner, conversationId, player), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync, + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync)) + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync)) .then(Mono.defer(() -> conversationId.get() == null ? Mono.fromRunnable(() -> System.out.println("No persisted conversation ID was returned.")) : VoiceAgentRealtimeSampleUtils.readConversation(conversations, agentName, conversationId.get()))) @@ -105,7 +105,7 @@ private static Mono cleanupAgent(AgentsAsyncClient agents, String agentNam .doOnSuccess(ignored -> System.out.println("Deleted voice agent: " + agentName)); } - private static Mono runConversation(BetaVoiceAgentWebSocketSessionAsyncClient session, Scanner scanner, + private static Mono runConversation(BetaVoiceAgentsWebSocketSessionAsyncClient session, Scanner scanner, AtomicReference conversationId, VoiceAgentRealtimeSampleUtils.SpeakerPlayer player) { AtomicReference> responseCompleted = new AtomicReference<>(); Disposable receiver = session.receiveEvents().subscribe(event -> { @@ -131,7 +131,7 @@ private static Mono runConversation(BetaVoiceAgentWebSocketSessionAsyncCli }); } - private static Mono prompt(BetaVoiceAgentWebSocketSessionAsyncClient session, Scanner scanner, + private static Mono prompt(BetaVoiceAgentsWebSocketSessionAsyncClient session, Scanner scanner, AtomicReference> responseCompleted) { return Mono.fromCallable(() -> { System.out.print("You: "); diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSample.java index 6b9ce05b1c00c..97ac549ca56c0 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSample.java @@ -7,8 +7,8 @@ import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsConversationsClient; import com.azure.ai.agents.BetaAgentsClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; import com.azure.ai.agents.models.AgentDetails; import com.azure.ai.agents.models.AgentVersionDetails; import com.azure.ai.agents.models.CreateAgentVersionInput; @@ -16,6 +16,7 @@ import com.azure.ai.agents.models.VoiceAgentDefinition; import com.azure.core.util.BinaryData; import com.azure.core.util.Configuration; +import com.azure.core.exception.ResourceModifiedException; import com.azure.identity.DefaultAzureCredentialBuilder; import java.time.Duration; @@ -40,6 +41,8 @@ *
  • {@code FOUNDRY_VOICE_AGENT_NAME} - Optional. The voice agent name. Defaults to * {@code sample-live-text-conversation-agent-java}.
  • * + *

    This sample deletes and replaces an existing agent with the selected name on a creation conflict. + * Use a name reserved for this sample. The replacement is deleted on exit, including on failure.

    */ public class VoiceAgentLiveTextConversationSample { private static final Duration RESPONSE_TIMEOUT = Duration.ofSeconds(45); @@ -56,23 +59,18 @@ public static void main(String[] args) { .allowPreview(true); AgentsClient agents = builder.buildAgentsClient(); BetaAgentsClient betaAgents = builder.beta().buildBetaAgentsClient(); - BetaVoiceAgentWebSocketClient realtime = builder.beta().buildBetaVoiceAgentWebSocketClient(); + BetaVoiceAgentsWebSocketClient realtime = builder.beta().buildBetaVoiceAgentsWebSocketClient(); BetaVoiceAgentsConversationsClient conversations = builder.beta().buildBetaVoiceAgentsConversationsClient(); - Map request = new LinkedHashMap<>(); - request.put("kind", "voice"); - request.put("name", agentName); - AgentDetails generated = betaAgents.createAgentFromPrompt(BinaryData.fromObject(request)); - - try { - AgentVersionDetails latest = generated.getVersions().getLatest(); + try (SampleAgent agent = createAgent(agents, betaAgents, agentName)) { + AgentVersionDetails latest = agent.details.getVersions().getLatest(); VoiceAgentDefinition definition = (VoiceAgentDefinition) latest.getDefinition(); agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition.setStore(true))); AtomicReference conversationId = new AtomicReference<>(); try (VoiceAgentRealtimeSampleUtils.SpeakerPlayer player = new VoiceAgentRealtimeSampleUtils.SpeakerPlayer(); - BetaVoiceAgentWebSocketSessionClient session = realtime.openWebSocketSession(agentName); + BetaVoiceAgentsWebSocketSessionClient session = realtime.openWebSocketSession(agentName); Scanner scanner = new Scanner(System.in)) { AtomicReference> responseCompleted = new AtomicReference<>(); ExecutorService receiver = Executors.newSingleThreadExecutor(); @@ -124,13 +122,47 @@ public static void main(String[] args) { } else { System.out.println("No persisted conversation ID was returned."); } - } finally { + } + } + + static SampleAgent createAgent(AgentsClient agents, BetaAgentsClient betaAgents, String agentName) { + Map request = new LinkedHashMap<>(); + request.put("kind", "voice"); + request.put("name", agentName); + BinaryData body = BinaryData.fromObject(request); + AgentDetails details; + try { + details = betaAgents.createAgentFromPrompt(body); + } catch (ResourceModifiedException error) { + if (error.getResponse() == null || error.getResponse().getStatusCode() != 409) { + throw error; + } + System.err.println("Deleting existing voice agent before replacement: " + agentName); agents.deleteAgent(agentName); - System.out.println("Deleted voice agent: " + agentName); + details = betaAgents.createAgentFromPrompt(body); + } + return new SampleAgent(agents, agentName, details); + } + + static final class SampleAgent implements AutoCloseable { + final AgentDetails details; + private final AgentsClient agents; + private final String name; + + private SampleAgent(AgentsClient agents, String name, AgentDetails details) { + this.agents = agents; + this.name = name; + this.details = details; + } + + @Override + public void close() { + agents.deleteAgent(name); + System.out.println("Deleted voice agent: " + name); } } - private static boolean awaitResponse(BetaVoiceAgentWebSocketSessionClient session, + private static boolean awaitResponse(BetaVoiceAgentsWebSocketSessionClient session, CompletableFuture completion) { try { completion.get(RESPONSE_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentRealtimeSampleUtils.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentRealtimeSampleUtils.java index 6ce3f33a22d51..aac7dea9530af 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentRealtimeSampleUtils.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentRealtimeSampleUtils.java @@ -11,7 +11,13 @@ import com.azure.ai.agents.models.RealtimeResponseAudioTranscriptDoneEvent; import com.azure.ai.agents.models.RealtimeResponseDoneEvent; import com.azure.ai.agents.models.RealtimeSessionCreatedEvent; +import com.azure.ai.agents.models.VoiceAgentAudioConfiguration; +import com.azure.ai.agents.models.VoiceAgentAudioOutputConfiguration; +import com.azure.ai.agents.models.VoiceAgentDefinition; import com.azure.ai.agents.models.VoiceConversation; +import com.azure.ai.agents.models.VoiceModelType; +import com.azure.ai.agents.models.VoiceOutputModality; +import com.azure.ai.agents.models.VoiceType; import com.azure.core.http.rest.RequestOptions; import com.azure.core.util.BinaryData; import reactor.core.publisher.Mono; @@ -20,6 +26,7 @@ import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -30,6 +37,19 @@ final class VoiceAgentRealtimeSampleUtils { private VoiceAgentRealtimeSampleUtils() { } + static VoiceAgentDefinition createDefinition(VoiceModelType modelType, String model, String instructions) { + VoiceAgentAudioOutputConfiguration output = new VoiceAgentAudioOutputConfiguration() + .setVoice("en-US-AvaNeural") + .setVoiceType(VoiceType.AZURE_STANDARD); + return new VoiceAgentDefinition() + .setModelType(modelType) + .setModel(model) + .setInstructions(instructions) + .setAudio(new VoiceAgentAudioConfiguration().setOutput(output)) + .setOutputModalities(Collections.singletonList(VoiceOutputModality.AUDIO)) + .setStore(true); + } + static boolean handleResponseEvent(RealtimeServerEvent event, AtomicReference conversationId, SpeakerPlayer player) { if (event instanceof RealtimeSessionCreatedEvent) { @@ -139,6 +159,12 @@ boolean isEnabled() { return line != null; } + synchronized void drain() { + if (line != null) { + line.drain(); + } + } + @Override public synchronized void close() { if (line != null) { diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentSampleUtils.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentSampleUtils.java deleted file mode 100644 index 2b37d1c0b1e02..0000000000000 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentSampleUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.voice; - -import com.azure.ai.agents.models.VoiceAgentAudioConfiguration; -import com.azure.ai.agents.models.VoiceAgentAudioOutputConfiguration; -import com.azure.ai.agents.models.VoiceAgentDefinition; -import com.azure.ai.agents.models.VoiceModelType; -import com.azure.ai.agents.models.VoiceOutputModality; -import com.azure.ai.agents.models.VoiceType; - -import java.util.Collections; - -final class VoiceAgentSampleUtils { - private VoiceAgentSampleUtils() { - } - - static VoiceAgentDefinition createDefinition(VoiceModelType modelType, String model, String instructions) { - VoiceAgentAudioOutputConfiguration output = new VoiceAgentAudioOutputConfiguration() - .setVoice("en-US-AvaNeural") - .setVoiceType(VoiceType.AZURE_STANDARD); - return new VoiceAgentDefinition() - .setModelType(modelType) - .setModel(model) - .setInstructions(instructions) - .setAudio(new VoiceAgentAudioConfiguration().setOutput(output)) - .setOutputModalities(Collections.singletonList(VoiceOutputModality.AUDIO)) - .setStore(true); - } -} diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentVersionsSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentVersionsSample.java index 724b553e30756..9e9e991c73459 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentVersionsSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentVersionsSample.java @@ -38,14 +38,14 @@ public static void main(String[] args) { .buildAgentsClient(); try { AgentVersionDetails first = client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a helpful voice assistant."))); AgentVersionDetails released = client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are a helpful voice assistant. Greet the caller by name.")) .setDescription("Added a personalized greeting.")); AgentVersionDetails draft = client.createAgentVersion(agentName, - new CreateAgentVersionInput(VoiceAgentSampleUtils.createDefinition(modelType, model, + new CreateAgentVersionInput(VoiceAgentRealtimeSampleUtils.createDefinition(modelType, model, "You are an experimental voice assistant.")) .setDescription("Candidate persona under review.") .setDraft(true)); diff --git a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentWithToolsSample.java b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentWithToolsSample.java index ab14a156ca71b..a5d9db700e638 100644 --- a/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentWithToolsSample.java +++ b/sdk/ai/azure-ai-agents/src/samples/java/com/azure/ai/agents/voice/VoiceAgentWithToolsSample.java @@ -10,7 +10,7 @@ import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.ai.agents.models.AgentVersionDetails; import com.azure.ai.agents.models.CreateAgentVersionInput; -import com.azure.ai.agents.models.RealtimePcmAudioFormat; +import com.openai.models.realtime.RealtimeAudioFormats; import com.openai.models.realtime.RealtimeAudioFormats.AudioPcm.Rate; import com.azure.ai.agents.models.VoiceAgentAudioConfiguration; import com.azure.ai.agents.models.VoiceAgentAudioInputConfiguration; @@ -58,8 +58,11 @@ public static void main(String[] args) { .allowPreview(true) .buildAgentsClient(); - RealtimePcmAudioFormat pcm = new RealtimePcmAudioFormat() - .setRate(Rate._24000); + RealtimeAudioFormats pcm = RealtimeAudioFormats.ofAudioPcm( + RealtimeAudioFormats.AudioPcm.builder() + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .rate(Rate._24000) + .build()); VoiceAgentAudioInputConfiguration input = new VoiceAgentAudioInputConfiguration() .setFormat(pcm) .setTurnDetection(new VoiceAgentServerVadTurnDetection() diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClientTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClientTests.java deleted file mode 100644 index 0692bfdc257ea..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentWebSocketSessionClientTests.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents; - -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; -import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; -import com.azure.ai.agents.models.VoiceAgentTransport; -import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; -import com.azure.core.http.ProxyOptions; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URI; -import java.time.OffsetDateTime; -import java.util.List; -import okhttp3.OkHttpClient; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class BetaVoiceAgentWebSocketSessionClientTests { - @Test - public void connectionUriUsesSelectedTransport() { - VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( - URI.create("https://localhost"), - request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), - "v1", "test-user-agent", null, null); - - URI defaultUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", - new VoiceAgentWebSocketConnectionOptions()); - URI websocketUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", - new VoiceAgentWebSocketConnectionOptions().setTransport(VoiceAgentTransport.WEBSOCKET)); - URI webRtcUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", - new VoiceAgentWebSocketConnectionOptions().setTransport(VoiceAgentTransport.WEBRTC)); - - assertEquals("websocket", queryParameter(defaultUri, "transport")); - assertEquals("websocket", queryParameter(websocketUri, "transport")); - assertEquals("webrtc", queryParameter(webRtcUri, "transport")); - } - - @Test - public void syncTransportHonorsNonProxyHosts() { - InetSocketAddress proxyAddress = new InetSocketAddress("localhost", 8080); - ProxyOptions proxyOptions - = new ProxyOptions(ProxyOptions.Type.HTTP, proxyAddress).setNonProxyHosts("localhost"); - VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( - URI.create("https://localhost"), - request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), - "v1", "test-user-agent", null, proxyOptions); - OkHttpClient client = BetaVoiceAgentWebSocketSessionClient.createHttpClient(configuration, - new VoiceAgentWebSocketConnectionOptions()); - - List bypassed = client.proxySelector().select(URI.create("https://LOCALHOST/session")); - List proxied = client.proxySelector().select(URI.create("https://example.com/session")); - - assertEquals(Proxy.NO_PROXY, bypassed.get(0)); - assertEquals(new Proxy(Proxy.Type.HTTP, proxyAddress), proxied.get(0)); - } - - private static String queryParameter(URI uri, String name) { - for (String parameter : uri.getQuery().split("&")) { - String[] pair = parameter.split("=", 2); - if (name.equals(pair[0])) { - return pair.length == 2 ? pair[1] : ""; - } - } - return null; - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClientTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClientTests.java new file mode 100644 index 0000000000000..5fbdb1144b488 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/BetaVoiceAgentsWebSocketSessionClientTests.java @@ -0,0 +1,221 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents; + +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketClientConfiguration; +import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketUtils; +import com.azure.ai.agents.implementation.realtime.WebSocketSessionTransport; +import com.azure.ai.agents.implementation.realtime.WebSocketTransportOptions; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.ai.agents.models.VoiceAgentTransport; +import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; +import com.azure.ai.agents.models.VoiceAgentWebSocketOverflowStrategy; +import com.azure.core.http.ProxyOptions; +import com.azure.core.http.HttpHeaders; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.List; +import java.util.function.Consumer; +import okhttp3.OkHttpClient; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class BetaVoiceAgentsWebSocketSessionClientTests { + @Test + public void connectionUriUsesSelectedTransport() throws Exception { + VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( + URI.create("https://localhost"), + request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), + "v1", "test-user-agent", null, null); + + URI defaultUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", + new VoiceAgentWebSocketConnectionOptions()); + URI websocketUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", + new VoiceAgentWebSocketConnectionOptions().setTransportType(VoiceAgentTransport.WEBSOCKET)); + URI webRtcUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent", + new VoiceAgentWebSocketConnectionOptions( + new VoiceAgentWebSocketConnectionOptions().setTransportType(VoiceAgentTransport.WEBRTC))); + + assertEquals("websocket", queryParameter(defaultUri, "transport")); + assertEquals("websocket", queryParameter(websocketUri, "transport")); + assertEquals("webrtc", queryParameter(webRtcUri, "transport")); + } + + @Test + public void connectionUrisPreserveEncodedPathsAndReplaceEndpointQuery() throws Exception { + VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( + URI.create("https://localhost:8443/project%20name/?discard=old&api-version=old"), + request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), + "v1", "test-user-agent", null, null); + + URI realtimeUri = VoiceAgentWebSocketUtils.buildWebSocketUri(configuration, "agent/name", + new VoiceAgentWebSocketConnectionOptions().setAgentSessionId("session & id")); + URI liveUri = VoiceAgentWebSocketUtils.buildLiveWebSocketUri(configuration, "agent/name", + new VoiceAgentLiveWebSocketConnectionOptions().setStructuredInputs("{\"name\":\"a & b\"}")); + + for (URI uri : new URI[] { realtimeUri, liveUri }) { + assertEquals("wss", uri.getScheme()); + assertEquals("localhost", uri.getHost()); + assertEquals(8443, uri.getPort()); + assertEquals("v1", queryParameter(uri, "api-version")); + assertEquals(null, queryParameter(uri, "discard")); + } + assertEquals("/project%20name/agents/agent%2Fname/endpoint/protocols/voice", realtimeUri.getRawPath()); + assertEquals("/project%20name/agents/agent%2Fname/endpoint/protocols/voice/live/sessions", + liveUri.getRawPath()); + assertEquals("session & id", queryParameter(realtimeUri, "agent_session_id")); + assertEquals("{\"name\":\"a & b\"}", queryParameter(liveUri, "structured_inputs")); + } + + @Test + public void syncTransportHonorsNonProxyHosts() { + InetSocketAddress proxyAddress = new InetSocketAddress("localhost", 8080); + ProxyOptions proxyOptions + = new ProxyOptions(ProxyOptions.Type.HTTP, proxyAddress).setNonProxyHosts("localhost"); + VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( + URI.create("https://localhost"), + request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), + "v1", "test-user-agent", null, proxyOptions); + OkHttpClient client = WebSocketSessionTransport.createHttpClient(configuration, + new WebSocketTransportOptions(new VoiceAgentWebSocketConnectionOptions())); + + List bypassed = client.proxySelector().select(URI.create("https://LOCALHOST/session")); + List proxied = client.proxySelector().select(URI.create("https://example.com/session")); + + assertEquals(Proxy.NO_PROXY, bypassed.get(0)); + assertEquals(new Proxy(Proxy.Type.HTTP, proxyAddress), proxied.get(0)); + } + + @Test + public void syncConnectionPreservesTokenFailure() { + IllegalStateException failure = new IllegalStateException("Token unavailable"); + VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( + URI.create("https://localhost"), request -> Mono.error(failure), "v1", "test-user-agent", null, null); + + IllegalStateException actual = assertThrows(IllegalStateException.class, + () -> WebSocketSessionTransport.connect(configuration, URI.create("wss://localhost/session"), + new WebSocketTransportOptions(new VoiceAgentWebSocketConnectionOptions()), null, + token -> new HttpHeaders())); + + assertSame(failure, actual); + } + + @Test + public void syncConnectionPreservesHeaderInitializationFailure() { + IllegalStateException failure = new IllegalStateException("Headers unavailable"); + VoiceAgentWebSocketClientConfiguration configuration = new VoiceAgentWebSocketClientConfiguration( + URI.create("https://localhost"), + request -> Mono.just(new com.azure.core.credential.AccessToken("token", OffsetDateTime.now().plusHours(1))), + "v1", "test-user-agent", null, null); + + IllegalStateException actual = assertThrows(IllegalStateException.class, + () -> WebSocketSessionTransport.connect(configuration, URI.create("wss://localhost/session"), + new WebSocketTransportOptions(new VoiceAgentWebSocketConnectionOptions()), null, token -> { + throw failure; + })); + + assertSame(failure, actual); + } + + @Test + public void liveOptionsAndTransportSnapshotAreIndependent() { + Consumer handler = error -> { + }; + VoiceAgentLiveWebSocketConnectionOptions options + = new VoiceAgentLiveWebSocketConnectionOptions().setReceiveBufferCapacity(17) + .setMaxMessageSize(4096) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.DROP_OLDEST) + .setMalformedEventHandler(handler) + .setHandshakeTimeout(Duration.ofSeconds(2)) + .setCloseTimeout(Duration.ofSeconds(3)) + .setStoreEnabled(true) + .setAgentVersionOverride("version-1") + .setStructuredInputs("{\"name\":\"value\"}"); + VoiceAgentLiveWebSocketConnectionOptions copy = new VoiceAgentLiveWebSocketConnectionOptions(options); + WebSocketTransportOptions snapshot = new WebSocketTransportOptions(options); + options.setReceiveBufferCapacity(1) + .setMaxMessageSize(1) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR) + .setMalformedEventHandler(null) + .setHandshakeTimeout(Duration.ofSeconds(10)) + .setCloseTimeout(Duration.ofSeconds(10)) + .setStoreEnabled(false) + .setAgentVersionOverride(null) + .setStructuredInputs(null); + + assertTransportSnapshot(snapshot, handler); + assertTransportSnapshot(new WebSocketTransportOptions(copy), handler); + assertEquals(true, copy.isStoreEnabled()); + assertEquals("version-1", copy.getAgentVersionOverride()); + assertEquals("{\"name\":\"value\"}", copy.getStructuredInputs()); + } + + @Test + public void realtimeTransportSnapshotIsIndependent() { + Consumer handler = error -> { + }; + VoiceAgentWebSocketConnectionOptions options + = new VoiceAgentWebSocketConnectionOptions().setReceiveBufferCapacity(17) + .setMaxMessageSize(4096) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.DROP_OLDEST) + .setMalformedEventHandler(handler) + .setHandshakeTimeout(Duration.ofSeconds(2)) + .setCloseTimeout(Duration.ofSeconds(3)); + WebSocketTransportOptions snapshot = new WebSocketTransportOptions(options); + options.setReceiveBufferCapacity(1) + .setMaxMessageSize(1) + .setOverflowStrategy(VoiceAgentWebSocketOverflowStrategy.ERROR) + .setMalformedEventHandler(null) + .setHandshakeTimeout(Duration.ofSeconds(10)) + .setCloseTimeout(Duration.ofSeconds(10)); + + assertTransportSnapshot(snapshot, handler); + } + + @Test + public void liveOptionsValidateTransportSettings() { + VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions(); + assertEquals(256, options.getReceiveBufferCapacity()); + assertEquals(32 * 1024 * 1024, options.getMaxMessageSize()); + assertEquals(VoiceAgentWebSocketOverflowStrategy.ERROR, options.getOverflowStrategy()); + assertEquals(Duration.ofSeconds(30), options.getHandshakeTimeout()); + assertEquals(Duration.ofSeconds(10), options.getCloseTimeout()); + assertThrows(IllegalArgumentException.class, () -> options.setReceiveBufferCapacity(0)); + assertThrows(IllegalArgumentException.class, () -> options.setReceiveBufferCapacity(65537)); + assertThrows(IllegalArgumentException.class, () -> options.setMaxMessageSize(0)); + assertThrows(NullPointerException.class, () -> options.setOverflowStrategy(null)); + assertThrows(IllegalArgumentException.class, () -> options.setHandshakeTimeout(null)); + assertThrows(IllegalArgumentException.class, () -> options.setHandshakeTimeout(Duration.ZERO)); + assertThrows(IllegalArgumentException.class, () -> options.setCloseTimeout(Duration.ofSeconds(-1))); + assertThrows(NullPointerException.class, () -> new VoiceAgentLiveWebSocketConnectionOptions(null)); + } + + private static void assertTransportSnapshot(WebSocketTransportOptions snapshot, Consumer handler) { + assertEquals(17, snapshot.getReceiveBufferCapacity()); + assertEquals(4096, snapshot.getMaxMessageSize()); + assertEquals(VoiceAgentWebSocketOverflowStrategy.DROP_OLDEST, snapshot.getOverflowStrategy()); + assertSame(handler, snapshot.getMalformedEventHandler()); + assertEquals(Duration.ofSeconds(2), snapshot.getHandshakeTimeout()); + assertEquals(Duration.ofSeconds(3), snapshot.getCloseTimeout()); + } + + private static String queryParameter(URI uri, String name) throws Exception { + for (String parameter : uri.getRawQuery().split("&")) { + String[] pair = parameter.split("=", 2); + if (name.equals(pair[0])) { + return pair.length == 2 ? URLDecoder.decode(pair[1], StandardCharsets.UTF_8.name()) : ""; + } + } + return null; + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/FoundryFeaturesHeaderVerificationTest.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/FoundryFeaturesHeaderVerificationTest.java index 948392401a2a8..87ce4147d12fe 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/FoundryFeaturesHeaderVerificationTest.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/FoundryFeaturesHeaderVerificationTest.java @@ -57,7 +57,9 @@ public void voicePreviewFactoriesAreOnlyPublicOnBetaBuilder() throws ReflectiveO BetaVoiceAgentsTelephonyClient.class, BetaVoiceAgentsTelephonyAsyncClient.class, BetaVoiceAgentsConversationsClient.class, - BetaVoiceAgentsConversationsAsyncClient.class }) { + BetaVoiceAgentsConversationsAsyncClient.class, + BetaVoiceAgentsLiveConversationsClient.class, + BetaVoiceAgentsLiveConversationsAsyncClient.class }) { String methodName = "build" + clientType.getSimpleName(); assertThrows(NoSuchMethodException.class, () -> AgentsClientBuilder.class.getMethod(methodName)); assertTrue(clientType.isInstance( @@ -72,6 +74,13 @@ public void voiceBetaClientsAddPreviewHeadersWithoutLeakingToGaClients() { AgentsClientBuilder builder = customPipeline ? createBuilder(createCustomPipeline(httpClient)) : createBuilder(httpClient); List requests = Arrays.asList( + () -> builder.beta() + .buildBetaVoiceAgentsLiveConversationsClient() + .getAgentConversationWithResponse("agent", "conversation", new RequestOptions()), + () -> builder.beta() + .buildBetaVoiceAgentsLiveConversationsAsyncClient() + .getAgentConversationWithResponse("agent", "conversation", new RequestOptions()) + .block(), () -> builder.beta() .buildBetaVoiceAgentsTelephonyClient() .getTelephonyBindingWithResponse("agent", "binding", new RequestOptions()), @@ -93,6 +102,13 @@ public void voiceBetaClientsAddPreviewHeadersWithoutLeakingToGaClients() { .buildBetaVoiceAgentsTelephonyAsyncClient() .getTelephonyCallJobWithResponse("agent", "job", new RequestOptions()) .block(), + () -> builder.beta() + .buildBetaVoiceAgentsTelephonyClient() + .getCampaignWithResponse("agent", "campaign", new RequestOptions()), + () -> builder.beta() + .buildBetaVoiceAgentsTelephonyAsyncClient() + .getCampaignWithResponse("agent", "campaign", new RequestOptions()) + .block(), () -> builder.beta() .buildBetaVoiceAgentsConversationsClient() .getAgentConversationWithResponse("agent", "conversation", new RequestOptions()), @@ -310,6 +326,20 @@ public void customPipelineDoesNotOverrideExplicitFoundryHeader() { assertEquals(explicitHeader, foundryFeatures(httpClient)); assertEquals(CUSTOM_PIPELINE_VALUE, customPipelineHeader(httpClient)); + + AgentsClientBuilder builder = createBuilder(customPipeline); + builder.beta() + .buildBetaVoiceAgentsLiveConversationsClient() + .getAgentConversationWithResponse("agent", "conversation", requestOptions); + assertEquals(explicitHeader, foundryFeatures(httpClient)); + assertEquals(CUSTOM_PIPELINE_VALUE, customPipelineHeader(httpClient)); + + builder.beta() + .buildBetaVoiceAgentsLiveConversationsAsyncClient() + .getAgentConversationWithResponse("agent", "conversation", requestOptions) + .block(); + assertEquals(explicitHeader, foundryFeatures(httpClient)); + assertEquals(CUSTOM_PIPELINE_VALUE, customPipelineHeader(httpClient)); } @Test @@ -412,11 +442,11 @@ public void webSocketClientsRejectUnsupportedHttpConfiguration() { .retryPolicy(new RetryPolicy()); IllegalStateException syncError - = assertThrows(IllegalStateException.class, () -> builder.beta().buildBetaVoiceAgentWebSocketClient()); + = assertThrows(IllegalStateException.class, () -> builder.beta().buildBetaVoiceAgentsWebSocketClient()); assertTrue(syncError.getMessage().contains("httpClient, pipeline, addPolicy, retryOptions, retryPolicy")); - IllegalStateException asyncError - = assertThrows(IllegalStateException.class, () -> builder.beta().buildBetaVoiceAgentWebSocketAsyncClient()); + IllegalStateException asyncError = assertThrows(IllegalStateException.class, + () -> builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient()); assertEquals(syncError.getMessage(), asyncError.getMessage()); } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategyTest.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategyTest.java new file mode 100644 index 0000000000000..89ea3df07e1ed --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/implementation/CampaignOperationLocationPollingStrategyTest.java @@ -0,0 +1,253 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.implementation; + +import com.azure.ai.agents.AgentsServiceVersion; +import com.azure.ai.agents.models.TelephonyCampaign; +import com.azure.ai.agents.models.TelephonyCampaignOperation; +import com.azure.ai.agents.models.TelephonyCampaignStatus; +import com.azure.core.exception.AzureException; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.HttpHeaders; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.HttpPipeline; +import com.azure.core.http.HttpPipelineBuilder; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.HttpResponse; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.test.http.MockHttpResponse; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Context; +import com.azure.core.util.polling.PollerFlux; +import com.azure.core.util.polling.PollingStrategyOptions; +import com.azure.core.util.polling.SyncPoller; +import com.azure.core.util.serializer.TypeReference; +import java.time.Duration; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.publisher.Mono; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CampaignOperationLocationPollingStrategyTest { + private static final String ENDPOINT = "https://example.test"; + private static final String CAMPAIGN_PATH = "/agents/agent/telephony_campaigns/campaign"; + private static final String MONITOR_PATH = "/agents/agent/telephony_campaign_operations/original"; + private static final HttpHeaderName OPERATION_ID = HttpHeaderName.fromString("Operation-Id"); + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private static final String CAMPAIGN = "{\"name\":\"campaign\",\"connection_name\":\"connection\"," + + "\"source\":{\"type\":\"phone_number\",\"value\":\"+14255550123\"}," + + "\"status\":\"cancelled\",\"operation_id\":\"later-action\"," + "\"created_at\":1,\"updated_at\":1}"; + + static Stream campaignCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of(false, true) + .flatMap( + raw -> Stream.of(HttpMethod.PUT, HttpMethod.POST).map(method -> Arguments.of(async, raw, method)))); + } + + @ParameterizedTest + @MethodSource("campaignCases") + void finalGetUsesOriginalOperationId(boolean async, boolean raw, HttpMethod method) { + Deque> requests = new ArrayDeque<>(); + requests.add(request -> monitorResponse(request, "succeeded")); + requests.add(request -> { + assertEquals(HttpMethod.GET, request.getHttpMethod()); + assertEquals(CAMPAIGN_PATH, request.getUrl().getPath()); + assertTrue(request.getUrl().getQuery().contains("operation_id=original%2Boperation")); + assertFalse(request.getUrl().getQuery().contains("later-action")); + assertNull(request.getHeaders().getValue(HttpHeaderName.IF_MATCH)); + return jsonResponse(request, 200, CAMPAIGN); + }); + + Object result = raw + ? finish(async, initialResponse(method, 202, true, true), requests, BinaryData.class, BinaryData.class) + : finish(async, initialResponse(method, 202, true, true), requests, TelephonyCampaignOperation.class, + TelephonyCampaign.class); + + TelephonyCampaign campaign + = raw ? ((BinaryData) result).toObject(TelephonyCampaign.class) : (TelephonyCampaign) result; + assertEquals("campaign", campaign.getName()); + assertEquals("later-action", campaign.getOperationId()); + assertEquals(TelephonyCampaignStatus.CANCELLED, campaign.getStatus()); + assertTrue(requests.isEmpty()); + } + + static Stream deletionCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of(false, true) + .flatMap(raw -> Stream.of(202, 204).map(status -> Arguments.of(async, raw, status)))); + } + + @ParameterizedTest + @MethodSource("deletionCases") + void deletionCompletesWithoutFinalGet(boolean async, boolean raw, int status) { + Deque> requests = new ArrayDeque<>(); + if (status == 202) { + requests.add(request -> monitorResponse(request, "succeeded")); + } + Object result = raw + ? finish(async, initialResponse(HttpMethod.DELETE, status, status == 202, false), requests, + BinaryData.class, Void.class) + : finish(async, initialResponse(HttpMethod.DELETE, status, status == 202, false), requests, + TelephonyCampaignOperation.class, Void.class); + assertNull(result); + assertTrue(requests.isEmpty()); + } + + static Stream terminalErrorCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of(HttpMethod.POST, HttpMethod.DELETE) + .flatMap( + method -> Stream.of("failed", "cancelled").map(status -> Arguments.of(async, method, status)))); + } + + @ParameterizedTest + @MethodSource("terminalErrorCases") + void unsuccessfulOperationsDoNotFetchOrReturnSuccess(boolean async, HttpMethod method, String status) { + Deque> requests = new ArrayDeque<>(); + requests.add(request -> monitorResponse(request, status)); + AzureException error = assertThrows(AzureException.class, () -> finish(async, + initialResponse(method, 202, true, true), requests, BinaryData.class, BinaryData.class)); + assertTrue(error.getMessage().contains(status)); + assertTrue(requests.isEmpty()); + } + + static Stream finalGetErrorCases() { + return Stream.of(false, true).flatMap(async -> Stream.of(404, 409).map(status -> Arguments.of(async, status))); + } + + @ParameterizedTest + @MethodSource("finalGetErrorCases") + void guardedGetErrorsArePreserved(boolean async, int status) { + Deque> requests = new ArrayDeque<>(); + requests.add(request -> monitorResponse(request, "succeeded")); + requests.add(request -> jsonResponse(request, status, + "{\"error\":{\"code\":\"campaign_operation_mismatch\",\"message\":\"Original campaign unavailable\"}}")); + HttpResponseException error = assertThrows(HttpResponseException.class, () -> finish(async, + initialResponse(HttpMethod.PUT, 201, true, true), requests, BinaryData.class, TelephonyCampaign.class)); + assertEquals(status, error.getResponse().getStatusCode()); + assertTrue(requests.isEmpty()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + void missingOperationIdFailsBeforePolling(boolean async) { + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> finish(async, initialResponse(HttpMethod.POST, 202, true, false), new ArrayDeque<>(), + BinaryData.class, BinaryData.class)); + assertTrue(error.getMessage().contains("Operation-Id")); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + void missingMonitorFailsBeforePolling(boolean async) { + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> finish(async, initialResponse(HttpMethod.POST, 202, false, true), new ArrayDeque<>(), + BinaryData.class, BinaryData.class)); + assertTrue(error.getMessage().contains("Operation-Location")); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + void bodylessFinalGetIsAnError(boolean async) { + Deque> requests = new ArrayDeque<>(); + requests.add(request -> monitorResponse(request, "succeeded")); + requests.add(request -> jsonResponse(request, 200, null)); + IllegalStateException error = assertThrows(IllegalStateException.class, () -> finish(async, + initialResponse(HttpMethod.PUT, 201, true, true), requests, BinaryData.class, TelephonyCampaign.class)); + assertTrue(error.getMessage().contains("response body")); + assertTrue(requests.isEmpty()); + } + + private static Response initialResponse(HttpMethod method, int status, boolean monitor, + boolean operationId) { + HttpHeaders headers = new HttpHeaders(); + if (monitor) { + headers.set(PollingUtils.OPERATION_LOCATION_HEADER, ENDPOINT + MONITOR_PATH); + } + if (operationId) { + headers.set(OPERATION_ID, "original+operation"); + } + String path = CAMPAIGN_PATH + (method == HttpMethod.POST ? ":cancel" : ""); + BinaryData body = method == HttpMethod.DELETE + ? null + : BinaryData + .fromString(method == HttpMethod.PUT ? CAMPAIGN : "{\"id\":\"original\",\"status\":\"queued\"}"); + HttpRequest request = new HttpRequest(method, ENDPOINT + path); + request.getHeaders().set(HttpHeaderName.IF_MATCH, "original-control-token"); + return new SimpleResponse<>(request, status, headers, body); + } + + private static HttpResponse monitorResponse(HttpRequest request, String status) { + assertEquals(HttpMethod.GET, request.getHttpMethod()); + assertEquals(MONITOR_PATH, request.getUrl().getPath()); + return jsonResponse(request, 200, "{\"id\":\"original\",\"status\":\"" + status + "\",\"created_at\":1}"); + } + + private static HttpResponse jsonResponse(HttpRequest request, int status, String body) { + return new MockHttpResponse(request, status, + new HttpHeaders().set(HttpHeaderName.CONTENT_TYPE, "application/json"), + body == null ? new byte[0] : BinaryData.fromString(body).toBytes()); + } + + private static U finish(boolean async, Response initial, + Deque> requests, Class monitorType, Class resultType) { + HttpClient transport = new HttpClient() { + @Override + public Mono send(HttpRequest request) { + assertTrue(async, "Sync polling must use synchronous HTTP."); + return Mono.fromSupplier(() -> respond(request)); + } + + @Override + public HttpResponse sendSync(HttpRequest request, Context context) { + assertFalse(async, "Async polling must use asynchronous HTTP."); + return respond(request); + } + + private HttpResponse respond(HttpRequest request) { + assertFalse(requests.isEmpty(), "Unexpected request: " + request.getUrl()); + return requests.removeFirst().apply(request); + } + }; + HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(transport).build(); + Context context = new Context("campaign-test", "preserved"); + PollingStrategyOptions options = new PollingStrategyOptions(pipeline).setEndpoint(ENDPOINT) + .setServiceVersion(AgentsServiceVersion.getLatest().getVersion()) + .setContext(context); + BetaVoiceAgentsTelephoniesImpl client + = new AgentsClientImpl(pipeline, ENDPOINT, AgentsServiceVersion.getLatest()) + .getBetaVoiceAgentsTelephonies(); + if (async) { + return PollerFlux.create(Duration.ofMillis(1), () -> Mono.just(initial), + new CampaignOperationLocationPollingStrategy(options, requestOptions -> { + assertEquals(context, requestOptions.getContext()); + return client.getCampaignWithResponseAsync("agent", "campaign", requestOptions); + }), TypeReference.createInstance(monitorType), TypeReference.createInstance(resultType)) + .last() + .flatMap(response -> response.getFinalResult()) + .block(TIMEOUT); + } + return SyncPoller.createPoller(Duration.ofMillis(1), () -> initial, + new SyncCampaignOperationLocationPollingStrategy(options, requestOptions -> { + assertEquals(context, requestOptions.getContext()); + return client.getCampaignWithResponse("agent", "campaign", requestOptions); + }), TypeReference.createInstance(monitorType), TypeReference.createInstance(resultType)) + .getFinalResult(TIMEOUT); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEventSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEventSerializationTests.java index b2c6b44a0f551..73e725713237f 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEventSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeConversationItemInputAudioTranscriptionCompletedEventSerializationTests.java @@ -3,10 +3,12 @@ package com.azure.ai.agents.models; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.core.util.BinaryData; +import com.openai.models.realtime.ConversationItemInputAudioTranscriptionCompletedEvent.Usage; import org.junit.jupiter.api.Test; import java.io.IOException; -import java.time.Duration; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -16,9 +18,9 @@ public class RealtimeConversationItemInputAudioTranscriptionCompletedEventSerial @Test public void tokenUsageRoundTrips() throws IOException { - TranscriptTextUsageTokens usage = UnionTypeSerializationTestUtils.deserialize( - "{\"type\":\"tokens\",\"input_tokens\":2,\"output_tokens\":3,\"total_tokens\":5}", - TranscriptTextUsageTokens::fromJson); + Usage usage = OpenAIJsonHelper.fromBinaryData( + BinaryData.fromString("{\"type\":\"tokens\",\"input_tokens\":2,\"output_tokens\":3,\"total_tokens\":5}"), + Usage.class); RealtimeConversationItemInputAudioTranscriptionCompletedEvent event = new RealtimeConversationItemInputAudioTranscriptionCompletedEvent("event", "item", 0, "hello", usage); @@ -26,15 +28,17 @@ public void tokenUsageRoundTrips() throws IOException { RealtimeConversationItemInputAudioTranscriptionCompletedEvent result = UnionTypeSerializationTestUtils .deserialize(json, RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); - assertTrue(json.contains("\"usage\":{\"input_tokens\":2")); - assertEquals(5L, result.getUsageAsTranscriptTextUsageTokens().getTotalTokens()); - assertNull(result.getUsageAsTranscriptTextUsageDuration()); + assertTrue(json.contains("\"input_tokens\":2")); + assertTrue(result.getUsage().isTranscriptTextUsageTokens()); + assertEquals(5L, result.getUsage().asTranscriptTextUsageTokens().totalTokens()); + assertEquals(usage, result.getUsage()); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(result)); } @Test public void durationUsageRoundTrips() throws IOException { - TranscriptTextUsageDuration usage = UnionTypeSerializationTestUtils - .deserialize("{\"type\":\"duration\",\"seconds\":7}", TranscriptTextUsageDuration::fromJson); + Usage usage = OpenAIJsonHelper.fromBinaryData(BinaryData.fromString("{\"type\":\"duration\",\"seconds\":7.5}"), + Usage.class); RealtimeConversationItemInputAudioTranscriptionCompletedEvent event = new RealtimeConversationItemInputAudioTranscriptionCompletedEvent("event", "item", 0, "hello", usage); @@ -42,9 +46,11 @@ public void durationUsageRoundTrips() throws IOException { RealtimeConversationItemInputAudioTranscriptionCompletedEvent result = UnionTypeSerializationTestUtils .deserialize(json, RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); - assertTrue(json.contains("\"usage\":{\"seconds\":7")); - assertEquals(Duration.ofSeconds(7), result.getUsageAsTranscriptTextUsageDuration().getDuration()); - assertNull(result.getUsageAsTranscriptTextUsageTokens()); + assertTrue(json.contains("\"seconds\":7.5")); + assertTrue(result.getUsage().isTranscriptTextUsageDuration()); + assertEquals(7.5, result.getUsage().asTranscriptTextUsageDuration().seconds()); + assertEquals(usage, result.getUsage()); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(result)); } @Test @@ -55,7 +61,19 @@ public void absentUsageReturnsNull() throws IOException { + "\"item_id\":\"item\",\"content_index\":0,\"transcript\":\"hello\"}", RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); - assertNull(event.getUsageAsTranscriptTextUsageTokens()); - assertNull(event.getUsageAsTranscriptTextUsageDuration()); + assertNull(event.getUsage()); + assertTrue(UnionTypeSerializationTestUtils.serialize(event).contains("\"usage\":null")); + } + + @Test + public void usageSurvivesServerEventDispatch() throws IOException { + RealtimeServerEvent event = UnionTypeSerializationTestUtils + .deserialize("{\"type\":\"conversation.item.input_audio_transcription.completed\",\"event_id\":\"event\"," + + "\"item_id\":\"item\",\"content_index\":0,\"transcript\":\"hello\"," + + "\"usage\":{\"type\":\"duration\",\"seconds\":7.5}}", RealtimeServerEvent::fromJson); + + RealtimeConversationItemInputAudioTranscriptionCompletedEvent completed + = (RealtimeConversationItemInputAudioTranscriptionCompletedEvent) event; + assertEquals(7.5, completed.getUsage().asTranscriptTextUsageDuration().seconds()); } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeOpenAIDedupSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeOpenAIDedupSerializationTests.java index d328f824011f4..ec744a5da641f 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeOpenAIDedupSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeOpenAIDedupSerializationTests.java @@ -8,12 +8,10 @@ import com.azure.json.JsonSerializable; import com.azure.json.JsonWriter; import com.openai.models.realtime.LogProbProperties; -import com.openai.models.realtime.NoiseReductionType; import com.openai.models.realtime.RealtimeReasoning; import com.openai.models.realtime.RealtimeReasoningEffort; import com.openai.models.realtime.RealtimeResponseStatus; import com.openai.models.realtime.RealtimeResponseUsage; -import com.openai.models.responses.ResponsePrompt; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -38,45 +36,27 @@ public class RealtimeOpenAIDedupSerializationTests { + "\"usage\":" + USAGE_JSON + "}"; @Test - public void testRealtimeReasoningAndPromptRoundTrip() throws IOException { - RealtimeReasoningEffort[] efforts = { - RealtimeReasoningEffort.MINIMAL, - RealtimeReasoningEffort.LOW, - RealtimeReasoningEffort.MEDIUM, - RealtimeReasoningEffort.HIGH, - RealtimeReasoningEffort.XHIGH }; - - for (RealtimeReasoningEffort effort : efforts) { - RealtimeReasoning reasoning = RealtimeReasoning.builder().effort(effort).build(); - ResponsePrompt prompt = ResponsePrompt.builder().id("pmpt_123").version("2").build(); - RealtimeSessionConfiguration original = new RealtimeSessionConfiguration().setInstructions("Be concise") - .setReasoning(reasoning) - .setPrompt(prompt); - - String json = serialize(original); - assertTrue(json.contains("\"effort\":\"" + effort.asString() + "\"")); - assertTrue(json.contains("\"prompt\":{\"id\":\"pmpt_123\"")); - - RealtimeSessionConfiguration result; + public void testConversationItemObjectTypeRoundTripsPolymorphically() throws IOException { + String[] variants = { + "\"type\":\"message\",\"role\":\"system\",\"content\":[]", + "\"type\":\"message\",\"role\":\"user\",\"content\":[]", + "\"type\":\"message\",\"role\":\"assistant\",\"content\":[]", + "\"type\":\"function_call\",\"call_id\":\"call\",\"name\":\"fn\",\"arguments\":\"{}\"", + "\"type\":\"function_call_output\",\"call_id\":\"call\",\"output\":\"done\"" }; + + for (String variant : variants) { + RealtimeConversationItem item; + try (JsonReader reader = JsonProviders.createReader("{" + variant + ",\"object\":\"realtime.item\"}")) { + item = RealtimeConversationItem.fromJson(reader); + } + String json = serialize(item); + assertTrue(json.contains("\"object\":\"realtime.item\"")); try (JsonReader reader = JsonProviders.createReader(json)) { - result = RealtimeSessionConfiguration.fromJson(reader); + assertEquals(json, serialize(RealtimeConversationItem.fromJson(reader))); } - - assertEquals(effort, result.getReasoning().effort().get()); - assertEquals("pmpt_123", result.getPrompt().id()); - assertEquals("2", result.getPrompt().version().get()); - assertEquals(json, serialize(result)); } } - @Test - public void testAbsentRealtimeReasoningAndPromptRemainAbsent() throws IOException { - String json = serialize(new RealtimeSessionConfiguration().setInstructions("No reasoning")); - - assertFalse(json.contains("\"reasoning\"")); - assertFalse(json.contains("\"prompt\"")); - } - @Test public void testRealtimeReasoningAcrossVoiceSessionModels() throws IOException { String input = "{\"reasoning\":{\"effort\":\"high\"}}"; @@ -99,37 +79,6 @@ public void testRealtimeReasoningAcrossVoiceSessionModels() throws IOException { assertReasoningRoundTrip(responseConfig.getReasoning(), serialize(responseConfig)); } - @Test - public void testNoiseReductionEnumRoundTrip() throws IOException { - NoiseReductionType[] types = { NoiseReductionType.NEAR_FIELD, NoiseReductionType.FAR_FIELD }; - - for (NoiseReductionType type : types) { - com.openai.models.realtime.RealtimeAudioConfigInput.NoiseReduction realtimeNoiseReduction - = com.openai.models.realtime.RealtimeAudioConfigInput.NoiseReduction.builder().type(type).build(); - com.openai.models.realtime.RealtimeTranscriptionSessionAudioInput.NoiseReduction transcriptionNoiseReduction - = com.openai.models.realtime.RealtimeTranscriptionSessionAudioInput.NoiseReduction.builder() - .type(type) - .build(); - RealtimeSessionAudioInput realtime - = new RealtimeSessionAudioInput().setNoiseReduction(realtimeNoiseReduction); - RealtimeTranscriptionSessionAudioInput transcription - = new RealtimeTranscriptionSessionAudioInput().setNoiseReduction(transcriptionNoiseReduction); - - String realtimeJson = serialize(realtime); - String transcriptionJson = serialize(transcription); - assertEquals("{\"noise_reduction\":{\"type\":\"" + type.asString() + "\"}}", realtimeJson); - assertEquals(realtimeJson, transcriptionJson); - - try (JsonReader reader = JsonProviders.createReader(realtimeJson)) { - assertEquals(type, RealtimeSessionAudioInput.fromJson(reader).getNoiseReduction().type().get()); - } - try (JsonReader reader = JsonProviders.createReader(transcriptionJson)) { - assertEquals(type, - RealtimeTranscriptionSessionAudioInput.fromJson(reader).getNoiseReduction().type().get()); - } - } - } - @Test public void testLogProbsRoundTripThroughPolymorphicServerEvent() throws IOException { String input = "{\"type\":\"conversation.item.input_audio_transcription.delta\"," diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionAudioOutputSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionAudioOutputSerializationTests.java deleted file mode 100644 index 1f6a881c9cffb..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionAudioOutputSerializationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.models; - -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class RealtimeSessionAudioOutputSerializationTests { - - @Test - public void builtInVoiceRoundTrips() throws IOException { - RealtimeSessionAudioOutput output = new RealtimeSessionAudioOutput().setVoice(VoiceIds.ALLOY); - assertEquals(VoiceIds.ALLOY, output.getVoiceAsVoiceIds()); - - String json = UnionTypeSerializationTestUtils.serialize(output); - RealtimeSessionAudioOutput result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionAudioOutput::fromJson); - - assertTrue(json.contains("\"voice\":\"alloy\"")); - assertEquals(VoiceIds.ALLOY, result.getVoiceAsVoiceIds()); - assertNull(result.getVoiceAsRealtimeSessionCreateRequestGAAudioOutputVoice()); - } - - @Test - public void customVoiceRoundTrips() throws IOException { - RealtimeSessionAudioOutput output - = new RealtimeSessionAudioOutput().setVoice(new RealtimeSessionCreateRequestGAAudioOutputVoice("voice-id")); - - String json = UnionTypeSerializationTestUtils.serialize(output); - RealtimeSessionAudioOutput result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionAudioOutput::fromJson); - - assertTrue(json.contains("\"voice\":{\"id\":\"voice-id\"}")); - assertEquals("voice-id", result.getVoiceAsRealtimeSessionCreateRequestGAAudioOutputVoice().getId()); - assertNull(result.getVoiceAsVoiceIds()); - } - - @Test - public void absentAndNullVoiceReturnNull() throws IOException { - RealtimeSessionAudioOutput output - = UnionTypeSerializationTestUtils.deserialize("{}", RealtimeSessionAudioOutput::fromJson); - assertNull(output.getVoiceAsVoiceIds()); - assertNull(output.getVoiceAsRealtimeSessionCreateRequestGAAudioOutputVoice()); - - output.setVoice(VoiceIds.ALLOY).setVoice((VoiceIds) null); - assertNull(output.getVoiceAsVoiceIds()); - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionConfigurationSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionConfigurationSerializationTests.java deleted file mode 100644 index 7a2639d3e40d0..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionConfigurationSerializationTests.java +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.models; - -import com.azure.core.util.BinaryData; -import com.openai.models.realtime.RealtimeFunctionTool; -import com.openai.models.realtime.RealtimeToolsConfigUnion; -import com.openai.models.realtime.RealtimeTruncationRetentionRatio; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.time.Duration; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class RealtimeSessionConfigurationSerializationTests { - - @Test - public void tracingVariantsRoundTrip() throws IOException { - RealtimeSessionConfiguration stringResult = roundTrip(new RealtimeSessionConfiguration().setTracing("auto")); - assertEquals("auto", stringResult.getTracingAsString()); - assertNull(stringResult.getTracingAsRealtimeSessionTracingConfiguration()); - - RealtimeSessionTracingConfiguration tracing - = new RealtimeSessionTracingConfiguration().setWorkflowName("workflow") - .setMetadata(Collections.singletonMap("key", BinaryData.fromObject("value"))); - RealtimeSessionConfiguration modelResult = roundTrip(new RealtimeSessionConfiguration().setTracing(tracing)); - assertEquals("workflow", modelResult.getTracingAsRealtimeSessionTracingConfiguration().getWorkflowName()); - assertEquals("value", - modelResult.getTracingAsRealtimeSessionTracingConfiguration() - .getMetadata() - .get("key") - .toObject(String.class)); - assertNull(modelResult.getTracingAsString()); - } - - @Test - public void toolsVariantsRoundTrip() throws IOException { - RealtimeFunctionTool function - = RealtimeFunctionTool.builder().name("lookup").type(RealtimeFunctionTool.Type.FUNCTION).build(); - RealtimeToolsConfigUnion.Mcp mcp - = RealtimeToolsConfigUnion.Mcp.builder().serverLabel("server").serverUrl("https://example.com/mcp").build(); - - RealtimeSessionConfiguration result = roundTrip(new RealtimeSessionConfiguration().setToolsAsOpenAITools( - Arrays.asList(RealtimeToolsConfigUnion.ofFunction(function), RealtimeToolsConfigUnion.ofMcp(mcp)))); - - List tools = result.getToolsAsOpenAITools(); - assertEquals(2, tools.size()); - assertTrue(tools.get(0).isFunction()); - assertEquals("lookup", tools.get(0).asFunction().name().orElse(null)); - assertTrue(tools.get(1).isMcp()); - assertEquals("server", tools.get(1).asMcp().serverLabel()); - } - - @Test - public void deserializesToolsVariants() throws IOException { - RealtimeSessionConfiguration result = UnionTypeSerializationTestUtils.deserialize( - "{\"type\":\"realtime\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\"}," - + "{\"type\":\"mcp\",\"server_label\":\"server\",\"server_url\":\"https://example.com/mcp\"}]}", - RealtimeSessionConfiguration::fromJson); - - List tools = result.getToolsAsOpenAITools(); - assertEquals(2, tools.size()); - assertTrue(tools.get(0).isFunction()); - assertTrue(tools.get(1).isMcp()); - } - - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - RealtimeSessionConfiguration request - = new RealtimeSessionConfiguration().setToolChoice(ToolChoiceOptions.REQUIRED); - assertEquals(ToolChoiceOptions.REQUIRED, request.getToolChoiceAsToolChoiceOptions()); - assertEquals("required", getSerializedToolChoice(request)); - - RealtimeSessionConfiguration stringResult = roundTrip(request); - assertEquals(ToolChoiceOptions.REQUIRED, stringResult.getToolChoiceAsToolChoiceOptions()); - assertNull(stringResult.getToolChoiceAsToolChoiceFunction()); - assertNull(stringResult.getToolChoiceAsToolChoiceMcp()); - - ToolChoiceFunction function = ToolChoiceFunction.builder().name("lookup").build(); - RealtimeSessionConfiguration functionRequest = new RealtimeSessionConfiguration().setToolChoice(function); - assertEquals(parseJson("{\"type\":\"function\",\"name\":\"lookup\"}"), - getSerializedToolChoice(functionRequest)); - - RealtimeSessionConfiguration functionResult = roundTrip(functionRequest); - assertEquals("lookup", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - assertNull(functionResult.getToolChoiceAsToolChoiceMcp()); - - ToolChoiceMcp mcp = ToolChoiceMcp.builder().serverLabel("server").name("search").build(); - RealtimeSessionConfiguration mcpResult = roundTrip(new RealtimeSessionConfiguration().setToolChoice(mcp)); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - assertNull(mcpResult.getToolChoiceAsToolChoiceFunction()); - } - - @Test - public void serverVadDurationsRoundTripAsMilliseconds() throws IOException { - RealtimeServerVadTurnDetection original - = new RealtimeServerVadTurnDetection().setSilenceDuration(Duration.ofMillis(500)) - .setIdleTimeout(Duration.ofMillis(1500)); - - String json = UnionTypeSerializationTestUtils.serialize(original); - assertTrue(json.contains("\"silence_duration_ms\":500")); - assertTrue(json.contains("\"idle_timeout_ms\":1500")); - - RealtimeServerVadTurnDetection result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeServerVadTurnDetection::fromJson); - assertEquals(Duration.ofMillis(500), result.getSilenceDuration()); - assertEquals(Duration.ofMillis(1500), result.getIdleTimeout()); - } - - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - RealtimeSessionConfiguration numberResult - = roundTrip(new RealtimeSessionConfiguration().setMaxOutputTokens(4096L)); - assertEquals(4096L, numberResult.getMaxOutputTokensAsLong()); - assertNull(numberResult.getMaxOutputTokensAsString()); - - RealtimeSessionConfiguration stringResult - = roundTrip(new RealtimeSessionConfiguration().setMaxOutputTokens("inf")); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void truncationVariantsRoundTrip() throws IOException { - RealtimeSessionConfiguration stringResult - = roundTrip(new RealtimeSessionConfiguration().setTruncation("disabled")); - assertEquals("disabled", stringResult.getTruncationAsString()); - assertNull(stringResult.getTruncationAsRealtimeTruncationRetentionRatio()); - - RealtimeTruncationRetentionRatio truncation - = RealtimeTruncationRetentionRatio.builder().retentionRatio(0.8).build(); - RealtimeSessionConfiguration modelResult - = roundTrip(new RealtimeSessionConfiguration().setTruncation(truncation)); - assertEquals(0.8, modelResult.getTruncationAsRealtimeTruncationRetentionRatio().retentionRatio()); - assertNull(modelResult.getTruncationAsString()); - } - - @Test - public void deserializesEveryUnionProperty() throws IOException { - String json = "{\"type\":\"realtime\",\"tracing\":{\"workflow_name\":\"workflow\"}," - + "\"tool_choice\":{\"type\":\"function\",\"name\":\"lookup\"}," + "\"max_output_tokens\":123," - + "\"truncation\":{\"type\":\"retention_ratio\",\"retention_ratio\":0.5}}"; - - RealtimeSessionConfiguration result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionConfiguration::fromJson); - - assertEquals("workflow", result.getTracingAsRealtimeSessionTracingConfiguration().getWorkflowName()); - assertEquals("lookup", result.getToolChoiceAsToolChoiceFunction().name()); - assertEquals(123L, result.getMaxOutputTokensAsLong()); - assertEquals(0.5, result.getTruncationAsRealtimeTruncationRetentionRatio().retentionRatio()); - } - - @Test - public void absentAndNullValuesReturnNull() throws IOException { - RealtimeSessionConfiguration result = UnionTypeSerializationTestUtils.deserialize("{\"type\":\"realtime\"}", - RealtimeSessionConfiguration::fromJson); - assertNull(result.getTracingAsString()); - assertNull(result.getTracingAsRealtimeSessionTracingConfiguration()); - assertNull(result.getToolsAsOpenAITools()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - assertNull(result.getMaxOutputTokensAsLong()); - assertNull(result.getMaxOutputTokensAsString()); - assertNull(result.getTruncationAsString()); - assertNull(result.getTruncationAsRealtimeTruncationRetentionRatio()); - - String serialized - = UnionTypeSerializationTestUtils.serialize(new RealtimeSessionConfiguration().setTracing((String) null) - .setToolsAsOpenAITools(null) - .setToolChoice((ToolChoiceOptions) null) - .setMaxOutputTokens((String) null) - .setTruncation((String) null)); - assertNotNull(serialized); - assertTrue(!serialized.contains("\"tracing\"") - && !serialized.contains("\"tools\"") - && !serialized.contains("\"tool_choice\"") - && !serialized.contains("\"max_output_tokens\"") - && !serialized.contains("\"truncation\"")); - } - - private Object getSerializedToolChoice(RealtimeSessionConfiguration value) throws IOException { - Object serialized = parseJson(UnionTypeSerializationTestUtils.serialize(value)); - return ((Map) serialized).get("tool_choice"); - } - - private Object parseJson(String json) throws IOException { - return UnionTypeSerializationTestUtils.deserialize(json, reader -> reader.readUntyped()); - } - - private RealtimeSessionConfiguration roundTrip(RealtimeSessionConfiguration value) throws IOException { - String json = UnionTypeSerializationTestUtils.serialize(value); - return UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionConfiguration::fromJson); - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionCreatedEventSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionCreatedEventSerializationTests.java index 8be551c94f262..e21004764c71f 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionCreatedEventSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionCreatedEventSerializationTests.java @@ -25,7 +25,7 @@ public void sessionRoundTrips() throws IOException { = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionCreatedEvent::fromJson); assertTrue(json.contains("\"session\":{\"type\":\"realtime\"")); - assertEquals("session", result.getSessionAsVoiceAgentSessionResponseConfiguration().getId()); + assertEquals("session", result.getSession().getId()); } @Test @@ -33,6 +33,6 @@ public void absentSessionReturnsNull() throws IOException { RealtimeSessionCreatedEvent event = UnionTypeSerializationTestUtils.deserialize( "{\"type\":\"session.created\",\"event_id\":\"event\"}", RealtimeSessionCreatedEvent::fromJson); - assertNull(event.getSessionAsVoiceAgentSessionResponseConfiguration()); + assertNull(event.getSession()); } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdateEventSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdateEventSerializationTests.java index b85cdd05de238..cc6ee5e351961 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdateEventSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdateEventSerializationTests.java @@ -3,10 +3,15 @@ package com.azure.ai.agents.models; +import com.openai.models.realtime.RealtimeSessionCreateRequest; +import com.openai.models.realtime.RealtimeTranscriptionSessionCreateRequest; +import com.openai.models.realtime.SessionUpdateEvent.Session; import org.junit.jupiter.api.Test; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -15,27 +20,30 @@ public class RealtimeSessionUpdateEventSerializationTests { @Test public void realtimeSessionRoundTrips() throws IOException { - RealtimeSessionUpdateEvent event = new RealtimeSessionUpdateEvent(new RealtimeSessionConfiguration()); + RealtimeSessionUpdateEvent event = new RealtimeSessionUpdateEvent(Session + .ofRealtimeSessionCreateRequest(RealtimeSessionCreateRequest.builder().instructions("Be concise").build())); String json = UnionTypeSerializationTestUtils.serialize(event); - RealtimeSessionUpdateEvent result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionUpdateEvent::fromJson); + RealtimeSessionUpdateEvent result = assertInstanceOf(RealtimeSessionUpdateEvent.class, + UnionTypeSerializationTestUtils.deserialize(json, RealtimeClientEvent::fromJson)); - assertTrue(json.contains("\"session\":{\"type\":\"realtime\"")); - assertInstanceOf(RealtimeSessionConfiguration.class, result.getSession()); + assertTrue(result.getSession().isRealtimeSessionCreateRequest()); + assertEquals("Be concise", result.getSession().asRealtimeSessionCreateRequest().instructions().get()); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(result)); } @Test public void transcriptionSessionRoundTrips() throws IOException { - RealtimeSessionUpdateEvent event - = new RealtimeSessionUpdateEvent(new RealtimeTranscriptionSessionConfiguration()); + RealtimeSessionUpdateEvent event = new RealtimeSessionUpdateEvent(Session + .ofRealtimeTranscriptionSessionCreateRequest(RealtimeTranscriptionSessionCreateRequest.builder().build())); String json = UnionTypeSerializationTestUtils.serialize(event); - RealtimeSessionUpdateEvent result - = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionUpdateEvent::fromJson); + RealtimeSessionUpdateEvent result = assertInstanceOf(RealtimeSessionUpdateEvent.class, + UnionTypeSerializationTestUtils.deserialize(json, RealtimeClientEvent::fromJson)); - assertTrue(json.contains("\"session\":{\"type\":\"transcription\"")); - assertInstanceOf(RealtimeTranscriptionSessionConfiguration.class, result.getSession()); + assertTrue(result.getSession().isRealtimeTranscriptionSessionCreateRequest()); + assertTrue(json.contains("\"type\":\"transcription\"")); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(result)); } @Test @@ -44,5 +52,37 @@ public void absentSessionReturnsNull() throws IOException { RealtimeSessionUpdateEvent::fromJson); assertNull(event.getSession()); + assertFalse(UnionTypeSerializationTestUtils.serialize(event).contains("\"session\"")); + event = UnionTypeSerializationTestUtils.deserialize("{\"type\":\"session.update\",\"session\":null}", + RealtimeSessionUpdateEvent::fromJson); + assertNull(event.getSession()); + assertFalse(UnionTypeSerializationTestUtils.serialize(event).contains("\"session\"")); + } + + @Test + public void nestedConfigurationRetainsExistingNullOmission() throws IOException { + String session = "{\"type\":\"realtime\",\"model\":\"future-model\",\"audio\":{\"input\":" + + "{\"format\":{\"type\":\"audio/pcm\",\"rate\":24000},\"noise_reduction\":null," + + "\"turn_detection\":{\"type\":\"server_vad\",\"silence_duration_ms\":500}}}," + + "\"tracing\":{\"workflow_name\":\"workflow\"},\"max_output_tokens\":\"inf\"," + + "\"truncation\":{\"type\":\"retention_ratio\",\"retention_ratio\":0.8}," + + "\"tools\":[{\"type\":\"function\",\"name\":\"lookup\"}]}"; + RealtimeSessionUpdateEvent event = UnionTypeSerializationTestUtils.deserialize( + "{\"type\":\"session.update\",\"session\":" + session + "}", RealtimeSessionUpdateEvent::fromJson); + String json = UnionTypeSerializationTestUtils.serialize(event); + assertFalse(json.contains("\"noise_reduction\"")); + assertEquals( + UnionTypeSerializationTestUtils.deserialize(session.replace(",\"noise_reduction\":null", ""), + reader -> reader.readUntyped()), + UnionTypeSerializationTestUtils.deserialize(json, reader -> reader.readMap(r -> r.readUntyped())) + .get("session")); + } + + @Test + public void unknownSessionVariantIsPreserved() throws IOException { + String session = "{\"type\":\"future_session\",\"setting\":true}"; + RealtimeSessionUpdateEvent event = UnionTypeSerializationTestUtils.deserialize( + "{\"type\":\"session.update\",\"session\":" + session + "}", RealtimeSessionUpdateEvent::fromJson); + assertTrue(UnionTypeSerializationTestUtils.serialize(event).contains("\"session\":" + session)); } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEventSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEventSerializationTests.java index 8c4c8de576684..4130b14d8a4d7 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEventSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeSessionUpdatedEventSerializationTests.java @@ -25,7 +25,7 @@ public void sessionRoundTrips() throws IOException { = UnionTypeSerializationTestUtils.deserialize(json, RealtimeSessionUpdatedEvent::fromJson); assertTrue(json.contains("\"session\":{\"type\":\"realtime\"")); - assertEquals("session", result.getSessionAsVoiceAgentSessionResponseConfiguration().getId()); + assertEquals("session", result.getSession().getId()); } @Test @@ -33,6 +33,6 @@ public void absentSessionReturnsNull() throws IOException { RealtimeSessionUpdatedEvent event = UnionTypeSerializationTestUtils.deserialize( "{\"type\":\"session.updated\",\"event_id\":\"event\"}", RealtimeSessionUpdatedEvent::fromJson); - assertNull(event.getSessionAsVoiceAgentSessionResponseConfiguration()); + assertNull(event.getSession()); } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeStandaloneOpenAIDedupSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeStandaloneOpenAIDedupSerializationTests.java index 13cf3c1537e9a..2315fa1ef077c 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeStandaloneOpenAIDedupSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/RealtimeStandaloneOpenAIDedupSerializationTests.java @@ -7,19 +7,20 @@ import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonWriter; +import com.openai.models.realtime.RealtimeAudioFormats; import com.openai.models.realtime.AudioTranscription.Delay; +import com.openai.models.realtime.ConversationItemInputAudioTranscriptionCompletedEvent.Usage; import com.openai.models.realtime.RateLimitsUpdatedEvent.RateLimit; import com.openai.models.realtime.RealtimeAudioInputTurnDetection.SemanticVad.Eagerness; import com.openai.models.realtime.RealtimeResponse; import com.openai.models.realtime.RealtimeResponseCreateParams.Conversation; -import com.openai.models.realtime.RealtimeSessionCreateRequest.Model; -import com.openai.models.realtime.RealtimeSessionCreateRequest.OutputModality; -import com.openai.models.realtime.RealtimeTruncationRetentionRatio; import com.openai.models.realtime.ResponseContentPartAddedEvent.Part; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; import java.util.Arrays; +import java.util.Collections; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -31,81 +32,100 @@ public class RealtimeStandaloneOpenAIDedupSerializationTests { @Test - public void testPcmRateRoundTripPolymorphically() throws IOException { - com.openai.models.realtime.RealtimeAudioFormats.AudioPcm.Rate rate - = com.openai.models.realtime.RealtimeAudioFormats.AudioPcm.Rate._24000; - RealtimePcmAudioFormat original = new RealtimePcmAudioFormat().setRate(rate); - RealtimePcmAudioFormat result = assertInstanceOf(RealtimePcmAudioFormat.class, - deserialize(serialize(original), RealtimeAudioFormat::fromJson)); - - assertEquals(rate, result.getRate()); - assertEquals(serialize(original), serialize(result)); + public void testAudioFormatsAcrossFoundryContainers() throws IOException { + for (String formatJson : Arrays.asList("{\"type\":\"audio/pcm\",\"rate\":24000}", "{\"type\":\"audio/pcma\"}", + "{\"type\":\"audio/pcmu\"}", "{\"type\":\"future_audio\",\"setting\":true}")) { + String json = "{\"format\":" + formatJson + "}"; + VoiceAgentAudioInputConfiguration input = deserialize(json, VoiceAgentAudioInputConfiguration::fromJson); + VoiceAgentAudioOutputConfiguration output + = deserialize("{\"voice\":\"en-US-AvaNeural\",\"format\":" + formatJson + "}", + VoiceAgentAudioOutputConfiguration::fromJson); + VoiceResponseAudioOutput response = deserialize(json, VoiceResponseAudioOutput::fromJson); + RealtimeResponseContentPart part = deserialize(json, RealtimeResponseContentPart::fromJson); + + assertJsonFieldEquals(formatJson, input, "format"); + assertJsonFieldEquals(formatJson, output, "format"); + assertJsonFieldEquals(formatJson, response, "format"); + assertJsonFieldEquals(formatJson, part, "format"); + assertEquals("en-US-AvaNeural", output.getVoice()); + assertStable(input, VoiceAgentAudioInputConfiguration::fromJson); + assertStable(output, VoiceAgentAudioOutputConfiguration::fromJson); + assertStable(response, VoiceResponseAudioOutput::fromJson); + assertStable(part, RealtimeResponseContentPart::fromJson); + assertEquals(input.getFormat(), response.getFormat()); + assertEquals(input.getFormat(), part.getFormat()); + assertEquals(input.getFormat(), output.getFormat()); + } + + RealtimeAudioFormats pcm = RealtimeAudioFormats.ofAudioPcm(RealtimeAudioFormats.AudioPcm.builder() + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .rate(RealtimeAudioFormats.AudioPcm.Rate._24000) + .build()); + assertTrue(serialize(new VoiceAgentAudioInputConfiguration().setFormat(pcm)).contains("\"rate\":24000")); + assertTrue(serialize(new VoiceAgentAudioOutputConfiguration().setFormat(pcm)).contains("\"rate\":24000")); + VoiceAgentAudioInputConfiguration roundTripped + = deserialize(serialize(new VoiceAgentAudioInputConfiguration().setFormat(pcm)), + VoiceAgentAudioInputConfiguration::fromJson); + assertTrue(roundTripped.getFormat().isAudioPcm()); } @Test - public void testSessionModelAndOutputModalityValuesRoundTrip() throws IOException { - String[] modelValues = { - "gpt-realtime", - "gpt-realtime-1.5", - "gpt-realtime-2", - "gpt-realtime-2.1", - "gpt-realtime-2.1-mini", - "gpt-realtime-2025-08-28", - "gpt-4o-realtime-preview", - "gpt-4o-realtime-preview-2024-10-01", - "gpt-4o-realtime-preview-2024-12-17", - "gpt-4o-realtime-preview-2025-06-03", - "gpt-4o-mini-realtime-preview", - "gpt-4o-mini-realtime-preview-2024-12-17", - "gpt-realtime-mini", - "gpt-realtime-mini-2025-10-06", - "gpt-realtime-mini-2025-12-15", - "gpt-audio-1.5", - "gpt-audio-mini", - "gpt-audio-mini-2025-10-06", - "gpt-audio-mini-2025-12-15", - "future-realtime-model" }; - - for (String modelValue : modelValues) { - RealtimeSessionConfiguration original = new RealtimeSessionConfiguration().setModel(Model.of(modelValue)) - .setOutputModalities(Arrays.asList(OutputModality.TEXT, OutputModality.AUDIO)); - String json = serialize(original); - RealtimeSessionConfiguration result = deserialize(json, RealtimeSessionConfiguration::fromJson); - - assertEquals(modelValue, result.getModel().asString()); - assertEquals(OutputModality.TEXT, result.getOutputModalities().get(0)); - assertEquals(OutputModality.AUDIO, result.getOutputModalities().get(1)); - assertEquals(json, serialize(result)); + public void testNullAndAbsentAudioFormatsAreOmitted() throws IOException { + for (String json : Arrays.asList("{}", "{\"format\":null}")) { + VoiceAgentAudioInputConfiguration input = deserialize(json, VoiceAgentAudioInputConfiguration::fromJson); + VoiceAgentAudioOutputConfiguration output = deserialize(json, VoiceAgentAudioOutputConfiguration::fromJson); + VoiceResponseAudioOutput response = deserialize(json, VoiceResponseAudioOutput::fromJson); + RealtimeResponseContentPart part = deserialize(json, RealtimeResponseContentPart::fromJson); + assertNull(input.getFormat()); + assertNull(output.getFormat()); + assertNull(response.getFormat()); + assertNull(part.getFormat()); + assertFalse(serialize(input).contains("\"format\"")); + assertFalse(serialize(output).contains("\"format\"")); + assertFalse(serialize(response).contains("\"format\"")); + assertFalse(serialize(part).contains("\"format\"")); + } + } + + @Test + public void testMcpErrorVariantsRoundTripThroughConversationHierarchy() throws IOException { + for (String errorJson : Arrays.asList( + "{\"type\":\"protocol_error\",\"code\":-32600,\"message\":\"bad request\"}", + "{\"type\":\"http_error\",\"code\":503,\"message\":\"unavailable\"}", + "{\"type\":\"tool_execution_error\",\"message\":\"failed\"}", + "{\"type\":\"future_error\",\"detail\":\"preserved\"}")) { + String json = "{\"type\":\"mcp_call\",\"id\":\"item-1\",\"server_label\":\"server\",\"name\":\"lookup\"," + + "\"arguments\":\"{}\",\"created_at\":123,\"response_id\":\"resp-1\",\"error\":" + errorJson + "}"; + RealtimeMcpToolCall call + = assertInstanceOf(RealtimeMcpToolCall.class, deserialize(json, RealtimeConversationItem::fromJson)); + if (errorJson.contains("\"protocol_error\"")) { + assertTrue(call.getError().isProtocol()); + } else if (errorJson.contains("\"http_error\"")) { + assertTrue(call.getError().isHttp()); + } else if (errorJson.contains("\"tool_execution_error\"")) { + assertTrue(call.getError().isToolExecution()); + } + assertEquals(OffsetDateTime.parse("1970-01-01T00:02:03Z"), call.getCreatedAt()); + assertEquals("resp-1", call.getResponseId()); + String serialized = serialize(call); + assertJsonFieldEquals(errorJson, call, "error"); + assertFalse(serialized.contains("\"created_at\"")); + assertFalse(serialized.contains("\"response_id\"")); + RealtimeMcpToolCall result = assertInstanceOf(RealtimeMcpToolCall.class, + deserialize(serialized, RealtimeConversationItem::fromJson)); + assertEquals(call.getError(), result.getError()); + assertEquals(serialized, + serialize(new RealtimeMcpToolCall("item-1", "server", "lookup", "{}").setError(call.getError()))); } } @Test - public void testTruncationAndTracingUnionsRoundTrip() throws IOException { - RealtimeTruncationRetentionRatio retentionRatio = RealtimeTruncationRetentionRatio.builder() - .retentionRatio(0.8) - .tokenLimits(RealtimeTruncationRetentionRatio.TokenLimits.builder().postInstructions(1024).build()) - .build(); - for (String strategy : Arrays.asList("auto", "disabled")) { - RealtimeSessionConfiguration original = new RealtimeSessionConfiguration().setTruncation(strategy); - RealtimeSessionConfiguration result - = deserialize(serialize(original), RealtimeSessionConfiguration::fromJson); - assertEquals(strategy, result.getTruncationAsString()); - assertStable(original, RealtimeSessionConfiguration::fromJson); + public void testNullAndAbsentMcpErrorsAreOmitted() throws IOException { + for (String json : Arrays.asList("{}", "{\"error\":null}")) { + RealtimeMcpToolCall call = deserialize(json, RealtimeMcpToolCall::fromJson); + assertNull(call.getError()); + assertFalse(serialize(call).contains("\"error\"")); } - RealtimeSessionConfiguration retained = new RealtimeSessionConfiguration().setTruncation(retentionRatio); - RealtimeSessionConfiguration retainedResult - = deserialize(serialize(retained), RealtimeSessionConfiguration::fromJson); - assertEquals(0.8, retainedResult.getTruncationAsRealtimeTruncationRetentionRatio().retentionRatio()); - assertStable(retained, RealtimeSessionConfiguration::fromJson); - - RealtimeSessionTracingConfiguration tracing - = new RealtimeSessionTracingConfiguration().setWorkflowName("voice").setGroupId("group-1"); - RealtimeSessionConfiguration traced = new RealtimeSessionConfiguration().setTracing(tracing); - RealtimeSessionConfiguration tracedResult - = deserialize(serialize(traced), RealtimeSessionConfiguration::fromJson); - assertEquals("voice", tracedResult.getTracingAsRealtimeSessionTracingConfiguration().getWorkflowName()); - assertStable(new RealtimeSessionConfiguration().setTracing("auto"), RealtimeSessionConfiguration::fromJson); - assertFalse(serialize(new RealtimeSessionConfiguration().setTracing((String) null)).contains("tracing")); } @Test @@ -288,8 +308,6 @@ public void testContentPartTypesRoundTripPolymorphically() throws IOException { public void testDelayConversationAndEagernessValuesRoundTrip() throws IOException { Delay[] delays = { Delay.MINIMAL, Delay.LOW, Delay.MEDIUM, Delay.HIGH, Delay.XHIGH }; for (Delay delay : delays) { - AudioTranscription transcription = new AudioTranscription().setDelay(delay); - assertEquals(delay, deserialize(serialize(transcription), AudioTranscription::fromJson).getDelay()); VoiceAgentInputTranscription voiceTranscription = new VoiceAgentInputTranscription(VoiceAgentInputTranscriptionModel.GPT_REALTIME_WHISPER) .setDelay(delay); @@ -309,9 +327,6 @@ public void testDelayConversationAndEagernessValuesRoundTrip() throws IOExceptio Eagerness.MEDIUM, Eagerness.HIGH, Eagerness.AUTO }) { - RealtimeSemanticVadTurnDetection realtime = new RealtimeSemanticVadTurnDetection().setEagerness(eagerness); - assertEquals(eagerness, - deserialize(serialize(realtime), RealtimeSemanticVadTurnDetection::fromJson).getEagerness()); VoiceAgentSemanticVadTurnDetection voice = new VoiceAgentSemanticVadTurnDetection().setEagerness(eagerness); assertEquals(eagerness, deserialize(serialize(voice), VoiceAgentSemanticVadTurnDetection::fromJson).getEagerness()); @@ -322,16 +337,100 @@ public void testDelayConversationAndEagernessValuesRoundTrip() throws IOExceptio public void testTranscriptionTokenDetailsRoundTripPolymorphically() throws IOException { String json = "{\"type\":\"tokens\",\"input_tokens\":10,\"output_tokens\":5,\"total_tokens\":15," + "\"input_token_details\":{\"audio_tokens\":7,\"text_tokens\":3}}"; - TranscriptTextUsageTokens usage - = assertInstanceOf(TranscriptTextUsageTokens.class, deserialize(json, TranscriptTextUsage::fromJson)); - TranscriptTextInputTokenDetails details = usage.getInputTokenDetails(); - assertEquals(7L, details.getAudioTokens()); - assertEquals(3L, details.getTextTokens()); - assertStable(usage, TranscriptTextUsage::fromJson); + RealtimeConversationItemInputAudioTranscriptionCompletedEvent event = deserialize("{\"usage\":" + json + "}", + RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); + Usage.TranscriptTextUsageTokens usage = event.getUsage().asTranscriptTextUsageTokens(); + Usage.TranscriptTextUsageTokens.InputTokenDetails details = usage.inputTokenDetails().get(); + assertEquals(7L, details.audioTokens().get().longValue()); + assertEquals(3L, details.textTokens().get().longValue()); + assertStable(event, RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); } @Test - public void testRealtimeResponseEnumsAndAbsentValues() throws IOException { + public void testTranscriptionLanguagesRoundTripWithExistingPayloads() throws IOException { + String languages = "[{\"code\":\"en\",\"confidence\":0.9},null,{\"code\":\"fr\"}]"; + String usage = "{\"type\":\"duration\",\"seconds\":1.5}"; + String logprobs = "[{\"token\":\"hello\",\"logprob\":-0.25,\"bytes\":[104]}]"; + RealtimeConversationItemInputAudioTranscriptionCompletedEvent event + = assertInstanceOf(RealtimeConversationItemInputAudioTranscriptionCompletedEvent.class, + deserialize("{\"type\":\"conversation.item.input_audio_transcription.completed\"," + + "\"event_id\":\"event-1\",\"item_id\":\"item-1\",\"content_index\":0,\"transcript\":\"hello\"," + + "\"languages\":" + languages + ",\"usage\":" + usage + ",\"logprobs\":" + logprobs + + ",\"phrases\":[]}", RealtimeServerEvent::fromJson)); + + assertEquals("en", event.getLanguages().get(0).code()); + assertNull(event.getLanguages().get(1)); + assertEquals("fr", event.getLanguages().get(2).code()); + assertJsonFieldEquals(languages, event, "languages"); + assertJsonFieldEquals(usage, event, "usage"); + assertJsonFieldEquals(logprobs, event, "logprobs"); + assertJsonFieldEquals("[]", event, "phrases"); + assertStable(event, RealtimeServerEvent::fromJson); + } + + @Test + public void testMcpListedToolsPreserveSchemaAndAnnotations() throws IOException { + String toolJson = "{\"name\":\"search\",\"description\":\"Search records\"," + + "\"input_schema\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}}," + + "\"required\":[\"query\"],\"additionalProperties\":false}," + + "\"annotations\":{\"readOnlyHint\":true,\"provider\":{\"limits\":[1,2]}},\"future_setting\":true}"; + RealtimeMcpListTools item = assertInstanceOf(RealtimeMcpListTools.class, + deserialize("{\"type\":\"mcp_list_tools\",\"server_label\":\"server\",\"id\":\"item-1\"," + "\"tools\":[" + + toolJson + ",null],\"created_at\":123,\"response_id\":\"response-1\"}", + RealtimeConversationItem::fromJson)); + + com.openai.models.realtime.RealtimeMcpListTools.Tool tool = item.getTools().get(0); + assertEquals("search", tool.name()); + assertEquals("Search records", tool.description().get()); + assertNull(item.getTools().get(1)); + assertJsonFieldEquals("[" + toolJson + ",null]", item, "tools"); + assertEquals(OffsetDateTime.parse("1970-01-01T00:02:03Z"), item.getCreatedAt()); + assertEquals("response-1", item.getResponseId()); + assertFalse(serialize(item).contains("\"created_at\"")); + assertFalse(serialize(item).contains("\"response_id\"")); + assertStable(item, RealtimeConversationItem::fromJson); + + RealtimeMcpListTools constructed + = new RealtimeMcpListTools("server", Arrays.asList(tool.toBuilder().build(), null)); + assertJsonFieldEquals("[" + toolJson + ",null]", constructed, "tools"); + assertStable(constructed, RealtimeConversationItem::fromJson); + } + + @Test + public void testNullAbsentAndEmptyLanguageAndToolLists() throws IOException { + for (String json : Arrays.asList("{}", "{\"languages\":null,\"tools\":null}", + "{\"languages\":[],\"tools\":[]}")) { + RealtimeConversationItemInputAudioTranscriptionCompletedEvent event + = deserialize(json, RealtimeConversationItemInputAudioTranscriptionCompletedEvent::fromJson); + RealtimeMcpListTools item = deserialize(json, RealtimeMcpListTools::fromJson); + if (json.contains("[]")) { + assertTrue(event.getLanguages().isEmpty()); + assertTrue(item.getTools().isEmpty()); + assertJsonFieldEquals("[]", event, "languages"); + assertJsonFieldEquals("[]", item, "tools"); + } else { + assertNull(event.getLanguages()); + assertNull(item.getTools()); + assertFalse(serialize(event).contains("\"languages\"")); + assertFalse(serialize(item).contains("\"tools\"")); + } + } + } + + @Test + public void testMcpListedToolReplacementPreservesAgentToolHierarchy() throws IOException { + FunctionTool original = new FunctionTool("lookup", Collections.emptyMap(), false); + String json = serialize(original); + FunctionTool result = assertInstanceOf(FunctionTool.class, deserialize(json, Tool::fromJson)); + assertEquals("lookup", result.getName()); + assertEquals(ToolType.FUNCTION, result.getType()); + assertFalse(json.contains("\"input_schema\"")); + assertFalse(json.contains("\"annotations\"")); + assertEquals(json, serialize(result)); + } + + @Test + public void testRealtimeResponseEnums() throws IOException { RealtimeResponse.Status[] statuses = { RealtimeResponse.Status.COMPLETED, RealtimeResponse.Status.CANCELLED, @@ -353,15 +452,12 @@ public void testRealtimeResponseEnumsAndAbsentValues() throws IOException { } } - String emptyAudio = serialize(new AudioTranscription()); - assertFalse(emptyAudio.contains("delay")); - assertNull(deserialize(emptyAudio, AudioTranscription::fromJson).getDelay()); - String emptySession = serialize(new RealtimeSessionConfiguration()); - assertFalse(emptySession.contains("tracing")); - assertFalse(emptySession.contains("truncation")); - assertNull(deserialize(emptySession, RealtimeSessionConfiguration::fromJson) - .getTracingAsRealtimeSessionTracingConfiguration()); - assertTrue(emptySession.contains("\"type\":\"realtime\"")); + } + + private static void assertJsonFieldEquals(String expected, JsonSerializable value, String field) + throws IOException { + assertEquals(deserialize(expected, JsonReader::readUntyped), + deserialize(serialize(value), reader -> reader.readMap(JsonReader::readUntyped)).get(field)); } private static > void assertStable(T value, Deserializer deserializer) diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/StructuredInputSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/StructuredInputSerializationTests.java new file mode 100644 index 0000000000000..fd99042ab32e5 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/StructuredInputSerializationTests.java @@ -0,0 +1,140 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.core.util.BinaryData; +import com.azure.json.JsonProviders; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonWriter; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collections; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StructuredInputSerializationTests { + private static final String DECIMAL = "0.123456789012345678901234567890"; + private static final String INTEGER = "9223372036854775808123456789"; + private static final String NESTED = "{\"items\":[" + DECIMAL + "," + INTEGER + ",1e400,null,\"text\",false]}"; + private static final String INPUTS + = "{\"decimal\":" + DECIMAL + ",\"integer\":" + INTEGER + ",\"exponent\":1e400,\"nested\":" + NESTED + + ",\"text\":\"line\\n\\\"quoted\\\"\",\"flag\":true,\"nil\":null}"; + + @ParameterizedTest + @ValueSource(strings = { "recipient", "create", "job", "response" }) + public void structuredInputsRetainExactJsonValues(String model) throws IOException { + JsonSerializable value; + Map inputs; + String json = "{\"destination\":{\"type\":\"phone_number\",\"value\":\"+15551234567\"}," + + "\"connection_name\":\"connection\",\"structured_inputs\":" + INPUTS + "}"; + try (JsonReader reader = JsonProviders.createReader(json)) { + switch (model) { + case "recipient": + TelephonyRecipient recipient = TelephonyRecipient.fromJson(reader); + inputs = recipient.getStructuredInputs(); + value = recipient; + break; + + case "create": + TelephonyCallJobCreate create = TelephonyCallJobCreate.fromJson(reader); + inputs = create.getStructuredInputs(); + value = create; + break; + + case "job": + TelephonyCallJob job = TelephonyCallJob.fromJson(reader); + inputs = job.getStructuredInputs(); + value = job; + break; + + case "response": + AzureCreateResponseOptions response = AzureCreateResponseOptions.fromJson(reader); + inputs = response.getStructuredInputs(); + value = response; + break; + + default: + throw new IllegalArgumentException("Unexpected model " + model); + } + } + assertEquals(new BigDecimal(DECIMAL), inputs.get("decimal").toObject(BigDecimal.class)); + assertEquals(new BigInteger(INTEGER), inputs.get("integer").toObject(BigInteger.class)); + assertEquals(new BigDecimal("1e400"), inputs.get("exponent").toObject(BigDecimal.class)); + assertEquals(NESTED, inputs.get("nested").toString()); + assertEquals("line\n\"quoted\"", inputs.get("text").toObject(String.class)); + assertEquals(Boolean.TRUE, inputs.get("flag").toObject(Boolean.class)); + assertTrue(inputs.containsKey("nil")); + assertNull(inputs.get("nil")); + assertTrue(serialize(value).contains("\"structured_inputs\":" + INPUTS)); + } + + @ParameterizedTest + @ValueSource(strings = { "voice", "prompt" }) + public void agentDefinitionDefaultsAndSchemasRetainExactNumbers(String kind) throws IOException { + String definition = "{\"kind\":\"" + kind + "\",\"structured_inputs\":{\"amount\":{\"default_value\":" + DECIMAL + + ",\"schema\":{\"maximum\":" + INTEGER + ",\"examples\":[" + NESTED + "]}}}}"; + JsonSerializable agent; + StructuredInputDefinition input; + try (JsonReader reader = JsonProviders.createReader(definition)) { + if ("voice".equals(kind)) { + VoiceAgentDefinition voice = VoiceAgentDefinition.fromJson(reader); + input = voice.getStructuredInputs().get("amount"); + agent = voice; + } else { + PromptAgentDefinition prompt = PromptAgentDefinition.fromJson(reader); + input = prompt.getStructuredInputs().get("amount"); + agent = prompt; + } + } + assertEquals(new BigDecimal(DECIMAL), input.getDefaultValue().toObject(BigDecimal.class)); + assertEquals(new BigInteger(INTEGER), input.getSchema().get("maximum").toObject(BigInteger.class)); + assertEquals("[" + NESTED + "]", input.getSchema().get("examples").toString()); + String serialized = serialize(agent); + assertTrue(serialized.contains("\"default_value\":" + DECIMAL)); + assertTrue(serialized.contains("\"maximum\":" + INTEGER)); + assertTrue(serialized.contains("\"examples\":[" + NESTED + "]")); + } + + @Test + public void absentNullAndEmptyInputsRemainDistinct() throws IOException { + try (JsonReader reader = JsonProviders.createReader("{}")) { + assertNull(AzureCreateResponseOptions.fromJson(reader).getStructuredInputs()); + } + try (JsonReader reader = JsonProviders.createReader("{\"structured_inputs\":null}")) { + assertNull(AzureCreateResponseOptions.fromJson(reader).getStructuredInputs()); + } + try (JsonReader reader = JsonProviders.createReader("{\"structured_inputs\":{}}")) { + AzureCreateResponseOptions options = AzureCreateResponseOptions.fromJson(reader); + assertTrue(options.getStructuredInputs().isEmpty()); + assertTrue(serialize(options).contains("\"structured_inputs\":{}")); + } + } + + @Test + public void callerProvidedStringInputsRemainJsonStrings() throws IOException { + AzureCreateResponseOptions options = new AzureCreateResponseOptions() + .setStructuredInputs(Collections.singletonMap("text", BinaryData.fromString("hello"))); + assertTrue(serialize(options).contains("\"structured_inputs\":{\"text\":\"hello\"}")); + StructuredInputDefinition definition + = new StructuredInputDefinition().setDefaultValue(BinaryData.fromString("hello")); + assertTrue(serialize(definition).contains("\"default_value\":\"hello\"")); + } + + private static String serialize(JsonSerializable value) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (JsonWriter writer = JsonProviders.createWriter(output)) { + value.toJson(writer); + } + return output.toString("UTF-8"); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentDefinitionSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentDefinitionSerializationTests.java index 2a8168adaf6e8..da797a92724d1 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentDefinitionSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentDefinitionSerializationTests.java @@ -7,9 +7,7 @@ import com.azure.json.JsonProviders; import com.azure.json.JsonReader; import com.azure.json.JsonWriter; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; +import com.openai.models.realtime.RealtimeAudioFormats; import com.openai.models.realtime.RealtimeAudioFormats.AudioPcm.Rate; import org.junit.jupiter.api.Test; @@ -21,69 +19,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; public class VoiceAgentDefinitionSerializationTests { - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - VoiceAgentDefinition longResult = roundTrip(new VoiceAgentDefinition().setMaxOutputTokens(512L)); - assertEquals(512L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceAgentDefinition stringResult = roundTrip(new VoiceAgentDefinition().setMaxOutputTokens("inf")); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - VoiceAgentDefinition definition = new VoiceAgentDefinition().setToolChoice(ToolChoiceOptions.AUTO); - assertEquals(ToolChoiceOptions.AUTO, definition.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentDefinition stringResult = roundTrip(definition); - assertEquals(ToolChoiceOptions.AUTO, stringResult.getToolChoiceAsToolChoiceOptions()); - assertNull(stringResult.getToolChoiceAsToolChoiceFunction()); - assertNull(stringResult.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentDefinition functionResult - = roundTrip(new VoiceAgentDefinition().setToolChoice(ToolChoiceFunction.builder().name("lookup").build())); - assertEquals("lookup", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentDefinition mcpResult = roundTrip(new VoiceAgentDefinition() - .setToolChoice(ToolChoiceMcp.builder().serverLabel("server").name("search").build())); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - } - - @Test - public void absentAndNullValuesReturnNull() throws IOException { - VoiceAgentDefinition result - = UnionTypeSerializationTestUtils.deserialize("{\"kind\":\"voice\"}", VoiceAgentDefinition::fromJson); - assertNull(result.getMaxOutputTokensAsLong()); - assertNull(result.getMaxOutputTokensAsString()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentDefinition cleared = new VoiceAgentDefinition().setMaxOutputTokens("inf") - .setMaxOutputTokens((String) null) - .setToolChoice(ToolChoiceOptions.AUTO) - .setToolChoice((ToolChoiceOptions) null); - assertNull(cleared.getMaxOutputTokensAsString()); - assertNull(cleared.getToolChoiceAsToolChoiceOptions()); - } - - private VoiceAgentDefinition roundTrip(VoiceAgentDefinition value) throws IOException { - String json = UnionTypeSerializationTestUtils.serialize(value); - return UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentDefinition::fromJson); - } - @Test public void fullVoiceDefinitionRoundTrips() throws IOException { - RealtimePcmAudioFormat pcm = new RealtimePcmAudioFormat().setRate(Rate._24000); + RealtimeAudioFormats pcm = RealtimeAudioFormats.ofAudioPcm(RealtimeAudioFormats.AudioPcm.builder() + .type(RealtimeAudioFormats.AudioPcm.Type.AUDIO_PCM) + .rate(Rate._24000) + .build()); VoiceAgentAudioInputConfiguration input = new VoiceAgentAudioInputConfiguration().setFormat(pcm) .setTurnDetection(new VoiceAgentServerVadTurnDetection().setThreshold(0.5) .setPrefixPaddingMs(300L) @@ -136,9 +81,7 @@ public void fullVoiceDefinitionRoundTrips() throws IOException { assertEquals(VoiceOutputModality.AUDIO, voice.getOutputModalities().get(0)); VoiceAgentAudioInputConfiguration deserializedInput = voice.getAudio().getInput(); - RealtimePcmAudioFormat deserializedInputFormat - = assertInstanceOf(RealtimePcmAudioFormat.class, deserializedInput.getFormat()); - assertEquals(pcm.getRate(), deserializedInputFormat.getRate()); + assertEquals(Rate._24000, deserializedInput.getFormat().asAudioPcm().rate().get()); VoiceAgentServerVadTurnDetection deserializedVad = assertInstanceOf(VoiceAgentServerVadTurnDetection.class, deserializedInput.getTurnDetection()); VoiceAgentServerVadTurnDetection originalVad = (VoiceAgentServerVadTurnDetection) input.getTurnDetection(); @@ -149,9 +92,7 @@ public void fullVoiceDefinitionRoundTrips() throws IOException { assertEquals(input.getTranscription().getModel(), deserializedInput.getTranscription().getModel()); VoiceAgentAudioOutputConfiguration deserializedOutput = voice.getAudio().getOutput(); - RealtimePcmAudioFormat deserializedOutputFormat - = assertInstanceOf(RealtimePcmAudioFormat.class, deserializedOutput.getFormat()); - assertEquals(pcm.getRate(), deserializedOutputFormat.getRate()); + assertEquals(Rate._24000, deserializedOutput.getFormat().asAudioPcm().rate().get()); assertEquals(output.getVoice(), deserializedOutput.getVoice()); assertEquals(output.getVoiceType(), deserializedOutput.getVoiceType()); diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentHandoffSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentHandoffSerializationTests.java new file mode 100644 index 0000000000000..aba0c462a96bb --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentHandoffSerializationTests.java @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VoiceAgentHandoffSerializationTests { + private static final String EVENT_FIELDS = "\"event_id\":\"event\",\"handoff_id\":\"handoff\",\"edge_id\":\"edge\"," + + "\"from_node_id\":\"$entrypoint\",\"to_node_id\":\"specialist\",\"from_model\":\"source\"," + + "\"to_model\":\"target\",\"tool_call_id\":\"call\",\"node_generation\":2"; + + @Test + public void abortedEventBridgesOpenAIError() throws IOException { + String json = "{\"type\":\"session.handoff.aborted\"," + EVENT_FIELDS + ",\"reason\":\"error\"," + + "\"error\":{\"type\":\"server_error\",\"message\":\"Preparation failed\"," + + "\"code\":\"handoff_failed\",\"param\":null}}"; + VoiceAgentSessionHandoffAbortedEvent aborted = assertInstanceOf(VoiceAgentSessionHandoffAbortedEvent.class, + UnionTypeSerializationTestUtils.deserialize(json, RealtimeServerEvent::fromJson)); + assertEquals("Preparation failed", aborted.getError().message()); + String serialized = UnionTypeSerializationTestUtils.serialize(aborted); + assertTrue(serialized.contains("\"message\":\"Preparation failed\"")); + VoiceAgentSessionHandoffAbortedEvent result = assertInstanceOf(VoiceAgentSessionHandoffAbortedEvent.class, + UnionTypeSerializationTestUtils.deserialize(serialized, RealtimeServerEvent::fromJson)); + assertEquals(VoiceAgentHandoffAbortReason.ERROR, result.getReason()); + assertEquals("server_error", result.getError().type()); + assertEquals("handoff_failed", result.getError().code().get()); + } + + @Test + public void abortedEventAllowsAbsentAndNullError() throws IOException { + for (String error : new String[] { "", ",\"error\":null" }) { + String json = "{\"type\":\"session.handoff.aborted\"," + EVENT_FIELDS + ",\"reason\":\"user_interruption\"" + + error + "}"; + VoiceAgentSessionHandoffAbortedEvent value = assertInstanceOf(VoiceAgentSessionHandoffAbortedEvent.class, + UnionTypeSerializationTestUtils.deserialize(json, RealtimeServerEvent::fromJson)); + assertNull(value.getError()); + assertEquals(VoiceAgentHandoffAbortReason.USER_INTERRUPTION, value.getReason()); + VoiceAgentSessionHandoffAbortedEvent result + = assertInstanceOf(VoiceAgentSessionHandoffAbortedEvent.class, UnionTypeSerializationTestUtils + .deserialize(UnionTypeSerializationTestUtils.serialize(value), RealtimeServerEvent::fromJson)); + assertNull(result.getError()); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveOpenAITypesSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveOpenAITypesSerializationTests.java new file mode 100644 index 0000000000000..0fdda9ee3abce --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveOpenAITypesSerializationTests.java @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.core.util.BinaryData; +import com.openai.models.live.AudioFormat; +import com.openai.models.live.CustomVoice; +import com.openai.models.live.SessionConfig; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VoiceAgentLiveOpenAITypesSerializationTests { + @Test + public void audioRoundTripsThroughAgentDefinition() throws IOException { + CustomVoice voice = CustomVoice.builder().id("voice_123").build(); + SessionConfig.Audio audio = SessionConfig.Audio.builder() + .format(AudioFormat.AudioPcm.builder().rate(AudioFormat.AudioPcm.Rate._24000).build()) + .output(SessionConfig.Audio.Output.builder().voice(voice).build()) + .build(); + VoiceAgentLiveDefinition original = new VoiceAgentLiveDefinition("live-deployment").setAudio(audio); + + String json = UnionTypeSerializationTestUtils.serialize(original); + assertTrue(json.contains("\"audio\":{")); + assertTrue(json.contains("\"type\":\"audio/pcm\"")); + assertTrue(json.contains("\"rate\":24000")); + assertTrue(json.contains("\"voice\":{\"id\":\"voice_123\"}")); + VoiceAgentLiveDefinition result = assertInstanceOf(VoiceAgentLiveDefinition.class, + UnionTypeSerializationTestUtils.deserialize(json, AgentDefinition::fromJson)); + assertEquals(audio, result.getAudio()); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(result)); + } + + @Test + public void usageRoundTripsAsAnOpenAIModel() throws IOException { + String json = "{\"id\":\"conv_live\",\"object\":\"voice.conversation\",\"status\":\"completed\"," + + "\"created_at\":1700000000,\"completed_at\":1700000013," + + "\"metadata\":{\"source\":\"test\"},\"usage\":{\"seconds\":12.5}}"; + VoiceAgentLiveConversation value + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentLiveConversation::fromJson); + assertEquals(12.5, value.getUsage().seconds()); + + String serialized = UnionTypeSerializationTestUtils.serialize(value); + assertTrue(serialized.contains("\"usage\":{")); + assertEquals(BinaryData.fromString(json).toObject(Object.class), + BinaryData.fromString(serialized).toObject(Object.class)); + VoiceAgentLiveConversation result + = UnionTypeSerializationTestUtils.deserialize(serialized, VoiceAgentLiveConversation::fromJson); + assertEquals(value.getUsage(), result.getUsage()); + } + + @Test + public void absentAndNullOpenAIPropertiesRemainNull() throws IOException { + for (String audio : new String[] { "", ",\"audio\":null" }) { + VoiceAgentLiveDefinition value = UnionTypeSerializationTestUtils.deserialize( + "{\"kind\":\"voice\",\"sub_protocol\":\"live\",\"model\":\"live-deployment\"" + audio + "}", + VoiceAgentLiveDefinition::fromJson); + assertNull(value.getAudio()); + assertFalse(UnionTypeSerializationTestUtils.serialize(value).contains("\"audio\"")); + } + for (String usage : new String[] { "", ",\"usage\":null" }) { + VoiceAgentLiveConversation value = UnionTypeSerializationTestUtils.deserialize( + "{\"id\":\"conv_live\",\"status\":\"in_progress\",\"created_at\":1700000000" + usage + "}", + VoiceAgentLiveConversation::fromJson); + assertNull(value.getUsage()); + assertFalse(UnionTypeSerializationTestUtils.serialize(value).contains("\"usage\"")); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationSerializationTests.java new file mode 100644 index 0000000000000..a2ee6736f13e7 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLiveResponsesDelegationSerializationTests.java @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.core.util.BinaryData; +import com.openai.models.live.FunctionTool; +import com.openai.models.live.ResponsesDelegationConfig; +import com.openai.models.live.ResponsesDelegationConfig.ToolChoice.LiveToolChoiceEnum; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VoiceAgentLiveResponsesDelegationSerializationTests { + @Test + public void openAISettingsRoundTripThroughDelegation() throws IOException { + ResponsesDelegationConfig responses = ResponsesDelegationConfig.builder() + .model("responses-deployment") + .instructions("Find the weather.") + .maxOutputTokens(256L) + .parallelToolCalls(false) + .addTool(FunctionTool.builder().name("get_weather").description("Get the weather.").build()) + .toolChoice(LiveToolChoiceEnum.AUTO) + .build(); + VoiceAgentLiveResponsesDelegation original + = new VoiceAgentLiveResponsesDelegation(responses).setAcknowledgementDelay(Duration.ofMillis(400)); + + String json = UnionTypeSerializationTestUtils.serialize(original); + assertTrue(json.contains("\"responses\":{")); + assertTrue(json.contains("\"tools\":[{\"")); + assertTrue(json.contains("\"type\":\"function\"")); + assertTrue(json.contains("\"tool_choice\":\"auto\"")); + assertTrue(json.contains("\"acknowledgement_delay_ms\":400")); + VoiceAgentLiveResponsesDelegation result = assertInstanceOf(VoiceAgentLiveResponsesDelegation.class, + UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentLiveDelegation::fromJson)); + assertEquals(VoiceAgentLiveDelegationType.RESPONSES, result.getType()); + assertEquals(Duration.ofMillis(400), result.getAcknowledgementDelay()); + assertEquals(responses, result.getResponses()); + assertEquals("get_weather", result.getResponses().tools().get().get(0).asFunction().name()); + assertEquals(LiveToolChoiceEnum.AUTO, result.getResponses().toolChoice().get().asLiveToolChoiceEnum()); + } + + @Test + public void namedToolChoiceAndToolSchemaRetainWireShape() throws IOException { + String json = "{\"type\":\"responses\",\"responses\":{\"model\":\"responses-deployment\"," + + "\"instructions\":\"Use tools.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\"," + + "\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}}}}]," + + "\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"}}}"; + VoiceAgentLiveResponsesDelegation value + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentLiveResponsesDelegation::fromJson); + assertEquals("get_weather", value.getResponses().toolChoice().get().asLiveFunctionToolChoiceParam().name()); + + String serialized = UnionTypeSerializationTestUtils.serialize(value); + assertEquals(BinaryData.fromString(json).toObject(Object.class), + BinaryData.fromString(serialized).toObject(Object.class)); + } + + @Test + public void absentAndNullResponsesRemainNull() throws IOException { + for (String responses : new String[] { "", ",\"responses\":null" }) { + VoiceAgentLiveResponsesDelegation value = UnionTypeSerializationTestUtils + .deserialize("{\"type\":\"responses\"" + responses + "}", VoiceAgentLiveResponsesDelegation::fromJson); + assertNull(value.getResponses()); + VoiceAgentLiveResponsesDelegation result = UnionTypeSerializationTestUtils.deserialize( + UnionTypeSerializationTestUtils.serialize(value), VoiceAgentLiveResponsesDelegation::fromJson); + assertNull(result.getResponses()); + } + } + + @Test + public void acknowledgementDelayPreservesNullAndZeroInCustomizedSerializer() throws IOException { + for (String delay : new String[] { + "", + ",\"acknowledgement_delay_ms\":null", + ",\"acknowledgement_delay_ms\":0" }) { + VoiceAgentLiveResponsesDelegation value = UnionTypeSerializationTestUtils + .deserialize("{\"type\":\"responses\"" + delay + "}", VoiceAgentLiveResponsesDelegation::fromJson); + Duration expected = delay.endsWith(":0") ? Duration.ZERO : null; + assertEquals(expected, value.getAcknowledgementDelay()); + VoiceAgentLiveResponsesDelegation result = UnionTypeSerializationTestUtils.deserialize( + UnionTypeSerializationTestUtils.serialize(value), VoiceAgentLiveResponsesDelegation::fromJson); + assertEquals(expected, result.getAcknowledgementDelay()); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfigurationSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfigurationSerializationTests.java deleted file mode 100644 index fd84952dbef86..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentLlmGeneratedGreetingConfigurationSerializationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.models; - -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class VoiceAgentLlmGeneratedGreetingConfigurationSerializationTests { - - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - VoiceAgentLlmGeneratedGreetingConfiguration config - = new VoiceAgentLlmGeneratedGreetingConfiguration("Say hello").setToolChoice(ToolChoiceOptions.NONE); - assertEquals(ToolChoiceOptions.NONE, config.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentLlmGeneratedGreetingConfiguration optionsResult = roundTrip(config); - assertEquals(ToolChoiceOptions.NONE, optionsResult.getToolChoiceAsToolChoiceOptions()); - assertNull(optionsResult.getToolChoiceAsToolChoiceFunction()); - assertNull(optionsResult.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentLlmGeneratedGreetingConfiguration functionResult - = roundTrip(new VoiceAgentLlmGeneratedGreetingConfiguration("Say hello") - .setToolChoice(ToolChoiceFunction.builder().name("greet").build())); - assertEquals("greet", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentLlmGeneratedGreetingConfiguration mcpResult - = roundTrip(new VoiceAgentLlmGeneratedGreetingConfiguration("Say hello") - .setToolChoice(ToolChoiceMcp.builder().serverLabel("server").build())); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - } - - @Test - public void absentAndNullToolChoiceReturnsNull() throws IOException { - VoiceAgentLlmGeneratedGreetingConfiguration result - = UnionTypeSerializationTestUtils.deserialize("{\"type\":\"llm_generated\",\"prompt\":\"Say hello\"}", - VoiceAgentLlmGeneratedGreetingConfiguration::fromJson); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - - result.setToolChoice(ToolChoiceOptions.AUTO).setToolChoice((ToolChoiceOptions) null); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - } - - private VoiceAgentLlmGeneratedGreetingConfiguration roundTrip(VoiceAgentLlmGeneratedGreetingConfiguration value) - throws IOException { - String json = UnionTypeSerializationTestUtils.serialize(value); - return UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentLlmGeneratedGreetingConfiguration::fromJson); - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokensSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokensSerializationTests.java new file mode 100644 index 0000000000000..a077c196607f2 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentMaxOutputTokensSerializationTests.java @@ -0,0 +1,155 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VoiceAgentMaxOutputTokensSerializationTests { + @Test + public void countsSerializeAsJsonIntegers() throws IOException { + for (int count : new int[] { 1, 8192, Integer.MAX_VALUE }) { + VoiceAgentMaxOutputTokens limit = VoiceAgentMaxOutputTokens.of(count); + String json = UnionTypeSerializationTestUtils.serialize(limit); + assertEquals(Integer.toString(count), json); + VoiceAgentMaxOutputTokens result + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentMaxOutputTokens::fromJson); + assertEquals(count, result.asInteger()); + assertFalse(result.isMaximum()); + } + } + + @Test + public void maximumSerializesAsInfString() throws IOException { + String json = UnionTypeSerializationTestUtils.serialize(VoiceAgentMaxOutputTokens.MAXIMUM); + assertEquals("\"inf\"", json); + VoiceAgentMaxOutputTokens result + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentMaxOutputTokens::fromJson); + assertTrue(result.isMaximum()); + assertNull(result.asInteger()); + } + + @Test + public void unknownStringsArePreservedWithoutBecomingCountsOrMaximum() throws IOException { + for (String json : Arrays.asList("\"future_limit\"", "\"1024\"")) { + VoiceAgentMaxOutputTokens limit + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentMaxOutputTokens::fromJson); + assertNull(limit.asInteger()); + assertFalse(limit.isMaximum()); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(limit)); + } + } + + @Test + public void nullIsUnsetAndOtherJsonShapesAreRejected() throws IOException { + assertNull(UnionTypeSerializationTestUtils.deserialize("null", VoiceAgentMaxOutputTokens::fromJson)); + for (String json : Arrays.asList("true", "[]", "{}", "1.5", "2147483648", "-2147483649")) { + assertThrows(IllegalStateException.class, + () -> UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentMaxOutputTokens::fromJson)); + } + } + + @Test + public void voiceAgentDefinitionRoundTrips() throws IOException { + assertModelRoundTrips("{\"kind\":\"voice\"}", "max_output_tokens", VoiceAgentDefinition::fromJson, + VoiceAgentDefinition::getMaxOutputTokens, VoiceAgentDefinition::setMaxOutputTokens); + } + + @Test + public void inlineVoiceSubagentRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"specialist\",\"description\":\"Specialist\"}", "max_response_output_tokens", + InlineVoiceSubagent::fromJson, InlineVoiceSubagent::getMaxResponseOutputTokens, + InlineVoiceSubagent::setMaxResponseOutputTokens); + } + + @Test + public void responseCreateOptionsRoundTrip() throws IOException { + assertModelRoundTrips("{\"instructions\":\"Say hello\"}", "max_output_tokens", + VoiceAgentResponseCreateOptions::fromJson, VoiceAgentResponseCreateOptions::getMaxOutputTokens, + VoiceAgentResponseCreateOptions::setMaxOutputTokens); + } + + @Test + public void sessionUpdateConfigurationRoundTrips() throws IOException { + assertModelRoundTrips("{\"type\":\"realtime\"}", "max_output_tokens", + VoiceAgentSessionUpdateConfiguration::fromJson, VoiceAgentSessionUpdateConfiguration::getMaxOutputTokens, + VoiceAgentSessionUpdateConfiguration::setMaxOutputTokens); + } + + @Test + public void sessionResponseConfigurationRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"s\",\"model\":\"m\"}", "max_output_tokens", + VoiceAgentSessionResponseConfiguration::fromJson, + VoiceAgentSessionResponseConfiguration::getMaxOutputTokens, null); + } + + @Test + public void realtimeResponseRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"r\"}", "max_output_tokens", VoiceAgentRealtimeResponse::fromJson, + VoiceAgentRealtimeResponse::getMaxOutputTokens, null); + } + + @Test + public void persistedResponseRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"r\",\"conversation_id\":\"c\"}", "max_output_tokens", VoiceResponse::fromJson, + VoiceResponse::getMaxOutputTokens, null); + } + + private static > void assertModelRoundTrips(String baseJson, String property, + UnionTypeSerializationTestUtils.Deserializer deserializer, Function getter, + BiConsumer setter) throws IOException { + T unset = UnionTypeSerializationTestUtils.deserialize(baseJson, deserializer); + assertNull(getter.apply(unset)); + assertFalse(properties(unset).containsKey(property)); + String prefix = baseJson.substring(0, baseJson.length() - 1) + ",\"" + property + "\":"; + assertNull(getter.apply(UnionTypeSerializationTestUtils.deserialize(prefix + "null}", deserializer))); + + for (String limitJson : Arrays.asList("1024", "\"inf\"", "\"future_limit\"", "\"1024\"")) { + VoiceAgentMaxOutputTokens limit + = UnionTypeSerializationTestUtils.deserialize(limitJson, VoiceAgentMaxOutputTokens::fromJson); + T model = UnionTypeSerializationTestUtils.deserialize(prefix + limitJson + "}", deserializer); + assertLimitEquals(limit, getter.apply(model)); + if (setter != null) { + setter.accept(model, null); + assertNull(getter.apply(model)); + assertFalse(properties(model).containsKey(property)); + setter.accept(model, limit); + assertLimitEquals(limit, getter.apply(model)); + } + assertEquals(UnionTypeSerializationTestUtils.deserialize(limitJson, JsonReader::readUntyped), + properties(model).get(property)); + T result = UnionTypeSerializationTestUtils.deserialize(UnionTypeSerializationTestUtils.serialize(model), + deserializer); + assertLimitEquals(limit, getter.apply(result)); + } + } + + private static void assertLimitEquals(VoiceAgentMaxOutputTokens expected, VoiceAgentMaxOutputTokens actual) + throws IOException { + assertNotNull(actual); + assertEquals(expected.asInteger(), actual.asInteger()); + assertEquals(expected.isMaximum(), actual.isMaximum()); + assertEquals(UnionTypeSerializationTestUtils.serialize(expected), + UnionTypeSerializationTestUtils.serialize(actual)); + } + + private static Map properties(JsonSerializable model) throws IOException { + return UnionTypeSerializationTestUtils.deserialize(UnionTypeSerializationTestUtils.serialize(model), + reader -> reader.readMap(JsonReader::readUntyped)); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponseSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponseSerializationTests.java index 31492ab706253..5c5d1f5c53a02 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponseSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentRealtimeResponseSerializationTests.java @@ -14,25 +14,6 @@ public class VoiceAgentRealtimeResponseSerializationTests { - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - VoiceAgentRealtimeResponse longResult = roundTrip("{\"max_output_tokens\":4096}"); - assertEquals(4096L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceAgentRealtimeResponse stringResult = roundTrip("{\"max_output_tokens\":\"inf\"}"); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void absentMaxOutputTokensReturnsNull() throws IOException { - VoiceAgentRealtimeResponse response - = UnionTypeSerializationTestUtils.deserialize("{}", VoiceAgentRealtimeResponse::fromJson); - assertNull(response.getMaxOutputTokensAsLong()); - assertNull(response.getMaxOutputTokensAsString()); - } - @Test public void objectTypeRoundTripsUnderObjectWireName() throws IOException { VoiceAgentRealtimeResponse response = UnionTypeSerializationTestUtils @@ -52,11 +33,4 @@ public void objectTypeRoundTripsUnderObjectWireName() throws IOException { .getObjectType()); } - private VoiceAgentRealtimeResponse roundTrip(String json) throws IOException { - VoiceAgentRealtimeResponse value - = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentRealtimeResponse::fromJson); - String serialized = UnionTypeSerializationTestUtils.serialize(value); - assertTrue(serialized.contains("\"max_output_tokens\"")); - return UnionTypeSerializationTestUtils.deserialize(serialized, VoiceAgentRealtimeResponse::fromJson); - } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptionsSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptionsSerializationTests.java index b5a30035a305e..ec0e65da84cc7 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptionsSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentResponseCreateOptionsSerializationTests.java @@ -6,9 +6,6 @@ import com.openai.models.realtime.RealtimeFunctionTool; import com.openai.models.realtime.RealtimeResponseCreateMcpTool; import com.openai.models.realtime.RealtimeResponseCreateParams; -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -21,19 +18,6 @@ public class VoiceAgentResponseCreateOptionsSerializationTests { - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - VoiceAgentResponseCreateOptions longResult - = roundTrip(new VoiceAgentResponseCreateOptions().setMaxOutputTokens(4096L)); - assertEquals(4096L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceAgentResponseCreateOptions stringResult - = roundTrip(new VoiceAgentResponseCreateOptions().setMaxOutputTokens("inf")); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - @Test public void toolsVariantsRoundTrip() throws IOException { RealtimeFunctionTool function @@ -68,45 +52,14 @@ public void deserializesToolsVariants() throws IOException { assertTrue(tools.get(1).isRealtimeResponseCreateMcp()); } - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - VoiceAgentResponseCreateOptions params - = new VoiceAgentResponseCreateOptions().setToolChoice(ToolChoiceOptions.REQUIRED); - assertEquals(ToolChoiceOptions.REQUIRED, params.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentResponseCreateOptions optionsResult = roundTrip(params); - assertEquals(ToolChoiceOptions.REQUIRED, optionsResult.getToolChoiceAsToolChoiceOptions()); - assertNull(optionsResult.getToolChoiceAsToolChoiceFunction()); - assertNull(optionsResult.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentResponseCreateOptions functionResult = roundTrip( - new VoiceAgentResponseCreateOptions().setToolChoice(ToolChoiceFunction.builder().name("lookup").build())); - assertEquals("lookup", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentResponseCreateOptions mcpResult = roundTrip( - new VoiceAgentResponseCreateOptions().setToolChoice(ToolChoiceMcp.builder().serverLabel("server").build())); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - } - @Test public void absentAndNullValuesReturnNull() throws IOException { VoiceAgentResponseCreateOptions result = UnionTypeSerializationTestUtils.deserialize("{}", VoiceAgentResponseCreateOptions::fromJson); - assertNull(result.getMaxOutputTokensAsLong()); - assertNull(result.getMaxOutputTokensAsString()); assertNull(result.getToolsAsOpenAITools()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - result.setMaxOutputTokens("inf").setMaxOutputTokens((String) null); result.setToolsAsOpenAITools(null); - result.setToolChoice(ToolChoiceOptions.AUTO).setToolChoice((ToolChoiceOptions) null); - assertNull(result.getMaxOutputTokensAsString()); assertNull(result.getToolsAsOpenAITools()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); } private VoiceAgentResponseCreateOptions roundTrip(VoiceAgentResponseCreateOptions value) throws IOException { diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfigurationSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfigurationSerializationTests.java deleted file mode 100644 index 92241bd8e3dcb..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionResponseConfigurationSerializationTests.java +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.models; - -import com.openai.models.responses.ToolChoiceOptions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class VoiceAgentSessionResponseConfigurationSerializationTests { - - @Test - public void longAndStringTokenLimitsRoundTrip() throws IOException { - VoiceAgentSessionResponseConfiguration longResult - = roundTrip("{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\"," - + "\"model\":\"m\",\"max_output_tokens\":2048}"); - assertEquals(2048L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceAgentSessionResponseConfiguration stringResult - = roundTrip("{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\"," - + "\"model\":\"m\",\"max_output_tokens\":\"inf\"}"); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - VoiceAgentSessionResponseConfiguration stringResult - = roundTrip("{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\"," - + "\"model\":\"m\",\"tool_choice\":\"auto\"}"); - assertEquals(ToolChoiceOptions.AUTO, stringResult.getToolChoiceAsToolChoiceOptions()); - assertNull(stringResult.getToolChoiceAsToolChoiceFunction()); - assertNull(stringResult.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentSessionResponseConfiguration functionResult - = roundTrip("{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\"," - + "\"model\":\"m\",\"tool_choice\":{\"type\":\"function\",\"name\":\"lookup\"}}"); - assertEquals("lookup", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentSessionResponseConfiguration mcpResult - = roundTrip("{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\"," - + "\"model\":\"m\",\"tool_choice\":{\"type\":\"mcp\",\"server_label\":\"server\"}}"); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - } - - @Test - public void absentValuesReturnNull() throws IOException { - VoiceAgentSessionResponseConfiguration result = UnionTypeSerializationTestUtils.deserialize( - "{\"type\":\"realtime\",\"object\":\"realtime.session\",\"id\":\"s\",\"model\":\"m\"}", - VoiceAgentSessionResponseConfiguration::fromJson); - assertNull(result.getMaxOutputTokensAsLong()); - assertNull(result.getMaxOutputTokensAsString()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - } - - private VoiceAgentSessionResponseConfiguration roundTrip(String json) throws IOException { - VoiceAgentSessionResponseConfiguration value - = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentSessionResponseConfiguration::fromJson); - String serialized = UnionTypeSerializationTestUtils.serialize(value); - assertTrue(serialized.contains("\"id\":\"s\"")); - return UnionTypeSerializationTestUtils.deserialize(serialized, - VoiceAgentSessionResponseConfiguration::fromJson); - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfigurationSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfigurationSerializationTests.java deleted file mode 100644 index dfbf5984eb835..0000000000000 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentSessionUpdateConfigurationSerializationTests.java +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.agents.models; - -import com.openai.models.responses.ToolChoiceFunction; -import com.openai.models.responses.ToolChoiceMcp; -import com.openai.models.responses.ToolChoiceOptions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class VoiceAgentSessionUpdateConfigurationSerializationTests { - - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - VoiceAgentSessionUpdateConfiguration longResult - = roundTrip(new VoiceAgentSessionUpdateConfiguration().setMaxOutputTokens(1024L)); - assertEquals(1024L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceAgentSessionUpdateConfiguration stringResult - = roundTrip(new VoiceAgentSessionUpdateConfiguration().setMaxOutputTokens("inf")); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void toolChoiceVariantsRoundTrip() throws IOException { - VoiceAgentSessionUpdateConfiguration config - = new VoiceAgentSessionUpdateConfiguration().setToolChoice(ToolChoiceOptions.AUTO); - assertEquals(ToolChoiceOptions.AUTO, config.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentSessionUpdateConfiguration optionsResult = roundTrip(config); - assertEquals(ToolChoiceOptions.AUTO, optionsResult.getToolChoiceAsToolChoiceOptions()); - assertNull(optionsResult.getToolChoiceAsToolChoiceFunction()); - assertNull(optionsResult.getToolChoiceAsToolChoiceMcp()); - - VoiceAgentSessionUpdateConfiguration functionResult = roundTrip(new VoiceAgentSessionUpdateConfiguration() - .setToolChoice(ToolChoiceFunction.builder().name("lookup").build())); - assertEquals("lookup", functionResult.getToolChoiceAsToolChoiceFunction().name()); - assertNull(functionResult.getToolChoiceAsToolChoiceOptions()); - - VoiceAgentSessionUpdateConfiguration mcpResult = roundTrip(new VoiceAgentSessionUpdateConfiguration() - .setToolChoice(ToolChoiceMcp.builder().serverLabel("server").build())); - assertEquals("server", mcpResult.getToolChoiceAsToolChoiceMcp().serverLabel()); - assertNull(mcpResult.getToolChoiceAsToolChoiceOptions()); - } - - @Test - public void absentAndNullValuesReturnNull() throws IOException { - VoiceAgentSessionUpdateConfiguration result = UnionTypeSerializationTestUtils - .deserialize("{\"type\":\"realtime\"}", VoiceAgentSessionUpdateConfiguration::fromJson); - assertNull(result.getMaxOutputTokensAsLong()); - assertNull(result.getMaxOutputTokensAsString()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - assertNull(result.getToolChoiceAsToolChoiceFunction()); - assertNull(result.getToolChoiceAsToolChoiceMcp()); - - result.setMaxOutputTokens("inf").setMaxOutputTokens((String) null); - result.setToolChoice(ToolChoiceOptions.AUTO).setToolChoice((ToolChoiceOptions) null); - assertNull(result.getMaxOutputTokensAsString()); - assertNull(result.getToolChoiceAsToolChoiceOptions()); - } - - private VoiceAgentSessionUpdateConfiguration roundTrip(VoiceAgentSessionUpdateConfiguration value) - throws IOException { - String json = UnionTypeSerializationTestUtils.serialize(value); - return UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentSessionUpdateConfiguration::fromJson); - } -} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentToolChoiceSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentToolChoiceSerializationTests.java new file mode 100644 index 0000000000000..95e395850e3cc --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceAgentToolChoiceSerializationTests.java @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.models; + +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.openai.models.responses.ToolChoiceFunction; +import com.openai.models.responses.ToolChoiceMcp; +import com.openai.models.responses.ToolChoiceOptions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class VoiceAgentToolChoiceSerializationTests { + @Test + public void voiceAgentDefinitionRoundTrips() throws IOException { + assertModelRoundTrips("{\"kind\":\"voice\"}", VoiceAgentDefinition::fromJson, + VoiceAgentDefinition::getToolChoice, VoiceAgentDefinition::setToolChoice); + } + + @Test + public void inlineVoiceSubagentRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"specialist\",\"description\":\"Specialist\"}", InlineVoiceSubagent::fromJson, + InlineVoiceSubagent::getToolChoice, InlineVoiceSubagent::setToolChoice); + } + + @Test + public void greetingConfigurationRoundTrips() throws IOException { + assertModelRoundTrips("{\"type\":\"llm_generated\",\"prompt\":\"Say hello\"}", + VoiceAgentLlmGeneratedGreetingConfiguration::fromJson, + VoiceAgentLlmGeneratedGreetingConfiguration::getToolChoice, + VoiceAgentLlmGeneratedGreetingConfiguration::setToolChoice); + } + + @Test + public void responseCreateOptionsRoundTrip() throws IOException { + assertModelRoundTrips("{\"instructions\":\"Say hello\"}", VoiceAgentResponseCreateOptions::fromJson, + VoiceAgentResponseCreateOptions::getToolChoice, VoiceAgentResponseCreateOptions::setToolChoice); + } + + @Test + public void sessionUpdateConfigurationRoundTrips() throws IOException { + assertModelRoundTrips("{\"type\":\"realtime\"}", VoiceAgentSessionUpdateConfiguration::fromJson, + VoiceAgentSessionUpdateConfiguration::getToolChoice, VoiceAgentSessionUpdateConfiguration::setToolChoice); + } + + @Test + public void sessionResponseConfigurationRoundTrips() throws IOException { + assertModelRoundTrips("{\"id\":\"s\",\"model\":\"m\"}", VoiceAgentSessionResponseConfiguration::fromJson, + VoiceAgentSessionResponseConfiguration::getToolChoice, null); + } + + @Test + public void variantsSerializeAsUnwrappedValuesAndExposeOnlySelectedValue() throws IOException { + for (ToolChoiceOptions mode : Arrays.asList(ToolChoiceOptions.NONE, ToolChoiceOptions.AUTO, + ToolChoiceOptions.REQUIRED)) { + VoiceAgentToolChoice choice = VoiceAgentToolChoice.ofMode(mode); + assertEquals("\"" + mode.asString() + "\"", UnionTypeSerializationTestUtils.serialize(choice)); + VoiceAgentToolChoice result = roundTrip(choice); + assertEquals(mode, result.getMode()); + assertNull(result.getFunction()); + assertNull(result.getMcp()); + } + + VoiceAgentToolChoice function + = VoiceAgentToolChoice.ofFunction(ToolChoiceFunction.builder().name("lookup").build()); + assertEquals(UnionTypeSerializationTestUtils.deserialize("{\"type\":\"function\",\"name\":\"lookup\"}", + JsonReader::readUntyped), properties(function)); + VoiceAgentToolChoice functionResult = roundTrip(function); + assertEquals("lookup", functionResult.getFunction().name()); + assertNull(functionResult.getMode()); + assertNull(functionResult.getMcp()); + + VoiceAgentToolChoice mcp + = VoiceAgentToolChoice.ofMcp(ToolChoiceMcp.builder().serverLabel("server").name("search").build()); + VoiceAgentToolChoice mcpResult = roundTrip(mcp); + assertEquals("server", mcpResult.getMcp().serverLabel()); + assertNull(mcpResult.getMode()); + assertNull(mcpResult.getFunction()); + } + + @Test + public void nullChoiceIsDistinctFromFactoriesWithNullArguments() throws IOException { + assertNull(UnionTypeSerializationTestUtils.deserialize("null", VoiceAgentToolChoice::fromJson)); + assertThrows(NullPointerException.class, () -> VoiceAgentToolChoice.ofMode(null)); + assertThrows(NullPointerException.class, () -> VoiceAgentToolChoice.ofFunction(null)); + assertThrows(NullPointerException.class, () -> VoiceAgentToolChoice.ofMcp(null)); + } + + @Test + public void unknownValuesArePreservedWithoutMisclassifyingObjectVariants() throws IOException { + VoiceAgentToolChoice futureMode = VoiceAgentToolChoice.ofMode(ToolChoiceOptions.of("future_mode")); + assertEquals("future_mode", roundTrip(futureMode).getMode().asString()); + String json = "{\"type\":\"future_tool\",\"setting\":true}"; + VoiceAgentToolChoice futureObject + = UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentToolChoice::fromJson); + assertEquals(json, UnionTypeSerializationTestUtils.serialize(futureObject)); + assertNull(futureObject.getMode()); + assertNull(futureObject.getFunction()); + assertNull(futureObject.getMcp()); + } + + @Test + public void rejectsJsonValuesOutsideTheUnionShape() { + for (String json : Arrays.asList("42", "true", "[]")) { + assertThrows(IllegalStateException.class, + () -> UnionTypeSerializationTestUtils.deserialize(json, VoiceAgentToolChoice::fromJson)); + } + } + + private static > void assertModelRoundTrips(String baseJson, + UnionTypeSerializationTestUtils.Deserializer deserializer, Function getter, + BiConsumer setter) throws IOException { + assertNull(getter.apply(UnionTypeSerializationTestUtils.deserialize(baseJson, deserializer))); + String prefix = baseJson.substring(0, baseJson.length() - 1) + ",\"tool_choice\":"; + assertNull(getter.apply(UnionTypeSerializationTestUtils.deserialize(prefix + "null}", deserializer))); + for (VoiceAgentToolChoice choice : Arrays.asList(VoiceAgentToolChoice.ofMode(ToolChoiceOptions.NONE), + VoiceAgentToolChoice.ofMode(ToolChoiceOptions.AUTO), + VoiceAgentToolChoice.ofMode(ToolChoiceOptions.REQUIRED), + VoiceAgentToolChoice.ofFunction(ToolChoiceFunction.builder().name("lookup").build()), + VoiceAgentToolChoice.ofMcp(ToolChoiceMcp.builder().serverLabel("server").name("search").build()))) { + String choiceJson = UnionTypeSerializationTestUtils.serialize(choice); + T model = UnionTypeSerializationTestUtils.deserialize(prefix + choiceJson + "}", deserializer); + assertChoiceEquals(choice, getter.apply(model)); + if (setter != null) { + setter.accept(model, null); + assertNull(getter.apply(model)); + assertFalse(properties(model).containsKey("tool_choice")); + setter.accept(model, choice); + } + assertEquals(UnionTypeSerializationTestUtils.deserialize(choiceJson, JsonReader::readUntyped), + properties(model).get("tool_choice")); + T result = UnionTypeSerializationTestUtils.deserialize(UnionTypeSerializationTestUtils.serialize(model), + deserializer); + assertChoiceEquals(choice, getter.apply(result)); + } + } + + private static Map properties(JsonSerializable model) throws IOException { + return UnionTypeSerializationTestUtils.deserialize(UnionTypeSerializationTestUtils.serialize(model), + reader -> reader.readMap(JsonReader::readUntyped)); + } + + private static void assertChoiceEquals(VoiceAgentToolChoice expected, VoiceAgentToolChoice actual) { + assertNotNull(actual); + assertEquals(expected.getMode(), actual.getMode()); + assertEquals(expected.getFunction(), actual.getFunction()); + assertEquals(expected.getMcp(), actual.getMcp()); + } + + private static VoiceAgentToolChoice roundTrip(VoiceAgentToolChoice choice) throws IOException { + return UnionTypeSerializationTestUtils.deserialize(UnionTypeSerializationTestUtils.serialize(choice), + VoiceAgentToolChoice::fromJson); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceResponseSerializationTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceResponseSerializationTests.java index 37a4960ae79d7..178e6863ad2f3 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceResponseSerializationTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/models/VoiceResponseSerializationTests.java @@ -14,25 +14,6 @@ public class VoiceResponseSerializationTests { - @Test - public void maxOutputTokensVariantsRoundTrip() throws IOException { - VoiceResponse longResult = roundTrip("{\"max_output_tokens\":4096}"); - assertEquals(4096L, longResult.getMaxOutputTokensAsLong()); - assertNull(longResult.getMaxOutputTokensAsString()); - - VoiceResponse stringResult = roundTrip("{\"max_output_tokens\":\"inf\"}"); - assertEquals("inf", stringResult.getMaxOutputTokensAsString()); - assertNull(stringResult.getMaxOutputTokensAsLong()); - } - - @Test - public void absentMaxOutputTokensReturnsNull() throws IOException { - VoiceResponse response = UnionTypeSerializationTestUtils - .deserialize("{\"id\":\"response\",\"conversation_id\":\"conversation\"}", VoiceResponse::fromJson); - assertNull(response.getMaxOutputTokensAsLong()); - assertNull(response.getMaxOutputTokensAsString()); - } - @Test public void objectTypeRoundTripsUnderObjectWireName() throws IOException { VoiceResponse response = UnionTypeSerializationTestUtils.deserialize( @@ -52,10 +33,4 @@ public void objectTypeRoundTripsUnderObjectWireName() throws IOException { UnionTypeSerializationTestUtils.deserialize("{\"object\":null}", VoiceResponse::fromJson).getObjectType()); } - private VoiceResponse roundTrip(String json) throws IOException { - VoiceResponse value = UnionTypeSerializationTestUtils.deserialize(json, VoiceResponse::fromJson); - String serialized = UnionTypeSerializationTestUtils.serialize(value); - assertTrue(serialized.contains("\"max_output_tokens\"")); - return UnionTypeSerializationTestUtils.deserialize(serialized, VoiceResponse::fromJson); - } } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveConversationSamplesTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveConversationSamplesTests.java new file mode 100644 index 0000000000000..d49e1f4b292ac --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveConversationSamplesTests.java @@ -0,0 +1,325 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.HttpHeaders; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.HttpResponse; +import com.azure.core.http.policy.ExponentialBackoffOptions; +import com.azure.core.http.policy.RetryOptions; +import com.azure.core.test.http.MockHttpResponse; +import com.azure.core.test.utils.MockTokenCredential; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.azure.core.util.Context; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.publisher.Mono; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GptLiveConversationSamplesTests { + private static final String ROOT = "/agents/live-agent/endpoint/protocols/voice/live/conversations"; + private static final String PATH = ROOT + "/conversation-1"; + private static final String CONVERSATION + = "{\"id\":\"conversation-1\",\"status\":\"completed\",\"created_at\":1700000000,\"usage\":{\"seconds\":2.5}}"; + private static final String INPUT = "{\"id\":\"input-1\",\"type\":\"input\",\"transcription\":\"Hello\"}"; + private static final String OUTPUT = "{\"id\":\"output-1\",\"type\":\"output\",\"transcription\":\"Hi\"}"; + private static final String DELEGATION + = "{\"id\":\"delegation-1\",\"type\":\"delegation\",\"target\":\"responses\",\"response_id\":\"response-1\"}"; + private static final byte[] WAV = { 82, 73, 70, 70, 0, 0, 0, 0, 87, 65, 86, 69 }; + private static final Duration TIMEOUT = Duration.ofSeconds(10); + + @TempDir + Path directory; + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void readsCursorPagesAndFetchesSpeechAndDelegationDetails(boolean async) { + ScriptedTransport transport = new ScriptedTransport(async); + transport.json(ROOT, null, 200, page(CONVERSATION)); + transport.json(ROOT, "conversation-1", 200, page()); + transport.json(PATH, null, 200, CONVERSATION); + transport.json(PATH + "/items", null, 200, page(INPUT)); + transport.json(PATH + "/items/input-1", null, 200, INPUT); + transport.json(PATH + "/items", "input-1", 200, page(OUTPUT, DELEGATION)); + transport.json(PATH + "/items/output-1", null, 200, OUTPUT); + transport.json(PATH + "/items/delegation-1", null, 200, DELEGATION); + transport.json(PATH + "/items", "delegation-1", 200, page()); + readConversation(builder(transport), async); + transport.assertConsumed(); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void missingConversationPropagates(boolean async) { + ScriptedTransport transport = new ScriptedTransport(async); + transport.json(ROOT, null, 200, page()); + transport.json(PATH, null, 404, error("not_found")); + HttpResponseException failure + = assertThrows(HttpResponseException.class, () -> readConversation(builder(transport), async)); + assertEquals(404, failure.getResponse().getStatusCode()); + transport.assertConsumed(); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void repeatedCursorFailsRatherThanLooping(boolean async) { + ScriptedTransport transport = new ScriptedTransport(async); + transport.json(ROOT, null, 200, page(CONVERSATION)); + transport.json(ROOT, "conversation-1", 200, page(CONVERSATION)); + assertThrows(IllegalStateException.class, () -> readConversation(builder(transport), async)); + transport.assertConsumed(); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void downloadsMergedAndItemBytesWithoutOverwritingFiles(boolean async) throws IOException { + Path existing = directory.resolve("existing.wav"); + byte[] original = { 1, 2, 3 }; + Files.write(existing, original); + ScriptedTransport transport = audioTransport(async, false); + downloadAudio(builder(transport), async, "input-1"); + transport.assertConsumed(); + assertEquals(3, files().size()); + assertArrayEquals(original, Files.readAllBytes(existing)); + for (Path file : files()) { + if (!file.equals(existing)) { + assertArrayEquals(WAV, Files.readAllBytes(file)); + assertTrue(file.getFileName().toString().endsWith(".wav")); + } + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void byosMetadataDoesNotCallFoundryContentEndpoints(boolean async) throws IOException { + ScriptedTransport transport = audioTransport(async, true); + downloadAudio(builder(transport), async, "input-1"); + transport.assertConsumed(); + assertTrue(files().isEmpty()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void optionalItemCanBeOmitted(boolean async) throws IOException { + ScriptedTransport transport = new ScriptedTransport(async); + transport.json(PATH + "/audio", null, 200, recording(false)); + transport.audio(PATH + "/audio/content"); + downloadAudio(builder(transport), async, null); + transport.assertConsumed(); + assertEquals(1, files().size()); + } + + @ParameterizedTest + @MethodSource("audioFailures") + public void audioErrorsPreserveStatusAndRetryAfter(boolean async, int status, boolean content) throws IOException { + ScriptedTransport transport = new ScriptedTransport(async); + if (content) { + transport.json(PATH + "/audio", null, 200, recording(false)); + } + transport.json(PATH + (content ? "/audio/content" : "/audio"), null, status, error("recording_not_ready")); + HttpResponseException failure + = assertThrows(HttpResponseException.class, () -> downloadAudio(builder(transport), async, null)); + assertEquals(status, failure.getResponse().getStatusCode()); + assertEquals("3", failure.getResponse().getHeaderValue("Retry-After")); + assertTrue(files().isEmpty()); + transport.assertConsumed(); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void blankItemFailsBeforeNetworkAccess(boolean async) { + ScriptedTransport transport = new ScriptedTransport(async); + assertThrows(IllegalArgumentException.class, () -> downloadAudio(builder(transport), async, " ")); + transport.assertConsumed(); + } + + @Test + public void failedFileWriteRemovesPartialOutput() throws IOException { + InputStream failingStream = new InputStream() { + @Override + public int read() throws IOException { + throw new IOException("Simulated read failure"); + } + }; + assertThrows(IOException.class, () -> GptLiveReadConversationAudioSample + .saveAudio(BinaryData.fromStream(failingStream), directory, "failure-")); + assertTrue(files().isEmpty()); + } + + @Test + public void configurationDirectoryAndCursorValidation() { + assertThrows(IllegalArgumentException.class, + () -> GptLiveSampleUtils.requireSetting(Configuration.NONE, "FOUNDRY_PROJECT_ENDPOINT")); + assertThrows(IllegalArgumentException.class, + () -> GptLiveReadConversationAudioSample.outputDirectory(new String[0])); + assertThrows(IllegalArgumentException.class, () -> GptLiveReadConversationAudioSample + .outputDirectory(new String[] { directory.resolve("missing").toString() })); + assertEquals(directory, + GptLiveReadConversationAudioSample.outputDirectory(new String[] { directory.toString() })); + assertThrows(IllegalStateException.class, () -> GptLiveReadConversationSample.nextCursor(null, null)); + assertThrows(IllegalStateException.class, () -> GptLiveReadConversationSample.nextCursor("", null)); + } + + private static Stream audioFailures() { + return Stream.of(false, true) + .flatMap(async -> Stream.of(403, 404, 409) + .flatMap(status -> Stream.of(false, true).map(content -> Arguments.of(async, status, content)))); + } + + private static void readConversation(AgentsClientBuilder builder, boolean async) { + if (async) { + GptLiveReadConversationAsyncSample + .readConversation(builder.beta().buildBetaVoiceAgentsLiveConversationsAsyncClient(), "live-agent", + "conversation-1") + .block(TIMEOUT); + } else { + GptLiveReadConversationSample.readConversation(builder.beta().buildBetaVoiceAgentsLiveConversationsClient(), + "live-agent", "conversation-1"); + } + } + + private void downloadAudio(AgentsClientBuilder builder, boolean async, String itemId) throws IOException { + if (async) { + GptLiveReadConversationAudioAsyncSample + .downloadAudio(builder.beta().buildBetaVoiceAgentsLiveConversationsAsyncClient(), "live-agent", + "conversation-1", itemId, directory) + .block(TIMEOUT); + } else { + GptLiveReadConversationAudioSample.downloadAudio( + builder.beta().buildBetaVoiceAgentsLiveConversationsClient(), "live-agent", "conversation-1", itemId, + directory); + } + } + + private static ScriptedTransport audioTransport(boolean async, boolean byos) { + ScriptedTransport transport = new ScriptedTransport(async); + transport.json(PATH + "/audio", null, 200, recording(byos)); + if (!byos) { + transport.audio(PATH + "/audio/content"); + } + transport.json(PATH + "/items/input-1/audio", null, 200, + "{\"conversation_id\":\"conversation-1\",\"item_id\":\"input-1\",\"format\":\"wav\",\"sample_rate\":24000" + + (byos ? ",\"blob_uri\":\"https://storage.example/item.wav\"" : "") + "}"); + if (!byos) { + transport.audio(PATH + "/items/input-1/audio/content"); + } + return transport; + } + + private List files() throws IOException { + try (Stream paths = Files.list(directory)) { + return paths.collect(Collectors.toList()); + } + } + + private static String recording(boolean byos) { + return "{\"conversation_id\":\"conversation-1\",\"format\":\"wav\",\"sample_rate\":24000,\"channels\":2," + + "\"channel_layout\":{\"left\":\"user\",\"right\":\"assistant\"},\"duration_ms\":2000" + + (byos ? ",\"blob_uri\":\"https://storage.example/call.wav\"" : "") + "}"; + } + + private static String page(String... entries) { + return "{\"data\":[" + String.join(",", entries) + "]}"; + } + + private static String error(String code) { + return "{\"error\":{\"code\":\"" + code + "\",\"message\":\"Sample service error\"}}"; + } + + private static AgentsClientBuilder builder(HttpClient transport) { + return new AgentsClientBuilder().endpoint("https://localhost") + .credential(new MockTokenCredential()) + .configuration(Configuration.NONE) + .addPolicy(GptLiveReadConversationSample.previewHeaders()) + .httpClient(transport) + .retryOptions(new RetryOptions(new ExponentialBackoffOptions().setMaxRetries(0))); + } + + private static final class ScriptedTransport implements HttpClient { + private final Deque> requests = new ArrayDeque<>(); + private final boolean async; + + ScriptedTransport(boolean async) { + this.async = async; + } + + void json(String path, String after, int status, String body) { + expect(path, after, status, "application/json", BinaryData.fromString(body).toBytes()); + } + + void audio(String path) { + expect(path, null, 200, "audio/wav", WAV); + } + + private void expect(String path, String after, int status, String contentType, byte[] body) { + requests.add(request -> { + assertEquals(HttpMethod.GET, request.getHttpMethod(), "Samples must not modify or delete data"); + assertEquals(path, request.getUrl().getPath()); + assertEquals("VoiceAgents=V1Preview", request.getHeaders().getValue("Foundry-Features")); + String query = request.getUrl().getQuery(); + assertTrue(query.contains("api-version=")); + if (path.equals(ROOT) || path.endsWith("/items")) { + assertTrue(query.contains("limit=100")); + assertTrue(query.contains("order=asc")); + } + if (after != null) { + assertTrue(query.contains("after=" + after), "Missing cursor: " + query); + } else { + assertFalse(query.contains("after="), "Unexpected cursor: " + query); + } + return new MockHttpResponse(request, status, + new HttpHeaders().set(HttpHeaderName.CONTENT_TYPE, contentType) + .set(HttpHeaderName.fromString("Retry-After"), "3"), + body); + }); + } + + @Override + public Mono send(HttpRequest request) { + assertTrue(async, "Synchronous examples must use synchronous HTTP"); + return Mono.fromSupplier(() -> respond(request)); + } + + @Override + public HttpResponse sendSync(HttpRequest request, Context context) { + assertFalse(async, "Asynchronous examples must use asynchronous HTTP"); + return respond(request); + } + + private HttpResponse respond(HttpRequest request) { + assertFalse(requests.isEmpty(), "Unexpected request: " + request.getUrl()); + return requests.removeFirst().apply(request); + } + + void assertConsumed() { + assertTrue(requests.isEmpty(), "Not all expected requests were made"); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveSamplesTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveSamplesTests.java new file mode 100644 index 0000000000000..5b4296fcaefce --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/GptLiveSamplesTests.java @@ -0,0 +1,1394 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionClient; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.core.credential.AccessToken; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ServerEvent; +import com.openai.models.responses.ResponseFunctionToolCall; +import java.io.ByteArrayOutputStream; +import java.io.FilterReader; +import java.io.InputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.Reader; +import java.io.PipedReader; +import java.io.PipedWriter; +import java.io.StringReader; +import java.lang.reflect.Proxy; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.stream.Stream; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.parallel.Isolated; +import org.junit.jupiter.api.parallel.ResourceLock; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; +import reactor.core.scheduler.Schedulers; +import reactor.netty.DisposableServer; +import reactor.test.StepVerifier; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Isolated("Virtual-time tests replace the global Reactor schedulers") +@ResourceLock("voice-agent-websocket-tls") +@Timeout(20) +public class GptLiveSamplesTests { + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private static final String STARTED = "{\"type\":\"session.started\",\"session\":{\"id\":\"live-1\"}}"; + private static final String CLOSED = "{\"type\":\"session.closed\",\"reason\":\"close_requested\"}"; + private static final String COMPLETED = "{\"type\":\"response.event\",\"delegation_id\":\"del-1\",\"event\":" + + "{\"type\":\"response.completed\",\"response\":{\"id\":\"resp-1\",\"output\":[]}}}"; + private static final String MODERATED = "{\"type\":\"error\",\"event_id\":\"moderated-1\"," + + "\"error\":{\"type\":\"content_filter\",\"code\":\"content_filter\"," + + "\"message\":\"The generation was stopped due to moderation.\"}}"; + private final List> commands = new CopyOnWriteArrayList<>(); + private DisposableServer server; + + @ParameterizedTest + @ValueSource(strings = { "text", "text-async", "interactive", "interactive-async", "audio-async", "tools" }) + public void agentNamesStayBelowServiceLimit(String scenario) { + String prefix = "gpt-live-" + scenario + "-"; + String name = GptLiveSampleUtils.createAgentName(scenario); + assertTrue(name.startsWith(prefix)); + assertTrue(name.length() <= 63, "Sample agent names must fit the 63-character limit"); + assertTrue(name.matches("[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]")); + assertEquals(36, name.substring(prefix.length()).length()); + assertEquals(4, UUID.fromString(name.substring(prefix.length())).version()); + assertFalse(name.equals(GptLiveSampleUtils.createAgentName(scenario))); + } + + @Test + @ResourceLock("java.lang.System.out") + public void audioTranscriptsLabelSpeakersWithoutPrintingBackendText() { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + GptLiveSampleUtils.AudioTranscriptPrinter printer = new GptLiveSampleUtils.AudioTranscriptPrinter(); + printer.print(typedEvent(BinaryData.fromString(STARTED))); + printer.print(typedEvent(GptLiveSampleUtils.event("session.input_transcript.delta", "delta", "Hello"))); + printer.print(typedEvent(GptLiveSampleUtils.event("session.input_transcript.delta", "delta", " there"))); + printer.print(typedEvent(BinaryData.fromString("{\"type\":\"response.event\"," + + "\"event\":{\"type\":\"response.output_text.delta\",\"delta\":\"backend-only text\"}}"))); + printer.print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "Hi!"))); + printer.beginTurn(); + printer.print( + typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "How can I help?"))); + } finally { + System.setOut(original); + } + String transcript = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertEquals("Live session started; conversation_id not provided (persistence may be disabled)." + + System.lineSeparator() + "You: Hello there" + System.lineSeparator() + "Assistant: Hi!" + + System.lineSeparator() + "Assistant: How can I help?", transcript); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void startupPrintsFoundryConversationIdInScriptedAndInteractiveModes(boolean interactive) { + ServerEvent event = typedEvent(BinaryData.fromString( + "{\"type\":\"session.started\",\"conversation_id\":\"conversation-1\",\"session\":{\"id\":\"native-1\"}}")); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + if (interactive) { + new GptLiveSampleUtils.AudioTranscriptPrinter(false, true).print(event); + } else { + GptLiveSampleUtils.printEvent(event); + } + } finally { + System.setOut(original); + } + assertEquals("Live session started; conversation_id=conversation-1" + System.lineSeparator(), + new String(output.toByteArray(), StandardCharsets.UTF_8)); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void startupWithoutPersistenceDoesNotSubstituteNativeSessionId(boolean interactive) { + ServerEvent event = typedEvent(BinaryData.fromString(STARTED)); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + if (interactive) { + new GptLiveSampleUtils.AudioTranscriptPrinter(false, true).print(event); + } else { + GptLiveSampleUtils.printEvent(event); + } + } finally { + System.setOut(original); + } + assertEquals("Live session started; conversation_id not provided (persistence may be disabled)." + + System.lineSeparator(), new String(output.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + @ResourceLock("java.lang.System.out") + public void transcriptBufferIsBoundedWhileReadingInput() { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + GptLiveSampleUtils.AudioTranscriptPrinter printer = new GptLiveSampleUtils.AudioTranscriptPrinter(); + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + printer.print( + typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "Previous response."))); + printer.beginInput(); + assertTrue(new String(output.toByteArray(), StandardCharsets.UTF_8) + .endsWith("Previous response." + System.lineSeparator() + "You: ")); + int promptLength = output.size(); + char[] characters = new char[GptLiveSampleUtils.AudioTranscriptPrinter.MAX_BUFFERED_TRANSCRIPT_CHARACTERS + - "Assistant: ".length()]; + Arrays.fill(characters, 'a'); + printer.print(typedEvent( + GptLiveSampleUtils.event("session.output_transcript.delta", "delta", new String(characters)))); + assertEquals(promptLength, output.size(), "Transcript output must not overwrite the input line"); + IllegalStateException error = assertThrows(IllegalStateException.class, () -> printer + .print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "x")))); + assertTrue(error.getMessage().contains("65536")); + printer.endInput(); + assertTrue(output.size() > promptLength, "Buffered text must be flushed after input ends"); + } finally { + System.setOut(original); + } + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + @ResourceLock("java.lang.System.out") + public void consoleTranscriptUsesSingleLineBreaks(boolean inputEchoed) { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + GptLiveSampleUtils.AudioTranscriptPrinter printer + = new GptLiveSampleUtils.AudioTranscriptPrinter(inputEchoed); + printer.print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "Welcome."))); + printer.beginInput(); + if (inputEchoed) { + System.out.println("testing"); + } + printer.print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "Reply."))); + printer.endInput(); + printer.beginInput(); + if (inputEchoed) { + System.out.println("exit"); + } + printer.endInput(); + printer.print(typedEvent(BinaryData.fromString(CLOSED))); + System.out.println("Live session closed."); + } finally { + System.setOut(original); + } + String newline = System.lineSeparator(); + assertEquals( + "Assistant: Welcome." + newline + "You: " + (inputEchoed ? "testing" : "") + newline + "Assistant: Reply." + + newline + "You: " + (inputEchoed ? "exit" : "") + newline + "Live session closed." + newline, + new String(output.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + @ResourceLock("java.lang.System.out") + public void partialUtteranceSurvivesInputSubmissionWithoutBeingPrinted() { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + GptLiveSampleUtils.AudioTranscriptPrinter printer + = new GptLiveSampleUtils.AudioTranscriptPrinter(false, true); + printer.beginInput(); + printer.print( + typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "This sentence "))); + printer.endInput(); + assertFalse(new String(output.toByteArray(), StandardCharsets.UTF_8).contains("This sentence")); + printer.beginTurn(); + printer.beginInput(); + printer.print(typedEvent( + GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "continues after Enter."))); + printer.endUtterance(); + assertTrue(new String(output.toByteArray(), StandardCharsets.UTF_8).endsWith("You: ")); + printer.endInput(); + } finally { + System.setOut(original); + } + String newline = System.lineSeparator(); + assertEquals( + "You: " + newline + "You: " + newline + "Assistant: This sentence continues after Enter." + newline, + new String(output.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + @ResourceLock("java.lang.System.out") + public void completedAndPartialUtterancesShareTheTranscriptBufferLimit() { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + GptLiveSampleUtils.AudioTranscriptPrinter printer + = new GptLiveSampleUtils.AudioTranscriptPrinter(false, true); + printer.beginInput(); + printer + .print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "Completed."))); + printer.endUtterance(); + int queuedLength = ("Assistant: Completed." + System.lineSeparator()).length(); + char[] characters + = new char[GptLiveSampleUtils.AudioTranscriptPrinter.MAX_BUFFERED_TRANSCRIPT_CHARACTERS - queuedLength]; + Arrays.fill(characters, 'a'); + printer.print(typedEvent( + GptLiveSampleUtils.event("session.output_transcript.delta", "delta", new String(characters)))); + assertThrows(IllegalStateException.class, () -> printer + .print(typedEvent(GptLiveSampleUtils.event("session.output_transcript.delta", "delta", "x")))); + printer.endInput(); + assertTrue(new String(output.toByteArray(), StandardCharsets.UTF_8).contains("Assistant: Completed.")); + assertFalse(new String(output.toByteArray(), StandardCharsets.UTF_8).contains("aaaa")); + } finally { + System.setOut(original); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void spokenSentenceIsNotSplitByBackendCompletionOrAnotherTypedTurn(boolean async) { + AtomicInteger responses = new AtomicInteger(); + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, outbound) -> outbound + .sendString(Flux.concat(Mono.just(STARTED), inbound.receive().asString().concatMap(json -> { + Map command = GptLiveFunctionToolSample.object(BinaryData.fromString(json)); + commands.add(command); + if ("session.commentary.append".equals(command.get("type"))) { + return Flux.just("{\"type\":\"session.output_transcript.delta\",\"delta\":\"Welcome.\"}", + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}"); + } + if ("response.create".equals(command.get("type"))) { + String fragment + = responses.incrementAndGet() == 1 ? "This sentence " : "continues across typed turns."; + return Flux.just( + GptLiveSampleUtils.event("session.output_transcript.delta", "delta", fragment).toString(), + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}", COMPLETED); + } + return "session.close".equals(command.get("type")) ? Flux.just(CLOSED) : Flux.empty(); + }))) + .then())) + .bindNow(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + runInteractiveConversation(async, new StringReader("one\ntwo\nexit\n")); + } finally { + System.setOut(original); + } + assertEquals(2, responses.get()); + String transcript = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(transcript.contains("Assistant: This sentence continues across typed turns.")); + assertFalse(transcript.contains("Assistant: continues")); + assertEquals(2, transcript.split("Assistant: ", -1).length - 1); + assertEquals(3, transcript.split("You: ", -1).length - 1, "Input must remain available between backend turns"); + } + + @Test + @ResourceLock("java.lang.System.out") + public void unknownLiveEventsDoNotInterruptTranscriptHandlers() { + ServerEvent event = typedEvent(GptLiveSampleUtils.event("session.future_event", "value", "future")); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + GptLiveSampleUtils.printEvent(event); + new GptLiveSampleUtils.AudioTranscriptPrinter().print(event); + } finally { + System.setOut(original); + } + assertEquals(0, output.size()); + } + + @ParameterizedTest + @ValueSource(strings = { "response.failed", "response.incomplete" }) + public void responseFailuresAreReportedForUnknownAndDelegatedEvents(String type) { + BinaryData failure = GptLiveSampleUtils.event(type, "event_id", "failure-1"); + for (boolean delegated : new boolean[] { false, true }) { + Map wrapper = new LinkedHashMap<>(); + wrapper.put("type", "response.event"); + wrapper.put("event", GptLiveFunctionToolSample.object(failure)); + ServerEvent event = typedEvent(delegated ? BinaryData.fromObject(wrapper) : failure); + IllegalStateException error + = assertThrows(IllegalStateException.class, () -> GptLiveSampleUtils.printEvent(event)); + assertTrue(error.getMessage().contains(type)); + assertTrue(error.getMessage().contains("failure-1")); + assertThrows(IllegalStateException.class, + () -> new GptLiveSampleUtils.AudioTranscriptPrinter().print(event)); + } + } + + @Test + public void moderationIsReportedExplicitlyAndPreservesServiceDiagnostics() { + Map event = GptLiveFunctionToolSample.object(BinaryData.fromString(MODERATED)); + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> new GptLiveSampleUtils.AudioTranscriptPrinter().print(typedEvent(BinaryData.fromString(MODERATED)))); + assertTrue(error.getMessage().contains("generation stopped by service moderation")); + assertTrue(error.getMessage().contains("content_filter")); + assertTrue(error.getMessage().contains("moderated-1")); + Map wrapper = new java.util.LinkedHashMap<>(); + wrapper.put("type", "response.event"); + wrapper.put("event", event); + assertThrows(IllegalStateException.class, + () -> new GptLiveSampleUtils.AudioTranscriptPrinter().print(typedEvent(BinaryData.fromObject(wrapper)))); + } + + @ParameterizedTest + @MethodSource("invalidSampleSettingCases") + @ResourceLock("com.azure.core.util.Configuration") + public void examplesValidateSettingsBeforeCreatingClients(String sampleName, Consumer main, + String setting, String value) { + Configuration configuration = Configuration.getGlobalConfiguration(); + Map original = new LinkedHashMap<>(); + for (String name : Arrays.asList("FOUNDRY_PROJECT_ENDPOINT", "FOUNDRY_GPT_LIVE_MODEL", + "FOUNDRY_GPT_LIVE_BACKEND_MODEL")) { + original.put(name, configuration.get(name)); + } + try { + configuration.put("FOUNDRY_PROJECT_ENDPOINT", "not-an-endpoint"); + configuration.put("FOUNDRY_GPT_LIVE_MODEL", "gpt-live-1"); + configuration.put("FOUNDRY_GPT_LIVE_BACKEND_MODEL", "gpt-5.6-terra"); + configuration.put(setting, value); + IllegalArgumentException error + = assertThrows(IllegalArgumentException.class, () -> main.accept(new String[0]), sampleName); + assertTrue(error.getMessage().contains(setting)); + } finally { + original.forEach((name, previous) -> { + if (previous == null) { + configuration.remove(name); + } else { + configuration.put(name, previous); + } + }); + } + } + + private static Stream invalidSampleSettingCases() { + Map> samples = new LinkedHashMap<>(); + samples.put("audio-async", GptLiveAudioConversationAsyncSample::main); + samples.put("text", GptLiveTextConversationSample::main); + samples.put("interactive-text", GptLiveInteractiveTextConversationSample::main); + samples.put("interactive-text-async", GptLiveInteractiveTextConversationAsyncSample::main); + samples.put("text-async", GptLiveTextConversationAsyncSample::main); + samples.put("tools", GptLiveFunctionToolSample::main); + return samples.entrySet() + .stream() + .flatMap(sample -> Stream + .of("FOUNDRY_PROJECT_ENDPOINT", "FOUNDRY_GPT_LIVE_MODEL", "FOUNDRY_GPT_LIVE_BACKEND_MODEL") + .flatMap(setting -> Stream.of("", " ") + .map(value -> Arguments.of(sample.getKey(), sample.getValue(), setting, value)))); + } + + @BeforeAll + static void installTlsCertificate() { + VoiceAgentWebSocketSessionTests.installTlsCertificate(); + } + + @AfterAll + static void restoreTlsConfiguration() { + VoiceAgentWebSocketSessionTests.restoreTlsConfiguration(); + } + + @AfterEach + void closeServer() { + if (server != null) { + server.disposeNow(); + } + } + + @Test + public void blockingConversationConsumesEventsWithoutSession() { + java.util.concurrent.BlockingQueue incoming = new java.util.concurrent.LinkedBlockingQueue<>(); + incoming.add(typedEvent(BinaryData.fromString(STARTED))); + Iterable events = () -> Stream.generate(() -> { + try { + return incoming.take(); + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("Event producer interrupted.", error); + } + }).iterator(); + GptLiveTextConversationSample.runConversation(events, command -> { + commands.add(GptLiveFunctionToolSample.object(OpenAIJsonHelper.toBinaryData(command))); + if (command.isResponseCreate()) { + incoming.add(typedEvent(BinaryData.fromString(COMPLETED))); + } else if (command.isSessionClose()) { + incoming.add(typedEvent(BinaryData.fromString(CLOSED))); + } + }, () -> "test close details", Arrays.asList("one", "two")); + assertEquals(Arrays.asList("response.item.create", "response.create", "response.item.create", "response.create", + "session.close"), commandTypes()); + } + + @Test + public void blockingConversationReportsCloseDetailsWithoutSession() { + IllegalStateException error = assertThrows(IllegalStateException.class, () -> GptLiveTextConversationSample + .runConversation(Collections.singletonList(typedEvent(BinaryData.fromString(CLOSED))), command -> { + }, () -> "transport close code=1006, reason=test disconnect", Collections.emptyList())); + assertTrue(error.getMessage().contains("transport close code=1006, reason=test disconnect")); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void textSamplesWaitForStartupAndCompleteMultipleTurns(boolean async) { + startTextServer(false, false); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + if (async) { + Mono.usingWhen( + builder().beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient().openWebSocketSession("agent"), + session -> GptLiveTextConversationAsyncSample.runConversation(session, Arrays.asList("one", "two")), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync).block(TIMEOUT); + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + GptLiveTextConversationSample.runConversation(session, Arrays.asList("one", "two")); + } + } + } finally { + System.setOut(original); + } + String text = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(text.contains("Assistant: Hello")); + assertFalse(text.contains("Spoken reply."), "Primary text samples must not render voice transcripts"); + List expected = Arrays.asList("response.item.create", "response.create", "response.item.create", + "response.create", "session.close"); + assertEquals(expected, commandTypes()); + Map item = GptLiveFunctionToolSample.object(commands.get(0).get("item")); + assertEquals("user", item.get("role")); + assertEquals("message", item.get("type")); + assertEquals("one", GptLiveFunctionToolSample.object(((List) item.get("content")).get(0)).get("text")); + } + + @ParameterizedTest + @MethodSource("interactiveExitCases") + public void interactiveTextSamplesReadMultipleTurnsAndCloseOnExit(boolean async, String exit) { + startTextServer(false, false); + AtomicBoolean inputClosed = new AtomicBoolean(); + Reader input = new StringReader("one\r\ntwo\n" + exit) { + @Override + public void close() { + inputClosed.set(true); + super.close(); + } + }; + runInteractiveConversation(async, input); + assertEquals(Arrays.asList("session.commentary.append", "response.item.create", "response.create", + "response.item.create", "response.create", "session.close"), commandsWithoutInputAudio()); + List sentPrompts = commands.stream() + .filter(command -> "response.item.create".equals(command.get("type"))) + .map(command -> GptLiveFunctionToolSample.object(command.get("item"))) + .map(item -> GptLiveFunctionToolSample.object(((List) item.get("content")).get(0))) + .map(part -> GptLiveFunctionToolSample.string(part, "text")) + .collect(java.util.stream.Collectors.toList()); + assertEquals(Arrays.asList("one", "two"), sentPrompts); + assertFalse(inputClosed.get(), "Conversation cleanup must not close standard input"); + } + + @ParameterizedTest + @MethodSource("interactiveExitCases") + public void interactiveTextSamplesCanExitWithoutSendingAPrompt(boolean async, String text) { + startTextServer(false, false); + runInteractiveConversation(async, new StringReader(text)); + assertEquals(Arrays.asList("session.commentary.append", "session.close"), commandsWithoutInputAudio()); + } + + private static Stream interactiveExitCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of("", "\n", "exit\n", " QuIt \r\n").map(exit -> Arguments.of(async, exit))); + } + + private List commandsWithoutInputAudio() { + return commandTypes().stream() + .filter(type -> !"session.input_audio.append".equals(type)) + .collect(java.util.stream.Collectors.toList()); + } + + private void runInteractiveConversation(boolean async, Reader input) { + runInteractiveConversation(async, input, pcm -> { + }, () -> { + }); + } + + private void runInteractiveConversation(boolean async, Reader input, Consumer playAudio, + Runnable drainAudio) { + if (async) { + Mono.usingWhen( + builder().beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient().openWebSocketSession("agent"), + session -> GptLiveInteractiveTextConversationAsyncSample.runInteractiveConversationAsync(session, input, + playAudio, drainAudio), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync).block(TIMEOUT); + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + GptLiveInteractiveTextConversationSample.runInteractiveConversation(session, input, playAudio, + drainAudio); + } + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void interactiveTextSampleReceivesServiceErrorsWhileWaitingForInput(boolean async) { + Sinks.Empty inputStarted = Sinks.empty(); + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, outbound) -> outbound + .sendString(Flux.concat(Mono.just(STARTED), inbound.receive().asString().concatMap(json -> { + Map command = GptLiveFunctionToolSample.object(BinaryData.fromString(json)); + return "session.commentary.append".equals(command.get("type")) + ? Flux.just("{\"type\":\"session.output_transcript.delta\",\"delta\":\"Welcome.\"}", + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}") + : Flux.empty(); + })).mergeWith(inputStarted.asMono().thenReturn(MODERATED))) + .then())) + .bindNow(); + CountDownLatch releaseRead = new CountDownLatch(1); + Reader idleInput = new Reader() { + @Override + public boolean ready() { + throw new AssertionError("Console input must use a blocking line read, not readiness polling"); + } + + @Override + public int read(char[] buffer, int offset, int length) throws IOException { + inputStarted.tryEmitEmpty(); + try { + releaseRead.await(); + return -1; + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new IOException("Console read interrupted", error); + } + } + + @Override + public void close() { + throw new AssertionError("Standard input must not be closed"); + } + }; + try { + StepVerifier + .create(Mono.fromRunnable(() -> runInteractiveConversation(async, idleInput)) + .subscribeOn(Schedulers.boundedElastic())) + .expectErrorMatches( + error -> error instanceof IllegalStateException && error.getMessage().contains("content_filter")) + .verify(TIMEOUT); + } finally { + releaseRead.countDown(); + } + } + + @Test + public void consoleReadFailuresPropagate() { + Reader input = new StringReader("") { + @Override + public int read(char[] buffer, int offset, int length) throws IOException { + throw new IOException("Console unavailable"); + } + }; + StepVerifier.create(GptLiveInteractiveTextConversationAsyncSample.readPromptAsync(input)) + .expectErrorMatches( + error -> error instanceof IOException && "Console unavailable".equals(error.getMessage())) + .verify(TIMEOUT); + } + + @Test + public void consoleInputIsSubmittedOnlyAfterEnterWithoutLosingCharacters() throws Exception { + try (PipedReader input = new PipedReader(); PipedWriter keyboard = new PipedWriter(input)) { + CompletableFuture prompt + = GptLiveInteractiveTextConversationAsyncSample.readPromptAsync(input).toFuture(); + try { + keyboard.write("testtesttes testing"); + keyboard.flush(); + assertThrows(TimeoutException.class, () -> prompt.get(200, TimeUnit.MILLISECONDS)); + keyboard.write("\r\n"); + keyboard.flush(); + assertEquals("testtesttes testing", prompt.get(5, TimeUnit.SECONDS)); + } finally { + prompt.cancel(true); + } + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void greetingIsPrintedAndPlayedBeforeReadingInput(boolean async) throws Exception { + Sinks.Empty allowGreeting = Sinks.empty(); + CountDownLatch greetingRequested = new CountDownLatch(1); + CountDownLatch inputStarted = new CountDownLatch(1); + startTextServer(false, false, Mono.fromRunnable(greetingRequested::countDown).then(allowGreeting.asMono())); + CountDownLatch greetingPlayed = new CountDownLatch(1); + CountDownLatch replyPlayed = new CountDownLatch(1); + CountDownLatch drainStarted = new CountDownLatch(1); + CountDownLatch allowDrain = new CountDownLatch(1); + AtomicBoolean drained = new AtomicBoolean(); + AtomicInteger played = new AtomicInteger(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PipedReader pipe = new PipedReader(); + PipedWriter keyboard = new PipedWriter(pipe); + PrintStream capture = new PrintStream(output)) { + Reader input = new FilterReader(pipe) { + @Override + public int read(char[] buffer, int offset, int length) throws IOException { + assertTrue(drained.get(), "Queued greeting audio must finish before input begins"); + inputStarted.countDown(); + return super.read(buffer, offset, length); + } + }; + System.setOut(capture); + CompletableFuture conversation + = Mono.fromRunnable(() -> runInteractiveConversation(async, input, pcm -> { + if (played.incrementAndGet() == 1) { + greetingPlayed.countDown(); + } else { + replyPlayed.countDown(); + } + }, () -> { + drainStarted.countDown(); + try { + assertTrue(allowDrain.await(5, TimeUnit.SECONDS)); + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new AssertionError(error); + } + drained.set(true); + })).subscribeOn(Schedulers.boundedElastic()).toFuture(); + try { + assertTrue(greetingRequested.await(5, TimeUnit.SECONDS)); + assertFalse(inputStarted.await(200, TimeUnit.MILLISECONDS)); + allowGreeting.tryEmitEmpty(); + assertTrue(greetingPlayed.await(5, TimeUnit.SECONDS)); + assertFalse(inputStarted.await(200, TimeUnit.MILLISECONDS), + "The quiet period must elapse before prompting"); + assertTrue(drainStarted.await(5, TimeUnit.SECONDS)); + assertFalse(inputStarted.await(200, TimeUnit.MILLISECONDS), + "The first prompt must wait for queued speaker playback"); + allowDrain.countDown(); + assertTrue(inputStarted.await(5, TimeUnit.SECONDS)); + String whileTyping = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(whileTyping.endsWith("You: ")); + assertTrue(whileTyping.contains("Assistant: Welcome." + System.lineSeparator() + "You: ")); + keyboard.write("testing\n"); + keyboard.flush(); + assertTrue(replyPlayed.await(5, TimeUnit.SECONDS)); + keyboard.write("exit\n"); + keyboard.flush(); + conversation.get(5, TimeUnit.SECONDS); + String transcript = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(transcript.indexOf("Assistant: Welcome.") < transcript.indexOf("You: ")); + assertTrue(transcript.contains("Spoken reply.")); + assertFalse(transcript.contains(System.lineSeparator() + System.lineSeparator())); + } finally { + allowDrain.countDown(); + conversation.cancel(true); + } + } finally { + System.setOut(original); + } + } + + @Test + public void greetingWaitsForBothOutputsAndRestartsQuietPeriodForEachChunk() { + AtomicReference greeting = new AtomicReference<>(); + AtomicBoolean drained = new AtomicBoolean(); + StepVerifier.withVirtualTime(() -> { + GptLiveSampleUtils.Greeting pending = new GptLiveSampleUtils.Greeting(); + greeting.set(pending); + return pending.awaitPlaybackAsync(() -> drained.set(true)); + }) + .expectSubscription() + .then(() -> greeting.get().onTranscript()) + .expectNoEvent(Duration.ofSeconds(2)) + .then(() -> greeting.get().onAudio(new byte[] { 1, 2 })) + .expectNoEvent(Duration.ofMillis(750)) + .then(() -> greeting.get().onAudio(new byte[] { 1, 2 })) + .expectNoEvent(Duration.ofMillis(750)) + .then(() -> greeting.get().onTranscript()) + .expectNoEvent(Duration.ofMillis(999)) + .then(() -> assertFalse(drained.get())) + .thenAwait(Duration.ofMillis(1)) + .verifyComplete(); + assertTrue(drained.get()); + } + + @ParameterizedTest + @ValueSource(strings = { "session.output_transcript.delta", "session.output_audio.delta" }) + public void missingGreetingOutputTimesOutInsteadOfStartingInput(String type) { + AtomicBoolean drained = new AtomicBoolean(); + StepVerifier.withVirtualTime(() -> { + GptLiveSampleUtils.Greeting greeting = new GptLiveSampleUtils.Greeting(); + if ("session.output_audio.delta".equals(type)) { + greeting.onAudio(new byte[] { 1, 2 }); + } else { + greeting.onTranscript(); + } + return greeting.awaitPlaybackAsync(() -> drained.set(true)); + }).expectSubscription().thenAwait(GptLiveSampleUtils.TIMEOUT).expectError(TimeoutException.class).verify(); + assertFalse(drained.get()); + } + + @Test + public void greetingDrainFailureIsReported() { + StepVerifier.withVirtualTime(() -> { + GptLiveSampleUtils.Greeting greeting = new GptLiveSampleUtils.Greeting(); + greeting.onAudio(new byte[] { 1, 2 }); + greeting.onTranscript(); + return greeting.awaitPlaybackAsync(() -> { + throw new IllegalStateException("Speaker drain failed"); + }); + }).expectSubscription().thenAwait(Duration.ofSeconds(1)).expectErrorMessage("Speaker drain failed").verify(); + } + + @Test + public void continuousSilentOutputDoesNotKeepTheGreetingOpen() { + AtomicBoolean drained = new AtomicBoolean(); + StepVerifier.withVirtualTime(() -> { + GptLiveSampleUtils.Greeting greeting = new GptLiveSampleUtils.Greeting(); + greeting.onAudio(new byte[] { 1, 2 }); + greeting.onTranscript(); + Mono silence = Flux.interval(Duration.ofMillis(20)) + .take(50) + .doOnNext(tick -> greeting.onAudio(new byte[960])) + .then(); + return Mono.when(silence, greeting.awaitPlaybackAsync(() -> drained.set(true))); + }).expectSubscription().thenAwait(Duration.ofSeconds(1)).verifyComplete(); + assertTrue(drained.get()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void continuousSilentAudioStillAllowsInputAfterTheGreeting(boolean async) { + startTextServer(false, false, Mono.empty(), true); + AtomicInteger silentFrames = new AtomicInteger(); + AtomicBoolean readingInput = new AtomicBoolean(); + CountDownLatch silenceWhileReading = new CountDownLatch(1); + Reader input = new StringReader("exit\n") { + @Override + public int read(char[] buffer, int offset, int length) throws IOException { + assertTrue(silentFrames.get() > 0, "Silent output must arrive before input begins"); + readingInput.set(true); + try { + assertTrue(silenceWhileReading.await(5, TimeUnit.SECONDS), + "Silent output must continue while reading input"); + return super.read(buffer, offset, length); + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new IOException("Console read interrupted", error); + } finally { + readingInput.set(false); + } + } + }; + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + runInteractiveConversation(async, input, pcm -> { + if (pcm.length == 960) { + assertArrayEquals(new byte[960], pcm); + silentFrames.incrementAndGet(); + if (readingInput.get()) { + silenceWhileReading.countDown(); + } + } + }, () -> { + }); + } finally { + System.setOut(original); + } + String transcript = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(transcript.contains("Assistant: Welcome." + System.lineSeparator() + "You: "), + () -> "Expected greeting followed by input prompt (async=" + async + "). Actual transcript: " + + transcript.replace("\r", "\\r").replace("\n", "\\n")); + assertEquals(Arrays.asList("session.commentary.append", "session.close"), commandsWithoutInputAudio()); + } + + @ParameterizedTest + @ValueSource(ints = { 0, 256, -256, 257, -257, 32767, -32768 }) + public void greetingSpeechDetectionHonorsSignedPcm16PeakThreshold(int peak) { + boolean audible = Math.abs(peak) > GptLiveSampleUtils.Greeting.SILENCE_PEAK_THRESHOLD; + AtomicBoolean drained = new AtomicBoolean(); + StepVerifier.Step verification = StepVerifier.withVirtualTime(() -> { + GptLiveSampleUtils.Greeting greeting = new GptLiveSampleUtils.Greeting(); + greeting.onTranscript(); + greeting.onAudio(new byte[] { (byte) peak, (byte) (peak >> 8) }); + return greeting.awaitPlaybackAsync(() -> drained.set(true)); + }).expectSubscription().thenAwait(audible ? Duration.ofSeconds(1) : GptLiveSampleUtils.TIMEOUT); + if (audible) { + verification.verifyComplete(); + } else { + verification.expectError(TimeoutException.class).verify(); + } + assertEquals(audible, drained.get()); + } + + @ParameterizedTest + @ValueSource(strings = { "", "\r\n", "exit\n", "quit\n" }) + public void consoleEofBlankAndExitProduceNoPrompt(String input) { + StepVerifier.create(GptLiveInteractiveTextConversationAsyncSample.readPromptAsync(new StringReader(input))) + .verifyComplete(); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void interactiveTextPlaybackFailureTerminatesTheConversation(boolean async) { + startTextServer(false, false); + StepVerifier.create( + Mono.fromRunnable(() -> runInteractiveConversation(async, new StringReader("testing\n"), pcm -> { + throw new IllegalStateException("Speaker failed"); + }, () -> { + })).subscribeOn(Schedulers.boundedElastic())) + .expectErrorMatches( + error -> error instanceof IllegalStateException && "Speaker failed".equals(error.getMessage())) + .verify(TIMEOUT); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + @ResourceLock("java.lang.System.out") + public void interactiveTextPlaysGreetingAndRepliesWithoutPrintingBackendNotes(boolean async) { + startTextServer(false, false); + List played = new CopyOnWriteArrayList<>(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + PrintStream original = System.out; + try (PrintStream capture = new PrintStream(output)) { + System.setOut(capture); + runInteractiveConversation(async, new StringReader("testing\nexit\n"), played::add, () -> { + }); + } finally { + System.setOut(original); + } + assertEquals(2, played.size()); + assertArrayEquals(new byte[] { 1, 2 }, played.get(0)); + assertArrayEquals(new byte[] { 1, 2 }, played.get(1)); + String transcript = new String(output.toByteArray(), StandardCharsets.UTF_8); + assertTrue(transcript.contains("Assistant: Welcome.")); + assertTrue(transcript.contains("Spoken reply.")); + assertFalse(transcript.contains("Hello"), "Backend text must not be printed as the spoken answer"); + assertFalse(transcript.contains("[GPT Live diagnostics]")); + assertFalse(transcript.contains("\"type\":\"session.closed\"")); + Map greeting = commands.stream() + .filter(command -> "session.commentary.append".equals(command.get("type"))) + .findFirst() + .get(); + assertEquals("session.commentary.append", greeting.get("type")); + assertEquals("Hi, how can I help you today?", greeting.get("content")); + assertTrue(greeting.containsKey("delegation_id")); + assertEquals(null, greeting.get("delegation_id")); + assertEquals("session.input_audio.append", commands.get(0).get("type")); + assertEquals("session.close", commands.get(commands.size() - 1).get("type")); + } + + @Test + public void silentAudioFramesArePacedAtRealTimePcmRate() { + StepVerifier.withVirtualTime(() -> GptLiveSampleUtils.silenceFramesAsync().take(3)) + .expectSubscription() + .thenAwait(Duration.ZERO) + .assertNext(this::assertSilentAudioFrame) + .expectNoEvent(Duration.ofMillis(19)) + .thenAwait(Duration.ofMillis(1)) + .assertNext(this::assertSilentAudioFrame) + .expectNoEvent(Duration.ofMillis(19)) + .thenAwait(Duration.ofMillis(1)) + .assertNext(this::assertSilentAudioFrame) + .verifyComplete(); + } + + @Test + public void silentAudioFramesWaitForDemandWithoutTimerOverflow() { + StepVerifier.withVirtualTime(() -> GptLiveSampleUtils.silenceFramesAsync().take(3), 0) + .expectSubscription() + .expectNoEvent(Duration.ofSeconds(40)) + .thenRequest(1) + .assertNext(this::assertSilentAudioFrame) + .expectNoEvent(Duration.ofSeconds(40)) + .thenRequest(1) + .thenAwait(Duration.ofMillis(20)) + .assertNext(this::assertSilentAudioFrame) + .expectNoEvent(Duration.ofSeconds(40)) + .thenRequest(1) + .thenAwait(Duration.ofMillis(20)) + .assertNext(this::assertSilentAudioFrame) + .verifyComplete(); + } + + @Test + public void silentAudioToleratesSendsSlowerThanItsFrameRate() { + StepVerifier + .withVirtualTime(() -> GptLiveSampleUtils.silenceFramesAsync() + .concatMap(frame -> Mono.delay(Duration.ofMillis(75)).thenReturn(frame), 1) + .take(500)) + .expectSubscription() + .thenAwait(Duration.ofSeconds(40)) + .expectNextCount(500) + .verifyComplete(); + } + + private void assertSilentAudioFrame(ClientEvent frame) { + assertTrue(frame.isSessionInputAudioAppend()); + assertArrayEquals(new byte[960], Base64.getDecoder().decode(frame.asSessionInputAudioAppend().audio())); + } + + @ParameterizedTest + @MethodSource("interactiveClosureCases") + public void interactiveTextPreservesServerClosureReason(boolean async, String reason) { + String closed = "{\"type\":\"session.closed\",\"reason\":\"" + reason + "\",\"event_id\":\"closed-1\"}"; + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, outbound) -> outbound + .sendString(Flux.concat(Mono.just(STARTED), inbound.receive().asString().concatMap(json -> { + Map command = GptLiveFunctionToolSample.object(BinaryData.fromString(json)); + commands.add(command); + if ("session.commentary.append".equals(command.get("type"))) { + return Flux.just("{\"type\":\"session.output_transcript.delta\",\"delta\":\"Welcome.\"}", + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}"); + } + return "response.create".equals(command.get("type")) ? Mono.just(closed) : Mono.empty(); + }))) + .then())) + .bindNow(); + if ("remote_hangup".equals(reason)) { + runInteractiveConversation(async, new StringReader("testing\n")); + } else { + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> runInteractiveConversation(async, new StringReader("testing\n"))); + assertTrue(error.getMessage().contains(reason)); + assertTrue(error.getMessage().contains("closed-1")); + } + assertFalse(commandTypes().contains("session.close")); + } + + private static Stream interactiveClosureCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of("remote_hangup", "expired", "content", "connection_lost") + .map(reason -> Arguments.of(async, reason))); + } + + @Test + public void synchronousConsoleReadFailuresPropagateAndReleaseTheSession() { + startTextServer(false, false); + IOException failure = new IOException("Console unavailable"); + Reader input = new Reader() { + @Override + public int read(char[] buffer, int offset, int length) throws IOException { + throw failure; + } + + @Override + public void close() { + throw new AssertionError("Standard input must not be closed"); + } + }; + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> GptLiveInteractiveTextConversationSample.runInteractiveConversation(session, input, pcm -> { + }, () -> { + })); + assertEquals("Unable to read console input.", error.getMessage()); + assertEquals(failure, error.getCause()); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void serviceErrorsFailBothTextSamples(boolean async) { + startTextServer(false, true); + if (async) { + StepVerifier + .create(Mono.usingWhen( + builder().beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient().openWebSocketSession("agent"), + session -> GptLiveTextConversationAsyncSample.runConversation(session, + Collections.singletonList("one")), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync)) + .expectErrorMatches(error -> error instanceof IllegalStateException + && error.getMessage().contains("GPT Live service error")) + .verify(TIMEOUT); + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + assertThrows(IllegalStateException.class, + () -> GptLiveTextConversationSample.runConversation(session, Collections.singletonList("one"))); + } + } + assertFalse(commandTypes().contains("session.close")); + } + + @Test + public void toolsUseGranularEventsAndReturnResultsBeforeContinuation() { + startTextServer(true, false); + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + GptLiveFunctionToolSample.runConversation(session, Collections.singletonList("Weather in Seattle?"), + GptLiveFunctionToolSample::toolResult); + } + assertEquals(Arrays.asList("response.item.create", "response.create", "response.item.create", "response.create", + "session.close"), commandTypes()); + Map item = GptLiveFunctionToolSample.object(commands.get(2).get("item")); + assertEquals("function_call_output", item.get("type")); + assertEquals("call-1", item.get("call_id")); + Map result = GptLiveFunctionToolSample.object(BinaryData.fromString((String) item.get("output"))); + assertEquals("Seattle", result.get("city")); + assertEquals(true, result.get("simulated")); + assertFalse(item.containsKey("delegation_id")); + } + + @Test + public void toolHandlerFailureStopsConversationBeforeContinuation() { + startTextServer(true, false); + IllegalStateException failure = new IllegalStateException("Tool execution failed"); + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + IllegalStateException error = assertThrows(IllegalStateException.class, () -> GptLiveFunctionToolSample + .runConversation(session, Collections.singletonList("Weather in Seattle?"), call -> { + throw failure; + })); + assertEquals(failure, error); + } + assertEquals(Arrays.asList("response.item.create", "response.create"), commandTypes()); + } + + @Test + public void toolSampleHandlesMultipleTurns() { + startTextServer(true, false); + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + GptLiveFunctionToolSample.runConversation(session, Arrays.asList("Weather in Seattle?", "Thanks!"), + GptLiveFunctionToolSample::toolResult); + } + assertEquals(Arrays.asList("response.item.create", "response.create", "response.item.create", "response.create", + "response.item.create", "response.create", "session.close"), commandTypes()); + Map followUp = GptLiveFunctionToolSample.object(commands.get(4).get("item")); + assertEquals("user", followUp.get("role")); + assertEquals("Thanks!", + GptLiveFunctionToolSample.object(((List) followUp.get("content")).get(0)).get("text")); + } + + @Test + public void toolSchemaAndArgumentsAreValidated() { + Map tool + = GptLiveFunctionToolSample.object(OpenAIJsonHelper.toBinaryData(GptLiveFunctionToolSample.weatherTool())); + assertEquals("function", tool.get("type")); + assertEquals("get_weather", tool.get("name")); + assertEquals(true, tool.get("strict")); + assertEquals(false, GptLiveFunctionToolSample.object(tool.get("parameters")).get("additionalProperties")); + ResponseFunctionToolCall unknown + = ResponseFunctionToolCall.builder().name("unknown").callId("c").arguments("{}").build(); + assertThrows(IllegalArgumentException.class, () -> GptLiveFunctionToolSample.toolResult(unknown)); + ResponseFunctionToolCall invalid + = ResponseFunctionToolCall.builder().name("get_weather").callId("c").arguments("{}").build(); + assertThrows(IllegalArgumentException.class, () -> GptLiveFunctionToolSample.toolResult(invalid)); + } + + @ParameterizedTest + @MethodSource("invalidTextLifecycleCases") + public void invalidLifecycleFailsBothTextSamples(boolean async, List events, String message) { + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket( + (inbound, outbound) -> outbound.sendString(Flux.fromIterable(events)).then(inbound.receive().then()))) + .bindNow(); + if (async) { + StepVerifier + .create(Mono.usingWhen( + builder().beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient().openWebSocketSession("agent"), + session -> GptLiveTextConversationAsyncSample.runConversation(session, + Collections.singletonList("one")), + BetaVoiceAgentsLiveWebSocketSessionAsyncClient::closeAsync)) + .expectErrorMatches( + error -> error instanceof IllegalStateException && error.getMessage().contains(message)) + .verify(TIMEOUT); + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + IllegalStateException error = assertThrows(IllegalStateException.class, + () -> GptLiveTextConversationSample.runConversation(session, Collections.singletonList("one"))); + assertTrue(error.getMessage().contains(message), error.getMessage()); + } + } + } + + static Stream invalidTextLifecycleCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of( + Arguments.of(async, Arrays.asList(STARTED, CLOSED), "closed before all turns completed"), + Arguments.of(async, Arrays.asList(STARTED, STARTED), "Duplicate session.started"), + Arguments.of(async, Collections.singletonList(COMPLETED), "Unexpected GPT Live response lifecycle"))); + } + + @Test + public void typedCommentaryPreservesExplicitNullDelegationId() throws IOException { + ClientEvent event = GptLiveSampleUtils.commentary("Hello"); + assertTrue(event.isSessionCommentaryAppend()); + BinaryData data = OpenAIJsonHelper.toBinaryData(event); + Map command = GptLiveFunctionToolSample.object(data); + assertEquals("session.commentary.append", command.get("type")); + assertEquals("Hello", command.get("content")); + assertTrue(command.containsKey("delegation_id")); + assertEquals(null, command.get("delegation_id")); + assertEquals(command, data.toObject(Map.class)); + assertEquals(command, GptLiveFunctionToolSample.object(BinaryData.fromBytes(data.toBytes()))); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (com.azure.json.JsonWriter writer = com.azure.json.JsonProviders.createWriter(output)) { + data.writeTo(writer); + } + assertEquals(command, GptLiveFunctionToolSample.object(BinaryData.fromBytes(output.toByteArray()))); + } + + @Test + public void nativeAudioEncodingAndDecodingPreservePcmBytes() { + byte[] pcm = new byte[] { 0, 1, -1, 127 }; + ClientEvent command = GptLiveSampleUtils.audio(pcm); + assertTrue(command.isSessionInputAudioAppend()); + assertArrayEquals(pcm, Base64.getDecoder().decode(command.asSessionInputAudioAppend().audio())); + ServerEvent event = typedEvent( + GptLiveSampleUtils.event("session.output_audio.delta", "delta", Base64.getEncoder().encodeToString(pcm))); + assertArrayEquals(pcm, GptLiveSampleUtils.decodeAudio(event)); + assertThrows(IllegalArgumentException.class, () -> GptLiveSampleUtils + .decodeAudio(typedEvent(GptLiveSampleUtils.event("session.output_audio.delta", "delta", "%%%")))); + assertThrows(IllegalArgumentException.class, () -> GptLiveSampleUtils + .decodeAudio(typedEvent(GptLiveSampleUtils.event("session.output_audio.delta", "delta", "AA==")))); + } + + private static ServerEvent typedEvent(BinaryData data) { + return OpenAIJsonHelper.fromBinaryData(data, ServerEvent.class); + } + + private static Stream audioSessionCases() { + return Stream.of(false, true) + .flatMap(moderated -> Stream.of(false, true).map(store -> Arguments.of(moderated, store))); + } + + @ParameterizedTest + @MethodSource("audioSessionCases") + public void audioSampleGreetsCapturesPlaysAndReleasesDevices(boolean moderated, boolean store) { + AtomicBoolean captured = new AtomicBoolean(); + AtomicInteger closed = new AtomicInteger(); + CountDownLatch unblockRead = new CountDownLatch(1); + AtomicReference played = new AtomicReference<>(); + AtomicBoolean firstRead = new AtomicBoolean(true); + TargetDataLine microphone = (TargetDataLine) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { TargetDataLine.class }, (proxy, method, args) -> { + if ("read".equals(method.getName())) { + if (firstRead.compareAndSet(true, false)) { + byte[] bytes = (byte[]) args[0]; + bytes[0] = 1; + bytes[1] = 2; + return 2; + } + unblockRead.await(5, TimeUnit.SECONDS); + return 0; + } else if ("close".equals(method.getName())) { + closed.incrementAndGet(); + unblockRead.countDown(); + } + return null; + }); + SourceDataLine speaker = (SourceDataLine) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[] { SourceDataLine.class }, (proxy, method, args) -> { + if ("write".equals(method.getName())) { + played.set(((byte[]) args[0]).clone()); + return args[2]; + } else if ("close".equals(method.getName())) { + closed.incrementAndGet(); + } + return null; + }); + AtomicReference requestUri = new AtomicReference<>(); + String started = store + ? "{\"type\":\"session.started\",\"conversation_id\":\"conversation-1\",\"session\":{\"id\":\"live-1\"}}" + : STARTED; + server = VoiceAgentWebSocketSessionTests.tlsServer().host("localhost").port(0).handle((request, response) -> { + requestUri.set(request.uri()); + return response + .sendWebsocket( + (inbound, + outbound) -> outbound.sendString(Flux.concat( + Flux.just(started, "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}"), + inbound.receive().asString().concatMap(json -> { + Map command = GptLiveFunctionToolSample.object(BinaryData.fromString(json)); + commands.add(command); + if ("session.input_audio.append".equals(command.get("type"))) { + captured.set(true); + } + if (moderated && "response.create".equals(command.get("type"))) { + return Mono.just(MODERATED); + } + return "session.close".equals(command.get("type")) ? Mono.just(CLOSED) : Mono.empty(); + }))).then()); + }).bindNow(); + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(store)) + .block(TIMEOUT); + assertNotNull(session); + assertTrue(requestUri.get().contains("store=" + store), requestUri.get()); + InputStream enterAfterAudio = new InputStream() { + @Override + public int available() { + return captured.get() && played.get() != null && commandTypes().contains("response.create") ? 1 : 0; + } + + @Override + public int read() { + return '\n'; + } + }; + try { + GptLiveSampleUtils.AudioProcessor processor = new GptLiveSampleUtils.AudioProcessor(microphone, speaker, + pcm -> session.sendEvent(GptLiveSampleUtils.audio(pcm.toBytes()))); + Mono conversation + = GptLiveAudioConversationAsyncSample.runAudioConversationAsync(session, processor, enterAfterAudio); + if (moderated) { + IllegalStateException error + = assertThrows(IllegalStateException.class, () -> conversation.block(TIMEOUT)); + assertTrue(error.getMessage().contains("content_filter")); + assertTrue(error.getMessage().contains("moderated-1")); + } else { + conversation.block(TIMEOUT); + assertTrue(captured.get()); + assertArrayEquals(new byte[] { 1, 2 }, played.get()); + assertTrue(commandTypes().contains("session.close")); + } + assertEquals(2, closed.get()); + List greetingCommands = commandTypes().stream() + .filter(type -> "response.item.create".equals(type) || "response.create".equals(type)) + .collect(java.util.stream.Collectors.toList()); + assertEquals(Arrays.asList("response.item.create", "response.create"), greetingCommands); + Map greeting = commands.stream() + .filter(command -> "response.item.create".equals(command.get("type"))) + .findFirst() + .get(); + Map item = GptLiveFunctionToolSample.object(greeting.get("item")); + assertEquals("Greet me briefly with: Hi, how can I help you today?", + GptLiveFunctionToolSample.object(((List) item.get("content")).get(0)).get("text")); + } finally { + session.closeAsync().block(TIMEOUT); + } + } + + private List commandTypes() { + return commands.stream() + .map(command -> GptLiveFunctionToolSample.string(command, "type")) + .collect(java.util.stream.Collectors.toList()); + } + + private AgentsClientBuilder builder() { + return new AgentsClientBuilder().endpoint("https://localhost:" + server.port()) + .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) + .configuration(Configuration.NONE); + } + + private void startTextServer(boolean tools, boolean fail) { + startTextServer(tools, fail, Mono.empty()); + } + + private void startTextServer(boolean tools, boolean fail, Mono beforeGreeting) { + startTextServer(tools, fail, beforeGreeting, false); + } + + private void startTextServer(boolean tools, boolean fail, Mono beforeGreeting, boolean continuousSilence) { + AtomicInteger responses = new AtomicInteger(); + AtomicInteger silentInputs = new AtomicInteger(); + String silentOutput = "{\"type\":\"session.output_audio.delta\",\"delta\":\"" + + Base64.getEncoder().encodeToString(new byte[960]) + "\"}"; + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, + response) -> response.sendWebsocket((inbound, outbound) -> outbound + .sendString(Flux.concat(Mono.just(STARTED).delayElement(Duration.ofMillis(50)), + inbound.receive().asString().concatMap(json -> { + Map command = GptLiveFunctionToolSample.object(BinaryData.fromString(json)); + commands.add(command); + if ("session.commentary.append".equals(command.get("type"))) { + return beforeGreeting.thenMany( + Flux.just("{\"type\":\"session.output_transcript.delta\",\"delta\":\"Welcome.\"}", + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}")); + } + if ("response.create".equals(command.get("type"))) { + int responseIndex = responses.incrementAndGet(); + if (fail) { + return Flux.just("{\"type\":\"error\",\"error\":{\"message\":\"failed\"}}"); + } + if (tools && responseIndex == 1) { + return Flux.just("{\"type\":\"response.event\",\"delegation_id\":\"del-1\"," + + "\"event\":{\"type\":\"response.output_item.done\",\"item\":" + + "{\"type\":\"function_call\",\"call_id\":\"call-1\",\"name\":\"get_weather\"," + + "\"arguments\":\"{\\\"city\\\":\\\"Seattle\\\"}\"}}}", COMPLETED); + } + return Flux.just( + "{\"type\":\"response.event\",\"event\":" + + "{\"type\":\"response.output_text.delta\",\"delta\":\"Hello\"}}", + "{\"type\":\"session.output_transcript.delta\",\"delta\":\"Spoken reply.\"}", + "{\"type\":\"session.output_audio.delta\",\"delta\":\"AQI=\"}", COMPLETED); + } + if (continuousSilence && "session.input_audio.append".equals(command.get("type"))) { + return silentInputs.getAndIncrement() % 5 == 0 ? Flux.just(silentOutput) : Flux.empty(); + } + return "session.close".equals(command.get("type")) ? Flux.just(CLOSED) : Flux.empty(); + }))) + .then())) + .bindNow(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsAsyncTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsAsyncTests.java index 6d684658132ab..c16daa0a8a0f1 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsAsyncTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsAsyncTests.java @@ -7,7 +7,7 @@ import com.azure.ai.agents.AgentsAsyncClient; import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsConversationsAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.RealtimeResponseDoneEvent; import com.azure.ai.agents.models.RealtimeSessionCreatedEvent; @@ -105,7 +105,7 @@ public void readLivePersistedConversation() { try { agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)).block(TIMEOUT); created = true; - Mono.usingWhen(builder.beta().buildBetaVoiceAgentWebSocketAsyncClient().openWebSocketSession(agentName), + Mono.usingWhen(builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient().openWebSocketSession(agentName), session -> session.receiveEvents().index().concatMap(indexed -> { if (indexed.getT1() == 0) { assertTrue(indexed.getT2() instanceof RealtimeSessionCreatedEvent, @@ -123,8 +123,8 @@ public void readLivePersistedConversation() { .switchIfEmpty(Mono.error(new AssertionError("Session ended without response.done."))) .timeout(Duration.ofSeconds(45)) .then(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync).block(Duration.ofSeconds(90)); + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync).block(Duration.ofSeconds(90)); Mono.delay(Duration.ofSeconds(30)).block(Duration.ofSeconds(35)); reading = true; assertPersistedConversation(conversations, agentName, conversationId.get()); diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsTests.java index 590ed1b4cceaf..d80518c0c5a52 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentConversationsTests.java @@ -6,7 +6,7 @@ import com.azure.ai.agents.AgentsClient; import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsConversationsClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.RealtimeServerEvent; import com.azure.ai.agents.models.RealtimeResponseDoneEvent; @@ -107,8 +107,8 @@ public void readLivePersistedConversation() throws InterruptedException { try { agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition)); created = true; - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession(agentName)) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession(agentName)) { Iterator events = session.receiveEvents(TIMEOUT).iterator(); assertTrue(events.hasNext(), "Expected session.created."); RealtimeServerEvent first = events.next(); diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudAsyncTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudAsyncTests.java index 335a8cd63a91c..98227f44d955c 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudAsyncTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudAsyncTests.java @@ -228,7 +228,8 @@ private static void validateAgent(AgentDetails agent, String name, String expect private static Map createBody(String instructions) { return object("definition", - object("kind", "voice", "model_type", "managed", "model", MODEL, "instructions", instructions, "audio", + object("kind", "voice", "sub_protocol", "realtime", "model_type", "managed", "model", MODEL, "instructions", + instructions, "audio", object("output", object("voice", "en-US-AvaNeural", "voice_type", "azure-standard")), "output_modalities", Collections.singletonList("audio"))); } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudTests.java index f502e686873b0..159892525389c 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentCrudTests.java @@ -218,7 +218,8 @@ private static void validateAgent(AgentDetails agent, String name, String expect private static Map createBody(String instructions) { return object("definition", - object("kind", "voice", "model_type", "managed", "model", MODEL, "instructions", instructions, "audio", + object("kind", "voice", "sub_protocol", "realtime", "model_type", "managed", "model", MODEL, "instructions", + instructions, "audio", object("output", object("voice", "en-US-AvaNeural", "voice_type", "azure-standard")), "output_modalities", Collections.singletonList("audio"))); } diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSampleTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSampleTests.java new file mode 100644 index 0000000000000..65068289eb980 --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveTextConversationSampleTests.java @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.core.exception.HttpResponseException; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.HttpHeaders; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.HttpResponse; +import com.azure.core.http.policy.ExponentialBackoffOptions; +import com.azure.core.http.policy.RetryOptions; +import com.azure.core.test.http.MockHttpResponse; +import com.azure.core.test.utils.MockTokenCredential; +import com.azure.core.util.BinaryData; +import com.azure.core.util.Configuration; +import com.azure.core.util.Context; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.publisher.Mono; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VoiceAgentLiveTextConversationSampleTests { + private static final String NAME = "sample-live-text-conversation-agent-java"; + private static final String GENERATE = "/agents:generate"; + private static final String AGENT = "/agents/" + NAME; + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void createdAgentIsDeletedOnNormalExitAndFailure(boolean failConversation) { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, 200); + transport.expect(HttpMethod.DELETE, AGENT, 200); + AgentsClientBuilder builder = builder(transport); + IllegalStateException failure = new IllegalStateException("Conversation failed"); + Runnable conversation = () -> { + try (VoiceAgentLiveTextConversationSample.SampleAgent agent = VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)) { + assertNotNull(agent.details); + if (failConversation) { + throw failure; + } + } + }; + if (failConversation) { + assertSame(failure, assertThrows(IllegalStateException.class, conversation::run)); + } else { + conversation.run(); + } + transport.assertConsumed(); + } + + @Test + public void conflictDeletesExistingAgentRetriesOnceAndDeletesReplacement() { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, 409); + transport.expect(HttpMethod.DELETE, AGENT, 200); + transport.expect(HttpMethod.POST, GENERATE, 200); + transport.expect(HttpMethod.DELETE, AGENT, 200); + AgentsClientBuilder builder = builder(transport); + try (VoiceAgentLiveTextConversationSample.SampleAgent agent = VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)) { + assertNotNull(agent.details); + } + transport.assertConsumed(); + } + + @ParameterizedTest + @ValueSource(ints = { 400, 403, 412 }) + public void nonConflictCreationFailureDoesNotDeleteAnAgent(int status) { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, status); + AgentsClientBuilder builder = builder(transport); + HttpResponseException error + = assertThrows(HttpResponseException.class, () -> VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)); + assertEquals(status, error.getResponse().getStatusCode()); + transport.assertConsumed(); + } + + @Test + public void replacementDeletionFailureStopsWithoutRetryingCreation() { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, 409); + transport.expect(HttpMethod.DELETE, AGENT, 403); + AgentsClientBuilder builder = builder(transport); + HttpResponseException error + = assertThrows(HttpResponseException.class, () -> VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)); + assertEquals(403, error.getResponse().getStatusCode()); + transport.assertConsumed(); + } + + @Test + public void repeatedConflictIsNotRetriedOrDeletedAgain() { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, 409); + transport.expect(HttpMethod.DELETE, AGENT, 200); + transport.expect(HttpMethod.POST, GENERATE, 409); + AgentsClientBuilder builder = builder(transport); + HttpResponseException error + = assertThrows(HttpResponseException.class, () -> VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)); + assertEquals(409, error.getResponse().getStatusCode()); + transport.assertConsumed(); + } + + @Test + public void cleanupFailureIsPreservedAlongsideConversationFailure() { + ScriptedTransport transport = new ScriptedTransport(); + transport.expect(HttpMethod.POST, GENERATE, 200); + transport.expect(HttpMethod.DELETE, AGENT, 403); + AgentsClientBuilder builder = builder(transport); + IllegalStateException failure = new IllegalStateException("Conversation failed"); + IllegalStateException error = assertThrows(IllegalStateException.class, () -> { + try (VoiceAgentLiveTextConversationSample.SampleAgent agent = VoiceAgentLiveTextConversationSample + .createAgent(builder.buildAgentsClient(), builder.beta().buildBetaAgentsClient(), NAME)) { + assertNotNull(agent.details); + throw failure; + } + }); + assertSame(failure, error); + assertEquals(1, error.getSuppressed().length); + assertTrue(error.getSuppressed()[0] instanceof HttpResponseException); + transport.assertConsumed(); + } + + private static AgentsClientBuilder builder(HttpClient transport) { + return new AgentsClientBuilder().endpoint("https://localhost") + .credential(new MockTokenCredential()) + .configuration(Configuration.NONE) + .httpClient(transport) + .retryOptions(new RetryOptions(new ExponentialBackoffOptions().setMaxRetries(0))) + .allowPreview(true); + } + + private static final class ScriptedTransport implements HttpClient { + private final Deque> requests = new ArrayDeque<>(); + + void expect(HttpMethod method, String path, int status) { + requests.add(request -> { + assertEquals(method, request.getHttpMethod()); + assertEquals(path, request.getUrl().getPath()); + if (method == HttpMethod.POST) { + assertEquals(NAME, request.getBodyAsBinaryData().toObject(java.util.Map.class).get("name")); + } + String body = status >= 400 + ? "{\"error\":{\"code\":\"" + (status == 409 ? "conflict" : "failed") + + "\",\"message\":\"failed\"}}" + : "{}"; + return new MockHttpResponse(request, status, + new HttpHeaders().set(HttpHeaderName.CONTENT_TYPE, "application/json"), + BinaryData.fromString(body).toBytes()); + }); + } + + @Override + public Mono send(HttpRequest request) { + throw new AssertionError("The sync sample must not use asynchronous HTTP."); + } + + @Override + public HttpResponse sendSync(HttpRequest request, Context context) { + assertFalse(requests.isEmpty(), "Unexpected request: " + request.getUrl()); + return requests.removeFirst().apply(request); + } + + void assertConsumed() { + assertTrue(requests.isEmpty(), "Expected HTTP requests were not sent"); + } + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveWebSocketTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveWebSocketTests.java new file mode 100644 index 0000000000000..88526d703823c --- /dev/null +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentLiveWebSocketTests.java @@ -0,0 +1,644 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.agents.voice; + +import com.azure.ai.agents.AgentsClientBuilder; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsLiveWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; +import com.azure.ai.agents.implementation.OpenAIJsonHelper; +import com.azure.ai.agents.models.VoiceAgentLiveWebSocketConnectionOptions; +import com.azure.ai.agents.models.VoiceAgentWebSocketConnectionOptions; +import com.azure.core.credential.AccessToken; +import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.util.BinaryData; +import com.azure.core.util.ClientOptions; +import com.azure.core.util.Configuration; +import com.azure.core.util.Header; +import com.openai.core.JsonValue; +import com.openai.models.live.ClientEvent; +import com.openai.models.live.ResponseCreateEvent; +import com.openai.models.live.ServerEvent; +import io.netty.handler.codec.http.HttpHeaderNames; +import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.parallel.ResourceLock; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.netty.DisposableServer; +import reactor.netty.http.server.WebsocketServerSpec; +import reactor.test.StepVerifier; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ResourceLock("voice-agent-websocket-tls") +@Timeout(20) +public class VoiceAgentLiveWebSocketTests { + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private static final String STARTED + = "{\"type\":\"session.started\",\"conversation_id\":\"conversation-1\",\"session\":{\"id\":\"live-1\"}}"; + private static final String RESPONSE = "{\"type\":\"response.done\",\"future_field\":{\"native\":true}}"; + private static final String FUTURE = "{\"type\":\"future.live.event\",\"unknown\":[1,2,3]}"; + private static final String ERROR + = "{\"type\":\"error\",\"error\":{\"type\":\"server_error\",\"message\":\"native Live error\"}}"; + private static final String COMMAND = "{\"type\":\"session.update\",\"session\":{\"future_setting\":true}}"; + private DisposableServer server; + + @BeforeAll + static void installTlsCertificate() { + VoiceAgentWebSocketSessionTests.installTlsCertificate(); + } + + @AfterAll + static void restoreTlsConfiguration() { + VoiceAgentWebSocketSessionTests.restoreTlsConfiguration(); + } + + @AfterEach + void stopServer() { + if (server != null) { + server.disposeNow(); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void handshakeUsesLiveRouteWithoutRealtimeSubprotocol(boolean async) throws Exception { + AtomicReference requestUri = new AtomicReference<>(); + AtomicReference headers = new AtomicReference<>(); + server = VoiceAgentWebSocketSessionTests.tlsServer().host("localhost").port(0).handle((request, response) -> { + requestUri.set(request.uri()); + headers.set(request.requestHeaders().copy()); + return response.sendWebsocket((inbound, outbound) -> inbound.receive().then()); + }).bindNow(); + AgentsClientBuilder builder + = builder().endpoint("https://localhost:" + server.port() + "/api/projects/project/") + .clientOptions(new ClientOptions().setApplicationId("live-app") + .setHeaders(Arrays.asList(new Header("X-Custom", "value"), new Header("Authorization", "override"), + new Header("Foundry-Features", "override"), new Header("Sec-WebSocket-Protocol", "realtime")))); + String inputs = "{\"name\":\"a & b/\u4f60\u597d\"}"; + VoiceAgentLiveWebSocketConnectionOptions options + = new VoiceAgentLiveWebSocketConnectionOptions().setStoreEnabled(true) + .setAgentVersionOverride("version 1") + .setStructuredInputs(inputs); + if (async) { + Mono connection = builder.beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent /name", options); + options.setStoreEnabled(false).setAgentVersionOverride("changed").setStructuredInputs("{}"); + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = connection.block(TIMEOUT); + assertNotNull(session); + assertTrue(session.isOpen()); + session.closeAsync().block(TIMEOUT); + assertFalse(session.isOpen()); + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session = builder.beta() + .buildBetaVoiceAgentsLiveWebSocketClient() + .openWebSocketSession("agent /name", options)) { + assertTrue(session.isOpen()); + } + } + + URI uri = URI.create(requestUri.get()); + assertEquals("/api/projects/project/agents/agent%20%2Fname/endpoint/protocols/voice/live/sessions", + uri.getRawPath()); + String query = URLDecoder.decode(uri.getRawQuery(), StandardCharsets.UTF_8.name()); + assertTrue(query.contains("api-version=v1"), query); + assertTrue(query.contains("store=true"), query); + assertTrue(query.contains("x-agent-version-override=version 1"), query); + assertTrue(query.contains("structured_inputs=" + inputs), query); + assertFalse(query.contains("transport="), query); + assertFalse(query.contains("agent_session_id="), query); + assertNull(headers.get().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)); + assertNull(headers.get().get("x-ms-voice-structured-inputs")); + assertEquals("VoiceAgents=V1Preview", headers.get().get("Foundry-Features")); + assertEquals("value", headers.get().get("X-Custom")); + assertTrue(headers.get().get(HttpHeaderNames.USER_AGENT).startsWith("live-app azsdk-java-")); + assertFalse("override".equals(headers.get().get(HttpHeaderNames.AUTHORIZATION))); + } + + @Test + public void syncNativeEventsAreLosslessAndSessionIsBidirectional() { + List sent = new CopyOnWriteArrayList<>(); + startEchoServer(sent); + BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent"); + try { + Iterator events = session.receiveRawEvents(TIMEOUT).iterator(); + assertEquals(STARTED, events.next().toString()); + assertEquals(RESPONSE, events.next().toString()); + assertEquals(FUTURE, events.next().toString()); + assertEquals(ERROR, events.next().toString()); + assertThrows(IllegalStateException.class, session::receiveRawEvents); + assertThrows(IllegalStateException.class, session::receiveEvents); + assertThrows(IllegalArgumentException.class, () -> session.sendEvent(BinaryData.fromString("[]"))); + session.sendEvent(BinaryData.fromString(COMMAND)); + assertEquals(COMMAND, events.next().toString()); + assertEquals(Arrays.asList(COMMAND), sent); + session.close(1000, "done"); + assertFalse(session.isOpen()); + assertThrows(IllegalStateException.class, () -> session.sendEvent(BinaryData.fromString(COMMAND))); + } finally { + session.close(); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void rawReceptionDoesNotRequireTypedDecoding(boolean async) { + String message = "not-json"; + String unusualPayload = "{\"type\":\"session.started\",\"session\":7}"; + AtomicInteger malformed = new AtomicInteger(); + VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions() + .setMalformedEventHandler(error -> malformed.incrementAndGet()); + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, + outbound) -> outbound.sendString(Flux.just(message, unusualPayload)).then(inbound.receive().then()))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", options) + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveRawEvents().take(2)) + .assertNext(event -> assertEquals(message, event.toString())) + .assertNext(event -> assertEquals(unusualPayload, event.toString())) + .verifyComplete(); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent", options)) { + Iterator events = session.receiveRawEvents(TIMEOUT).iterator(); + assertEquals(message, events.next().toString()); + assertEquals(unusualPayload, events.next().toString()); + } + } + assertEquals(0, malformed.get()); + } + + @Test + public void asyncNativeEventsAreLosslessAndSessionIsBidirectional() { + List sent = new CopyOnWriteArrayList<>(); + startEchoServer(sent); + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent") + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.sendEvent(BinaryData.fromString("[]"))) + .expectError(IllegalArgumentException.class) + .verify(TIMEOUT); + StepVerifier + .create(session.sendEvent(BinaryData.fromString(COMMAND)) + .thenMany(session.receiveRawEvents()) + .map(BinaryData::toString)) + .expectNext(STARTED, RESPONSE, FUTURE, ERROR) + .expectNext(COMMAND) + .thenCancel() + .verify(TIMEOUT); + assertEquals(Arrays.asList(COMMAND), sent); + StepVerifier.create(session.receiveRawEvents()).expectError(IllegalStateException.class).verify(TIMEOUT); + StepVerifier.create(session.receiveEvents()).expectError(IllegalStateException.class).verify(TIMEOUT); + session.closeAsync(1000, "done").block(TIMEOUT); + assertFalse(session.isOpen()); + StepVerifier.create(session.sendEvent(BinaryData.fromString(COMMAND))) + .expectError(IllegalStateException.class) + .verify(TIMEOUT); + } finally { + session.closeAsync().block(TIMEOUT); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void sameBuilderKeepsLiveAndRealtimeHandshakesIndependent(boolean async) { + List requestUris = new CopyOnWriteArrayList<>(); + List headers = new CopyOnWriteArrayList<>(); + server = VoiceAgentWebSocketSessionTests.tlsServer().host("localhost").port(0).handle((request, response) -> { + requestUris.add(request.uri()); + headers.add(request.requestHeaders().copy()); + return response.sendWebsocket((inbound, outbound) -> inbound.receive().then(), + WebsocketServerSpec.builder().protocols("realtime").build()); + }).bindNow(); + AgentsClientBuilder builder = builder(); + String inputs = "{\"name\":\"value\"}"; + VoiceAgentLiveWebSocketConnectionOptions liveOptions + = new VoiceAgentLiveWebSocketConnectionOptions().setStructuredInputs(inputs); + VoiceAgentWebSocketConnectionOptions realtimeOptions + = new VoiceAgentWebSocketConnectionOptions().setStructuredInputs(inputs); + if (async) { + try (BetaVoiceAgentsLiveWebSocketSessionAsyncClient live = builder.beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", liveOptions) + .block(TIMEOUT)) { + assertNotNull(live); + assertTrue(live.isOpen()); + } + try (BetaVoiceAgentsWebSocketSessionAsyncClient realtime = builder.beta() + .buildBetaVoiceAgentsWebSocketAsyncClient() + .openWebSocketSession("agent", realtimeOptions) + .block(TIMEOUT)) { + assertNotNull(realtime); + assertTrue(realtime.isOpen()); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient live + = builder.beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent", liveOptions)) { + assertTrue(live.isOpen()); + } + try (BetaVoiceAgentsWebSocketSessionClient realtime + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", realtimeOptions)) { + assertTrue(realtime.isOpen()); + } + } + assertEquals(2, requestUris.size()); + assertEquals("/agents/agent/endpoint/protocols/voice/live/sessions", URI.create(requestUris.get(0)).getPath()); + assertTrue(requestUris.get(0).contains("structured_inputs=")); + assertFalse(requestUris.get(0).contains("transport=")); + assertNull(headers.get(0).get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)); + assertNull(headers.get(0).get("x-ms-voice-structured-inputs")); + assertEquals("/agents/agent/endpoint/protocols/voice", URI.create(requestUris.get(1)).getPath()); + assertTrue(requestUris.get(1).contains("transport=websocket")); + assertFalse(requestUris.get(1).contains("structured_inputs=")); + assertEquals("realtime", headers.get(1).get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)); + assertEquals(inputs, headers.get(1).get("x-ms-voice-structured-inputs")); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void typedEventsRoundTripWithoutLosingUnknownFields(boolean async) { + List sent = new CopyOnWriteArrayList<>(); + String audio = "{\"type\":\"session.output_audio.delta\",\"delta\":\"AAA=\",\"future_field\":true}"; + String backend = "{\"type\":\"response.event\",\"event_id\":\"backend-1\"," + + "\"event\":{\"type\":\"response.completed\",\"response\":{\"id\":\"response-1\",\"future_field\":true}}}"; + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, + response) -> response.sendWebsocket((inbound, + outbound) -> outbound.sendString(Flux.concat(Flux.just(STARTED, audio, backend, FUTURE, ERROR), + inbound.receive().asString().doOnNext(sent::add))).then())) + .bindNow(); + ClientEvent command = ClientEvent.ofResponseCreate(ResponseCreateEvent.builder() + .eventId("command-1") + .putAdditionalProperty("future_setting", JsonValue.from(true)) + .build()); + String commandJson = OpenAIJsonHelper.toBinaryData(command).toString(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent") + .block(TIMEOUT); + assertNotNull(session); + try { + assertThrows(NullPointerException.class, () -> session.sendEvent((ClientEvent) null)); + StepVerifier.create(session.sendEvent(command).thenMany(session.receiveEvents())) + .assertNext(event -> assertStartedEvent(event)) + .assertNext(event -> assertAudioEvent(event, audio)) + .assertNext(event -> assertBackendEvent(event, backend)) + .assertNext(event -> assertEventJson(event, FUTURE)) + .assertNext(event -> { + assertTrue(event.isErrorEvent()); + assertEventJson(event, ERROR); + }) + .assertNext(event -> assertEventJson(event, commandJson)) + .thenCancel() + .verify(TIMEOUT); + StepVerifier.create(session.receiveRawEvents()) + .expectError(IllegalStateException.class) + .verify(TIMEOUT); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + assertThrows(NullPointerException.class, () -> session.sendEvent((ClientEvent) null)); + assertThrows(IllegalArgumentException.class, () -> session.receiveEvents(Duration.ZERO)); + Iterator events = session.receiveEvents(TIMEOUT).iterator(); + assertStartedEvent(events.next()); + assertAudioEvent(events.next(), audio); + assertBackendEvent(events.next(), backend); + assertEventJson(events.next(), FUTURE); + ServerEvent error = events.next(); + assertTrue(error.isErrorEvent()); + assertEventJson(error, ERROR); + session.sendEvent(command); + assertEventJson(events.next(), commandJson); + assertThrows(IllegalStateException.class, session::receiveRawEvents); + } + } + assertEquals(Arrays.asList(commandJson), sent); + } + + private static void assertStartedEvent(ServerEvent event) { + assertTrue(event.isSessionStarted()); + assertEquals(JsonValue.from("conversation-1"), + event.asSessionStarted()._additionalProperties().get("conversation_id")); + assertEventJson(event, STARTED); + } + + private static void assertAudioEvent(ServerEvent event, String json) { + assertTrue(event.isSessionOutputAudioDelta()); + assertEquals("AAA=", event.asSessionOutputAudioDelta().delta()); + assertEventJson(event, json); + } + + private static void assertBackendEvent(ServerEvent event, String json) { + assertTrue(event.isResponseEvent()); + assertEquals("backend-1", event.asResponseEvent().eventId()); + assertEventJson(event, json); + } + + private static void assertEventJson(ServerEvent event, String json) { + assertEquals(BinaryData.fromString(json).toObject(Object.class), + OpenAIJsonHelper.toBinaryData(event).toObject(Object.class)); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void handshakeFailuresSurfaceAsAzureExceptions(boolean async) { + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.status(404).send()) + .bindNow(); + if (async) { + StepVerifier + .create(builder().beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient().openWebSocketSession("missing")) + .expectError(ResourceNotFoundException.class) + .verify(TIMEOUT); + } else { + assertThrows(ResourceNotFoundException.class, + () -> builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("missing")); + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void malformedJsonTerminatesReception(boolean async) { + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket( + (inbound, outbound) -> outbound.sendString(Mono.just("[]")).then(inbound.receive().then()))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent") + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveEvents()) + .expectError(IllegalArgumentException.class) + .verify(TIMEOUT); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + assertThrows(IllegalArgumentException.class, () -> session.receiveEvents(TIMEOUT).iterator().hasNext()); + } + } + } + + @Test + public void connectionOptionsValidateBoundsAndCopyAllSettings() { + VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions(); + assertEquals(256, options.getReceiveBufferCapacity()); + assertEquals(32 * 1024 * 1024, options.getMaxMessageSize()); + assertThrows(IllegalArgumentException.class, () -> options.setReceiveBufferCapacity(0)); + assertThrows(IllegalArgumentException.class, () -> options.setReceiveBufferCapacity(65537)); + assertThrows(IllegalArgumentException.class, () -> options.setMaxMessageSize(0)); + assertThrows(IllegalArgumentException.class, () -> options.setHandshakeTimeout(Duration.ZERO)); + assertThrows(IllegalArgumentException.class, () -> options.setCloseTimeout(Duration.ofSeconds(-1))); + options.setReceiveBufferCapacity(1) + .setMaxMessageSize(1024) + .setStoreEnabled(true) + .setHandshakeTimeout(TIMEOUT) + .setCloseTimeout(TIMEOUT) + .setAgentVersionOverride("1") + .setStructuredInputs("{\"name\":\"value\"}"); + VoiceAgentLiveWebSocketConnectionOptions copy = new VoiceAgentLiveWebSocketConnectionOptions(options); + options.setReceiveBufferCapacity(65536).setStoreEnabled(false).setStructuredInputs("{}"); + assertEquals(1, copy.getReceiveBufferCapacity()); + assertEquals(1024, copy.getMaxMessageSize()); + assertEquals(true, copy.isStoreEnabled()); + assertEquals(TIMEOUT, copy.getHandshakeTimeout()); + assertEquals(TIMEOUT, copy.getCloseTimeout()); + assertEquals("1", copy.getAgentVersionOverride()); + assertEquals("{\"name\":\"value\"}", copy.getStructuredInputs()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void throwingMalformedEventCallbackTerminatesTypedReception(boolean async) { + IllegalStateException failure = new IllegalStateException("Malformed event callback failed."); + VoiceAgentLiveWebSocketConnectionOptions options + = new VoiceAgentLiveWebSocketConnectionOptions().setMalformedEventHandler(error -> { + throw failure; + }); + server + = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, + outbound) -> outbound.sendString(Flux.just("not-json", STARTED)).then(inbound.receive().then()))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", options) + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveEvents()) + .expectErrorMatches(error -> error == failure) + .verify(TIMEOUT); + assertFalse(session.isOpen()); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent", options)) { + Iterator events = session.receiveEvents(TIMEOUT).iterator(); + assertEquals(failure, assertThrows(IllegalStateException.class, events::hasNext)); + assertFalse(events.hasNext()); + assertFalse(session.isOpen()); + } + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void peerClosurePreservesEventsAndCloseMetadata(boolean async) { + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, + response) -> response.sendWebsocket((inbound, outbound) -> outbound.sendString(Mono.just(STARTED)) + .then(outbound.sendClose(1000, "finished")))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent") + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveRawEvents().map(BinaryData::toString)) + .expectNext(STARTED) + .expectComplete() + .verify(TIMEOUT); + assertEquals(1000, session.getCloseCode()); + assertEquals("finished", session.getCloseReason()); + assertFalse(session.isOpen()); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent")) { + Iterator events = session.receiveRawEvents(TIMEOUT).iterator(); + assertEquals(STARTED, events.next().toString()); + assertFalse(events.hasNext()); + assertEquals(1000, session.getCloseCode()); + assertEquals("finished", session.getCloseReason()); + assertFalse(session.isOpen()); + } + } + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void malformedEventCallbackCanSkipInvalidJson(boolean async) { + AtomicInteger malformed = new AtomicInteger(); + VoiceAgentLiveWebSocketConnectionOptions options = new VoiceAgentLiveWebSocketConnectionOptions() + .setMalformedEventHandler(error -> malformed.incrementAndGet()); + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket((inbound, + outbound) -> outbound.sendString(Flux.just("[]", "not-json", STARTED)).then(inbound.receive().then()))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", options) + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveEvents()) + .assertNext(VoiceAgentLiveWebSocketTests::assertStartedEvent) + .thenCancel() + .verify(TIMEOUT); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent", options)) { + assertStartedEvent(session.receiveEvents(TIMEOUT).iterator().next()); + } + } + assertEquals(2, malformed.get()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void oversizedEventsFailEvenWhenMalformedCallbackIsConfigured(boolean async) { + AtomicInteger malformed = new AtomicInteger(); + VoiceAgentLiveWebSocketConnectionOptions options + = new VoiceAgentLiveWebSocketConnectionOptions().setMaxMessageSize(32) + .setMalformedEventHandler(error -> malformed.incrementAndGet()); + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, response) -> response.sendWebsocket( + (inbound, outbound) -> outbound.sendString(Mono.just(STARTED)).then(inbound.receive().then()))) + .bindNow(); + if (async) { + BetaVoiceAgentsLiveWebSocketSessionAsyncClient session = builder().beta() + .buildBetaVoiceAgentsLiveWebSocketAsyncClient() + .openWebSocketSession("agent", options) + .block(TIMEOUT); + assertNotNull(session); + try { + StepVerifier.create(session.receiveRawEvents()).expectError().verify(TIMEOUT); + } finally { + session.closeAsync().block(TIMEOUT); + } + } else { + try (BetaVoiceAgentsLiveWebSocketSessionClient session + = builder().beta().buildBetaVoiceAgentsLiveWebSocketClient().openWebSocketSession("agent", options)) { + assertThrows(IllegalArgumentException.class, + () -> session.receiveRawEvents(TIMEOUT).iterator().hasNext()); + } + } + assertEquals(0, malformed.get()); + } + + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void unsupportedHttpSettingsAreRejected(boolean async) { + AgentsClientBuilder builder = new AgentsClientBuilder().endpoint("https://example.com") + .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) + .httpClient(com.azure.core.http.HttpClient.createDefault()); + if (async) { + assertThrows(IllegalStateException.class, + () -> builder.beta().buildBetaVoiceAgentsLiveWebSocketAsyncClient()); + } else { + assertThrows(IllegalStateException.class, () -> builder.beta().buildBetaVoiceAgentsLiveWebSocketClient()); + } + } + + private AgentsClientBuilder builder() { + return new AgentsClientBuilder().endpoint("https://localhost:" + server.port()) + .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) + .configuration(Configuration.NONE); + } + + private void startEchoServer(List sent) { + server = VoiceAgentWebSocketSessionTests.tlsServer() + .host("localhost") + .port(0) + .handle((request, + response) -> response.sendWebsocket((inbound, + outbound) -> outbound.sendString(Flux.concat(Flux.just(STARTED, RESPONSE, FUTURE, ERROR), + inbound.receive().asString().doOnNext(sent::add))).then())) + .bindNow(); + } +} diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentRealtimeLiveTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentRealtimeLiveTests.java index 9b05562145d25..613b92cc46172 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentRealtimeLiveTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentRealtimeLiveTests.java @@ -6,8 +6,8 @@ import com.azure.ai.agents.AgentsAsyncClient; import com.azure.ai.agents.AgentsClient; import com.azure.ai.agents.AgentsClientBuilder; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; import com.azure.ai.agents.models.CreateAgentVersionInput; import com.azure.ai.agents.models.RealtimeClientEvent; import com.azure.ai.agents.models.RealtimeConversationItemCreateEvent; @@ -87,8 +87,8 @@ public void realtimeLive(Scenario scenario) { try { agents.createAgentVersion(agentName, new CreateAgentVersionInput(definition(scenario))); created = true; - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession(agentName)) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession(agentName)) { Turn turn = new Turn(scenario); Iterator events = session.receiveEvents(EVENT_TIMEOUT).iterator(); turn.accept(events.next()).forEach(session::sendEvent); @@ -118,7 +118,7 @@ public void realtimeLiveAsync(Scenario scenario) { .block(EVENT_TIMEOUT); created = true; Turn turn = new Turn(scenario); - Mono.usingWhen(builder.beta().buildBetaVoiceAgentWebSocketAsyncClient().openWebSocketSession(agentName), + Mono.usingWhen(builder.beta().buildBetaVoiceAgentsWebSocketAsyncClient().openWebSocketSession(agentName), session -> session.receiveEvents() .timeout(EVENT_TIMEOUT) .concatMap(event -> Flux.fromIterable(turn.accept(event)) @@ -130,8 +130,8 @@ public void realtimeLiveAsync(Scenario scenario) { .timeout(RESPONSE_TIMEOUT) .doOnNext(ignored -> turn.assertComplete()) .then(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), - BetaVoiceAgentWebSocketSessionAsyncClient::closeAsync).block(Duration.ofSeconds(90)); + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync, (session, error) -> session.closeAsync(), + BetaVoiceAgentsWebSocketSessionAsyncClient::closeAsync).block(Duration.ofSeconds(90)); } finally { if (created) { agents.deleteAgent(agentName).block(EVENT_TIMEOUT); diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyLiveTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyLiveTests.java index d47c877a813b1..b8f62e75272f0 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyLiveTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyLiveTests.java @@ -8,20 +8,18 @@ import com.azure.ai.agents.BetaVoiceAgentsTelephonyClient; import com.azure.ai.agents.ClientTestBase; import com.azure.ai.agents.models.CreateAgentVersionInput; -import com.azure.ai.agents.models.CreateTelephonyCallJobInput; -import com.azure.ai.agents.models.CreateTwilioTelephonyBindingInput; -import com.azure.ai.agents.models.PstnTelephonyTransferDestination; import com.azure.ai.agents.models.TelephonyBinding; import com.azure.ai.agents.models.TelephonyBindingListItem; import com.azure.ai.agents.models.TelephonyCallJobSchedule; import com.azure.ai.agents.models.TelephonyCallRecord; import com.azure.ai.agents.models.TelephonyCallJob; +import com.azure.ai.agents.models.TelephonyCallJobCreate; import com.azure.ai.agents.models.TelephonyCallSummary; -import com.azure.ai.agents.models.TelephonyOutboundDestination; -import com.azure.ai.agents.models.TelephonyOutboundDestinationType; +import com.azure.ai.agents.models.TelephonyPhoneNumber; import com.azure.ai.agents.models.TelephonyProvider; import com.azure.ai.agents.models.TelephonyTransferTarget; import com.azure.ai.agents.models.TelephonyTransferTargets; +import com.azure.ai.agents.models.TwilioTelephonyBinding; import com.azure.ai.agents.models.UpdateTelephonyBindingInput; import com.azure.ai.agents.models.VoiceAgentAudioConfiguration; import com.azure.ai.agents.models.VoiceAgentAudioOutputConfiguration; @@ -53,6 +51,7 @@ import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -92,8 +91,8 @@ protected List getAdditionalTestProxyExcludedHeaders() { } /** - * Removes the common {@code $..source} sanitizer so the telephony-specific sanitizer can preserve a valid E.164 - * placeholder for request matching and response assertions during playback. + * Removes the common {@code $..source} sanitizer so the telephony-specific sanitizer can preserve the source + * address object and a valid E.164 placeholder for request matching and response assertions during playback. */ @Override protected List getAdditionalTestProxySanitizersToRemove() { @@ -124,7 +123,7 @@ public void bindingLifecycleLive(HttpClient httpClient, AgentsServiceVersion ser new CreateAgentVersionInput(definition(model, "Greet the caller briefly, then say goodbye."))); agentCreated = true; TelephonyBinding binding = telephony.createTelephonyBinding(agentName, - new CreateTwilioTelephonyBindingInput(connection, number).setLabel("Java SDK live test")); + new TwilioTelephonyBinding(connection, number).setLabel("Java SDK live test")); bindingId = binding.getId(); TelephonyBindingListItem listedBinding = findBinding(telephony, agentName, binding.getId()); assertNotNull(listedBinding.getETag()); @@ -188,7 +187,7 @@ public void twilioBindingAndOutboundCallLive(HttpClient httpClient, AgentsServic outboundAgentCreated = true; TelephonyBinding binding = telephony.createTelephonyBinding(inboundAgent, - new CreateTwilioTelephonyBindingInput(connection1, number1).setLabel("Java SDK live test")); + new TwilioTelephonyBinding(connection1, number1).setLabel("Java SDK live test")); inboundBindingId = binding.getId(); assertNotNull(binding.getId()); assertEquals(TelephonyProvider.TWILIO, binding.getProvider()); @@ -200,22 +199,21 @@ public void twilioBindingAndOutboundCallLive(HttpClient httpClient, AgentsServic = initialTargetsResponse.getValue().toObject(TelephonyTransferTargets.class); assertTrue(initialTargets.getTransferTargets().isEmpty()); TelephonyTransferTarget transferTarget = new TelephonyTransferTarget("test_number_2", - "Java SDK live test target", new PstnTelephonyTransferDestination(number2)); + "Java SDK live test target", new TelephonyPhoneNumber(number2)); TelephonyTransferTargets replacedTargets = telephony.replaceTelephonyTransferTargets(inboundAgent, requireEtag(initialTargetsResponse, "telephony transfer targets"), Collections.singletonList(transferTarget)); assertEquals(1, replacedTargets.getTransferTargets().size()); - CreateTelephonyCallJobInput request = new CreateTelephonyCallJobInput( - new TelephonyOutboundDestination(TelephonyOutboundDestinationType.PHONE_NUMBER, number1), connection2, - number2).setPurpose("Java SDK live telephony validation"); + TelephonyCallJobCreate request = new TelephonyCallJobCreate(new TelephonyPhoneNumber(number1), connection2, + new TelephonyPhoneNumber(number2)).setPurpose("Java SDK live telephony validation"); TelephonyCallJob job = telephony.createTelephonyCallJob(outboundAgent, testResourceNamer.randomUuid(), request); callJobId = job.getId(); assertNotNull(callJobId); assertEquals(outboundAgent, job.getAgentName()); assertEquals(connection2, job.getConnectionName()); - assertEquals(number2, job.getSource()); + assertEquals(number2, assertInstanceOf(TelephonyPhoneNumber.class, job.getSource()).getValue()); TelephonyCallSummary inboundCall = waitForInboundCall(telephony, inboundAgent); inboundCallId = inboundCall.getId(); @@ -234,9 +232,8 @@ public void twilioBindingAndOutboundCallLive(HttpClient httpClient, AgentsServic waitForDispatchedCallJob(telephony, outboundAgent, callJobId); OffsetDateTime notBefore = testResourceNamer.now().plusMinutes(10); - CreateTelephonyCallJobInput scheduledRequest = new CreateTelephonyCallJobInput( - new TelephonyOutboundDestination(TelephonyOutboundDestinationType.PHONE_NUMBER, number1), connection2, - number2).setPurpose("Java SDK live cancellation validation") + TelephonyCallJobCreate scheduledRequest = new TelephonyCallJobCreate(new TelephonyPhoneNumber(number1), + connection2, new TelephonyPhoneNumber(number2)).setPurpose("Java SDK live cancellation validation") .setSchedule( new TelephonyCallJobSchedule().setNotBefore(notBefore).setExpiresAt(notBefore.plusMinutes(10))); TelephonyCallJob scheduledJob @@ -338,7 +335,6 @@ private void addPhoneSanitizers(String value, String sanitizedValue) { interceptorManager.addSanitizers(Arrays.asList( new TestProxySanitizer("$..phone_number", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), new TestProxySanitizer("$..identifier", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), - new TestProxySanitizer("$..source", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), new TestProxySanitizer("$..caller_number", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), new TestProxySanitizer("$..provider_number", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), new TestProxySanitizer("$..value", null, sanitizedValue, TestProxySanitizerType.BODY_KEY), diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyTests.java index 1505651aa71d7..6b70d057af7a4 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentTelephonyTests.java @@ -6,18 +6,19 @@ import com.azure.ai.agents.AgentsClientBuilder; import com.azure.ai.agents.BetaVoiceAgentsTelephonyAsyncClient; import com.azure.ai.agents.BetaVoiceAgentsTelephonyClient; -import com.azure.ai.agents.models.CreateTelephonyCallJobInput; -import com.azure.ai.agents.models.CreateTwilioTelephonyBindingInput; +import com.azure.ai.agents.models.TelephonyAddressType; import com.azure.ai.agents.models.TelephonyBinding; import com.azure.ai.agents.models.TelephonyBindingListItem; -import com.azure.ai.agents.models.TelephonyBindingStatus; import com.azure.ai.agents.models.TelephonyCallRecord; import com.azure.ai.agents.models.TelephonyCallJob; +import com.azure.ai.agents.models.TelephonyCallJobCreate; import com.azure.ai.agents.models.TelephonyCallJobStatus; import com.azure.ai.agents.models.TelephonyCallSummary; -import com.azure.ai.agents.models.TelephonyOutboundDestination; -import com.azure.ai.agents.models.TelephonyOutboundDestinationType; +import com.azure.ai.agents.models.TelephonyFixedIntervalRetryPolicy; +import com.azure.ai.agents.models.TelephonyPhoneNumber; +import com.azure.ai.agents.models.TelephonyProvider; import com.azure.ai.agents.models.TelephonyTransferTargets; +import com.azure.ai.agents.models.TwilioTelephonyBinding; import com.azure.ai.agents.models.UpdateTelephonyBindingInput; import com.azure.core.exception.HttpResponseException; import com.azure.core.exception.ResourceNotFoundException; @@ -58,6 +59,7 @@ public class VoiceAgentTelephonyTests { private static final String AGENT = "voice-telephony-test"; private static final String MISSING = "nonexistent-id"; private static final String ROOT = "/agents/" + AGENT + "/telephony"; + private static final String CALL_JOBS = "/agents/" + AGENT + "/telephony_call_jobs"; private static final String CONNECTION_1 = "twilio-sdk-testing-1"; private static final String CONNECTION_2 = "twilio-sdk-testing-2"; private static final String NUMBER_1 = "+13853864628"; @@ -68,7 +70,7 @@ public class VoiceAgentTelephonyTests { private static final String EMPTY_TARGETS = "{\"transfer_targets\":[]}"; private static final String TARGETS = "{\"transfer_targets\":[{\"name\":\"sales_desk\"," + "\"description\":\"Transfers to the sales desk for pricing questions.\"," - + "\"destination\":{\"kind\":\"pstn\",\"value\":\"+14255550123\"}}]}"; + + "\"destination\":{\"type\":\"phone_number\",\"value\":\"+14255550123\"}}]}"; @ParameterizedTest @ValueSource(booleans = { false, true }) @@ -76,45 +78,49 @@ public void createsTwilioBindingAndOutboundCallJob(boolean async) { String bindingRequest = "{\"connection_name\":\"" + CONNECTION_1 + "\",\"label\":\"Java SDK test\"," + "\"phone_number\":\"" + NUMBER_1 + "\",\"provider\":\"twilio\"}"; String bindingResponse = "{\"provider\":\"twilio\",\"id\":\"binding-1\",\"label\":\"Java SDK test\"," - + "\"status\":\"active\",\"incoming_call_url\":\"https://example.test/incoming\"," - + "\"connection_name\":\"" + CONNECTION_1 + "\",\"phone_number\":\"" + NUMBER_1 + "\"}"; + + "\"incoming_call_url\":\"https://example.test/incoming\"," + "\"connection_name\":\"" + CONNECTION_1 + + "\",\"phone_number\":\"" + NUMBER_1 + "\"}"; String jobRequest = "{\"destination\":{\"type\":\"phone_number\",\"value\":\"" + NUMBER_1 + "\"}," - + "\"connection_name\":\"" + CONNECTION_2 + "\",\"source\":\"" + NUMBER_2 + "\"," - + "\"purpose\":\"Java SDK telephony validation\"}"; + + "\"connection_name\":\"" + CONNECTION_2 + "\"," + "\"source\":{\"type\":\"phone_number\",\"value\":\"" + + NUMBER_2 + "\"}," + "\"purpose\":\"Java SDK telephony validation\"}"; String jobResponse = "{\"destination\":{\"type\":\"phone_number\",\"value\":\"" + NUMBER_1 + "\"}," - + "\"connection_name\":\"" + CONNECTION_2 + "\",\"source\":\"" + NUMBER_2 + "\"," - + "\"purpose\":\"Java SDK telephony validation\",\"id\":\"job-1\"," + + "\"connection_name\":\"" + CONNECTION_2 + "\"," + "\"source\":{\"type\":\"phone_number\",\"value\":\"" + + NUMBER_2 + "\"}," + "\"purpose\":\"Java SDK telephony validation\",\"id\":\"job-1\"," + "\"object\":\"telephony.call_job\",\"agent_name\":\"" + AGENT + "\",\"status\":\"accepted\"," - + "\"retry_policy\":{\"max_attempts\":1},\"attempt_count\":0,\"revision\":1," - + "\"created_at\":1,\"updated_at\":1}"; + + "\"retry_policy\":{\"type\":\"fixed_interval\",\"max_attempts\":1,\"interval\":0}," + + "\"attempt_count\":0,\"revision\":1," + "\"created_at\":1,\"updated_at\":1}"; String cancelledJobResponse = jobResponse.replace("\"status\":\"accepted\"", "\"status\":\"cancelled\"") .replace("\"revision\":1", "\"revision\":2"); ScriptedTransport transport = new ScriptedTransport(async); transport.expect(HttpMethod.POST, ROOT + "/bindings", bindingRequest, 201, bindingResponse); - transport.expect(HttpMethod.POST, ROOT + "/call_jobs", jobRequest, - header(IDEMPOTENCY_KEY, "offline-idempotency-key"), 202, jobResponse, new HttpHeaders()); - transport.expect(HttpMethod.GET, ROOT + "/call_jobs/job-1", null, 200, jobResponse); - transport.expect(HttpMethod.POST, ROOT + "/call_jobs/job-1:cancel", null, header(HttpHeaderName.IF_MATCH, "1"), - 200, cancelledJobResponse, new HttpHeaders()); + transport.expect(HttpMethod.POST, CALL_JOBS, jobRequest, header(IDEMPOTENCY_KEY, "offline-idempotency-key"), + 202, jobResponse, new HttpHeaders()); + transport.expect(HttpMethod.GET, CALL_JOBS + "/job-1", null, 200, jobResponse); + transport.expect(HttpMethod.POST, CALL_JOBS + "/job-1:cancel", null, header(HttpHeaderName.IF_MATCH, "1"), 200, + cancelledJobResponse, new HttpHeaders()); AgentsClientBuilder builder = builder(transport); BetaVoiceAgentsTelephonyClient syncClient = builder.beta().buildBetaVoiceAgentsTelephonyClient(); BetaVoiceAgentsTelephonyAsyncClient asyncClient = builder.beta().buildBetaVoiceAgentsTelephonyAsyncClient(); - CreateTwilioTelephonyBindingInput bindingRequestModel - = new CreateTwilioTelephonyBindingInput(CONNECTION_1, NUMBER_1).setLabel("Java SDK test"); + TwilioTelephonyBinding bindingRequestModel + = new TwilioTelephonyBinding(CONNECTION_1, NUMBER_1).setLabel("Java SDK test"); TelephonyBinding binding = call(async, () -> syncClient.createTelephonyBinding(AGENT, bindingRequestModel), () -> asyncClient.createTelephonyBinding(AGENT, bindingRequestModel)); assertEquals("binding-1", binding.getId()); - assertEquals(TelephonyBindingStatus.ACTIVE, binding.getStatus()); + assertEquals(TelephonyProvider.TWILIO, binding.getProvider()); + assertEquals(NUMBER_1, assertInstanceOf(TwilioTelephonyBinding.class, binding).getPhoneNumber()); - CreateTelephonyCallJobInput jobRequestModel = new CreateTelephonyCallJobInput( - new TelephonyOutboundDestination(TelephonyOutboundDestinationType.PHONE_NUMBER, NUMBER_1), CONNECTION_2, - NUMBER_2).setPurpose("Java SDK telephony validation"); + TelephonyCallJobCreate jobRequestModel = new TelephonyCallJobCreate(new TelephonyPhoneNumber(NUMBER_1), + CONNECTION_2, new TelephonyPhoneNumber(NUMBER_2)).setPurpose("Java SDK telephony validation"); TelephonyCallJob job = call(async, () -> syncClient.createTelephonyCallJob(AGENT, "offline-idempotency-key", jobRequestModel), () -> asyncClient.createTelephonyCallJob(AGENT, "offline-idempotency-key", jobRequestModel)); assertEquals("job-1", job.getId()); assertEquals(TelephonyCallJobStatus.ACCEPTED, job.getStatus()); + assertEquals(NUMBER_1, assertInstanceOf(TelephonyPhoneNumber.class, job.getDestination()).getValue()); + assertEquals(NUMBER_2, assertInstanceOf(TelephonyPhoneNumber.class, job.getSource()).getValue()); + assertEquals(Duration.ZERO, + assertInstanceOf(TelephonyFixedIntervalRetryPolicy.class, job.getRetryPolicy()).getInterval()); assertEquals(1L, job.getRevision()); assertEquals("job-1", call(async, () -> syncClient.getTelephonyCallJob(AGENT, "job-1"), () -> asyncClient.getTelephonyCallJob(AGENT, "job-1")).getId()); @@ -130,8 +136,8 @@ public void createsTwilioBindingAndOutboundCallJob(boolean async) { public void bindingTransferTargetAndCallLifecycle(boolean async) { String bindingPath = ROOT + "/bindings/binding-1"; String binding = "{\"provider\":\"twilio\",\"id\":\"binding-1\",\"label\":\"Java SDK test\"," - + "\"status\":\"active\",\"incoming_call_url\":\"https://example.test/incoming\"," - + "\"connection_name\":\"" + CONNECTION_1 + "\",\"phone_number\":\"" + NUMBER_1 + "\"}"; + + "\"incoming_call_url\":\"https://example.test/incoming\"," + "\"connection_name\":\"" + CONNECTION_1 + + "\",\"phone_number\":\"" + NUMBER_1 + "\"}"; String listedBinding = binding.substring(0, binding.length() - 1) + ",\"etag\":\"binding-etag\"}"; String updatedBinding = binding.replace("Java SDK test", "Updated Java SDK test"); String callPath = ROOT + "/calls/call-1"; @@ -141,7 +147,7 @@ public void bindingTransferTargetAndCallLifecycle(boolean async) { transport.expect(HttpMethod.GET, bindingPath, null, 200, binding); transport.expect(HttpMethod.GET, ROOT + "/bindings", null, 200, "{\"data\":[" + listedBinding + "],\"has_more\":false}"); - transport.expect(HttpMethod.PATCH, bindingPath, "{\"status\":\"active\",\"label\":\"Updated Java SDK test\"}", + transport.expect(HttpMethod.PATCH, bindingPath, "{\"label\":\"Updated Java SDK test\"}", header(HttpHeaderName.IF_MATCH, "*"), 200, updatedBinding, new HttpHeaders()); transport.expect(HttpMethod.GET, ROOT + "/transfer_targets", null, Collections.emptyMap(), 200, EMPTY_TARGETS, new HttpHeaders().set(HttpHeaderName.ETAG, "targets-etag")); @@ -166,8 +172,7 @@ public void bindingTransferTargetAndCallLifecycle(boolean async) { : syncClient.listTelephonyBindings(AGENT).iterator().next(); assertNotNull(listed); assertEquals("binding-etag", listed.getETag()); - UpdateTelephonyBindingInput update = new UpdateTelephonyBindingInput().setStatus(TelephonyBindingStatus.ACTIVE) - .setLabel("Updated Java SDK test"); + UpdateTelephonyBindingInput update = new UpdateTelephonyBindingInput().setLabel("Updated Java SDK test"); assertEquals("Updated Java SDK test", call(async, () -> syncClient.updateTelephonyBinding(AGENT, "binding-1", "*", update), () -> asyncClient.updateTelephonyBinding(AGENT, "binding-1", "*", update)).getLabel()); @@ -213,7 +218,7 @@ public void bindingsAndTransferTargets(boolean async) { header(HttpHeaderName.IF_MATCH, "targets-etag-2"), 200, EMPTY_TARGETS, new HttpHeaders().set(HttpHeaderName.ETAG, "targets-etag-3")); transport.notFound(HttpMethod.GET, ROOT + "/bindings/" + MISSING, null); - transport.notFound(HttpMethod.PATCH, ROOT + "/bindings/" + MISSING, "{\"status\":\"suspended\"}"); + transport.notFound(HttpMethod.PATCH, ROOT + "/bindings/" + MISSING, "{\"label\":\"Updated Java SDK test\"}"); transport.notFound(HttpMethod.DELETE, ROOT + "/bindings/" + MISSING, null); AgentsClientBuilder builder = builder(transport); BetaVoiceAgentsTelephonyClient syncClient = builder.beta().buildBetaVoiceAgentsTelephonyClient(); @@ -238,8 +243,7 @@ public void bindingsAndTransferTargets(boolean async) { .isEmpty()); assertNotFound(() -> call(async, () -> syncClient.getTelephonyBinding(AGENT, MISSING), () -> asyncClient.getTelephonyBinding(AGENT, MISSING)), true); - UpdateTelephonyBindingInput update - = new UpdateTelephonyBindingInput().setStatus(TelephonyBindingStatus.SUSPENDED); + UpdateTelephonyBindingInput update = new UpdateTelephonyBindingInput().setLabel("Updated Java SDK test"); assertNotFound(() -> call(async, () -> syncClient.updateTelephonyBinding(AGENT, MISSING, null, update), () -> asyncClient.updateTelephonyBinding(AGENT, MISSING, null, update)), true); assertNotFound(() -> call(async, () -> { @@ -306,8 +310,8 @@ public void generatedAudioNotFound(boolean async) { @ValueSource(booleans = { false, true }) public void callJobNotFound(boolean async) { ScriptedTransport transport = new ScriptedTransport(async); - transport.notFound(HttpMethod.GET, ROOT + "/call_jobs/" + MISSING, null); - transport.notFound(HttpMethod.POST, ROOT + "/call_jobs/" + MISSING + ":cancel", null); + transport.notFound(HttpMethod.GET, CALL_JOBS + "/" + MISSING, null); + transport.notFound(HttpMethod.POST, CALL_JOBS + "/" + MISSING + ":cancel", null); AgentsClientBuilder builder = builder(transport); BetaVoiceAgentsTelephonyClient syncClient = builder.beta().buildBetaVoiceAgentsTelephonyClient(); BetaVoiceAgentsTelephonyAsyncClient asyncClient = builder.beta().buildBetaVoiceAgentsTelephonyAsyncClient(); @@ -322,7 +326,10 @@ private static void assertTargets(TelephonyTransferTargets targets) { assertNotNull(targets); assertEquals(1, targets.getTransferTargets().size()); assertEquals("sales_desk", targets.getTransferTargets().get(0).getName()); - assertEquals("pstn", targets.getTransferTargets().get(0).getDestination().getKind().toString()); + assertEquals(TelephonyAddressType.PHONE_NUMBER, targets.getTransferTargets().get(0).getDestination().getType()); + assertEquals("+14255550123", + assertInstanceOf(TelephonyPhoneNumber.class, targets.getTransferTargets().get(0).getDestination()) + .getValue()); } private static Map header(HttpHeaderName name, String value) { diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionAsyncTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionAsyncTests.java index 225f80c03e38b..0e7fa4bfa9d31 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionAsyncTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionAsyncTests.java @@ -4,8 +4,8 @@ package com.azure.ai.agents.voice; import com.azure.ai.agents.AgentsClientBuilder; -import com.azure.ai.agents.BetaVoiceAgentWebSocketAsyncClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketAsyncClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionAsyncClient; import com.azure.ai.agents.implementation.realtime.VoiceAgentWebSocketHttpResponse; import com.azure.ai.agents.models.RawRealtimeServerEvent; import com.azure.ai.agents.models.RealtimeResponseCreateEvent; @@ -51,6 +51,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; import org.junit.jupiter.api.parallel.ResourceLock; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -66,6 +67,7 @@ import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; import static org.junit.jupiter.api.Assertions.assertTrue; +@Isolated("Virtual-time tests replace the global Reactor schedulers") @ResourceLock("voice-agent-websocket-tls") public class VoiceAgentWebSocketSessionAsyncTests { private DisposableServer server; @@ -91,8 +93,8 @@ public void handshakeUsesSdkManagedProtocolValues() { new Header("Foundry-Features", "override-feature"), new Header("Sec-WebSocket-Protocol", "override-protocol")))); - BetaVoiceAgentWebSocketSessionAsyncClient session = builder.beta() - .buildBetaVoiceAgentWebSocketAsyncClient() + BetaVoiceAgentsWebSocketSessionAsyncClient session = builder.beta() + .buildBetaVoiceAgentsWebSocketAsyncClient() .openWebSocketSession("agent name") .block(Duration.ofSeconds(5)); session.closeAsync().block(Duration.ofSeconds(5)); @@ -131,8 +133,8 @@ public void handshakeUsesHttpLogApplicationIdFallback() { .httpLogOptions(new HttpLogOptions().setApplicationId("log-app")) .clientOptions(new ClientOptions()); - BetaVoiceAgentWebSocketSessionAsyncClient session = builder.beta() - .buildBetaVoiceAgentWebSocketAsyncClient() + BetaVoiceAgentsWebSocketSessionAsyncClient session = builder.beta() + .buildBetaVoiceAgentsWebSocketAsyncClient() .openWebSocketSession("agent") .block(Duration.ofSeconds(5)); session.closeAsync().block(Duration.ofSeconds(5)); @@ -166,8 +168,8 @@ public void typedStringAndMappingSendsRejectInvalidJson() { AgentsClientBuilder builder = builder(server.port()); String raw = "{\"type\": \"response.create\"}"; BinaryData mapping = BinaryData.fromObject(Collections.singletonMap("type", "response.cancel")); - BetaVoiceAgentWebSocketSessionAsyncClient session = builder.beta() - .buildBetaVoiceAgentWebSocketAsyncClient() + BetaVoiceAgentsWebSocketSessionAsyncClient session = builder.beta() + .buildBetaVoiceAgentsWebSocketAsyncClient() .openWebSocketSession("agent", tlsOptions()) .block(Duration.ofSeconds(5)); try { @@ -194,7 +196,7 @@ public void pingPongFramesAreNotApplicationEvents() { new TextWebSocketFrame("{\"type\":\"session.created\",\"session\":{}}"), new TextWebSocketFrame("{\"type\":\"future.event\",\"foo\":\"bar\"}"))); server = frameWebSocketServer(frames, false); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(Duration.ofSeconds(5)); List events; try { @@ -217,7 +219,7 @@ public void malformedEventsCanBeReportedAndSkipped() { new TextWebSocketFrame(warningJson()))), true); VoiceAgentWebSocketConnectionOptions options = tlsOptions().setMalformedEventHandler(error -> failures.incrementAndGet()); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", options).block(Duration.ofSeconds(5)); StepVerifier.create(session.receiveEvents()) .assertNext(this::assertWarningEvent) @@ -234,7 +236,7 @@ public void boundedQueuesHonorOverflowPolicies() { .map(index -> new TextWebSocketFrame("{\"type\":\"future.event\",\"index\":" + index + "}")), true); VoiceAgentWebSocketConnectionOptions options = tlsOptions().setReceiveBufferCapacity(2).setOverflowStrategy(strategy); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", options).block(Duration.ofSeconds(5)); boolean overflowError = strategy == VoiceAgentWebSocketOverflowStrategy.ERROR; List received = new ArrayList<>(); @@ -271,7 +273,7 @@ public void messageSizeLimitCannotBeBypassedByRecoveryHandler() { VoiceAgentWebSocketConnectionOptions options = tlsOptions().setMaxMessageSize(16).setMalformedEventHandler(error -> recovered.set(true)); StepVerifier.create(createAsyncClient(server.port()).openWebSocketSession("agent", options) - .flatMapMany(BetaVoiceAgentWebSocketSessionAsyncClient::receiveEvents)).expectError().verify(); + .flatMapMany(BetaVoiceAgentsWebSocketSessionAsyncClient::receiveEvents)).expectError().verify(); assertFalse(recovered.get()); } @@ -282,7 +284,7 @@ public void rawEventRoundTripsAndOptionsValidateBounds() throws Exception { RawRealtimeServerEvent copy = BinaryData.fromObject(event).toObject(RawRealtimeServerEvent.class); assertEquals(payload.toObject(Map.class), copy.getRawEvent().toObject(Map.class)); server = oneShotWebSocketServer("{\"type\":42,\"value\":1}"); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(Duration.ofSeconds(5)); try { StepVerifier.create(session.receiveEvents()) @@ -312,7 +314,7 @@ public void insecureEndpointsAreRejectedBeforeAuthentication() { "https://example.com/#fragment" }) { AgentsClientBuilder clientBuilder = new AgentsClientBuilder().endpoint(endpoint).credential(credential); StepVerifier - .create(clientBuilder.beta().buildBetaVoiceAgentWebSocketAsyncClient().openWebSocketSession("agent")) + .create(clientBuilder.beta().buildBetaVoiceAgentsWebSocketAsyncClient().openWebSocketSession("agent")) .expectError(IllegalArgumentException.class) .verify(); } @@ -330,7 +332,7 @@ public void rawEventsUseCustomizedTlsTransport() { WebsocketServerSpec.builder().protocols("realtime").build())) .bindNow(); BinaryData payload = BinaryData.fromString("{\"type\":\"future.event\",\"value\":42}"); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(Duration.ofSeconds(5)); StepVerifier.create(session.sendEvent(BinaryData.fromString("[]"))) .expectError(IllegalArgumentException.class) @@ -348,7 +350,7 @@ public void rawEventsUseCustomizedTlsTransport() { public void customCloseFrame() { server = startServer(new CopyOnWriteArrayList<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), false); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(Duration.ofSeconds(5)); assertNotNull(session); StepVerifier.create(session.closeAsync(1006, "invalid")).expectError(IllegalArgumentException.class).verify(); @@ -374,18 +376,18 @@ public void asyncSessionNegotiatesHandshakeAndExchangesTypedEvents() { }; VoiceAgentWebSocketConnectionOptions options = tlsOptions().setStoreEnabled(true).setAgentVersionOverride("version 2"); - BetaVoiceAgentWebSocketAsyncClient client + BetaVoiceAgentsWebSocketAsyncClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .clientOptions(new ClientOptions().setApplicationId("test-app") .setHeaders(Collections.singletonList(new Header("X-Test-Header", "test-value")))) .beta() - .buildBetaVoiceAgentWebSocketAsyncClient(); - Mono sessionMono + .buildBetaVoiceAgentsWebSocketAsyncClient(); + Mono sessionMono = client.openWebSocketSession("agent name", options); options.setStoreEnabled(false).setAgentVersionOverride("mutated"); - BetaVoiceAgentWebSocketSessionAsyncClient session = sessionMono.block(); + BetaVoiceAgentsWebSocketSessionAsyncClient session = sessionMono.block(); assertTrue(session.isOpen()); StepVerifier.create(session.receiveEvents().take(4)) .then(() -> session.sendText("hello").block()) @@ -426,12 +428,12 @@ public void tokenFailureOccursBeforeNetworkAccess() { return response.send(); }).bindNow(); TokenCredential credential = request -> Mono.error(new IllegalStateException("token unavailable")); - BetaVoiceAgentWebSocketAsyncClient client + BetaVoiceAgentsWebSocketAsyncClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketAsyncClient(); + .buildBetaVoiceAgentsWebSocketAsyncClient(); StepVerifier.create(client.openWebSocketSession("agent", tlsOptions())) .expectErrorMatches( error -> error instanceof IllegalStateException && error.getMessage().contains("token unavailable")) @@ -445,12 +447,12 @@ public void tokenAcquisitionDoesNotUseHandshakeTimeout() { new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), false); TokenCredential credential = request -> Mono.delay(Duration.ofMillis(1500)) .map(ignored -> new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketAsyncClient client + BetaVoiceAgentsWebSocketAsyncClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketAsyncClient(); + .buildBetaVoiceAgentsWebSocketAsyncClient(); VoiceAgentWebSocketConnectionOptions options = tlsOptions().setHandshakeTimeout(Duration.ofSeconds(1)); StepVerifier.withVirtualTime(() -> client.openWebSocketSession("agent", options).flatMap(session -> { assertTrue(session.isOpen()); @@ -488,11 +490,11 @@ public void cancellingAsyncConnectCancelsTokenRequest() { AtomicBoolean tokenRequestCancelled = new AtomicBoolean(); TokenCredential credential = request -> Mono.never().doOnCancel(() -> tokenRequestCancelled.set(true)); - BetaVoiceAgentWebSocketAsyncClient client = new AgentsClientBuilder().endpoint("https://example.com") + BetaVoiceAgentsWebSocketAsyncClient client = new AgentsClientBuilder().endpoint("https://example.com") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketAsyncClient(); + .buildBetaVoiceAgentsWebSocketAsyncClient(); StepVerifier.create(client.openWebSocketSession("agent", tlsOptions())).thenCancel().verify(); assertTrue(tokenRequestCancelled.get()); } @@ -500,7 +502,7 @@ public void cancellingAsyncConnectCancelsTokenRequest() { @Test public void unknownEventFallsBackToRealtimeServerEvent() { server = oneShotWebSocketServer("{\"type\":\"future.event\",\"value\":42}"); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(); StepVerifier.create(session.receiveEvents()).assertNext(event -> { assertEquals("future.event", event.getType().toString()); @@ -516,7 +518,7 @@ public void fragmentedTextFrameIsAggregated() { int split = message.length() / 2; server = frameWebSocketServer(Flux.just(new TextWebSocketFrame(false, 0, message.substring(0, split)), new ContinuationWebSocketFrame(true, 0, message.substring(split))), true); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(); StepVerifier.create(session.receiveEvents()).assertNext(this::assertWarningEvent).verifyComplete(); session.close(); @@ -526,7 +528,7 @@ public void fragmentedTextFrameIsAggregated() { public void binaryJsonFrameIsParsed() { server = frameWebSocketServer( Mono.just(new BinaryWebSocketFrame(Unpooled.copiedBuffer(warningJson(), StandardCharsets.UTF_8))), true); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(); StepVerifier.create(session.receiveEvents()).assertNext(this::assertWarningEvent).verifyComplete(); session.close(); @@ -535,7 +537,7 @@ public void binaryJsonFrameIsParsed() { @Test public void malformedJsonTerminatesReceiveStream() { server = oneShotWebSocketServer("{not-json"); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(); StepVerifier.create(session.receiveEvents()).expectError().verify(); assertFalse(session.isOpen()); @@ -545,7 +547,7 @@ public void malformedJsonTerminatesReceiveStream() { public void closeIsIdempotentAndSendAfterCloseFails() { server = startServer(new CopyOnWriteArrayList<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), false); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("agent", tlsOptions()).block(); StepVerifier.create(session.closeAsync().then(session.closeAsync())).verifyComplete(); StepVerifier.create(session.sendText("after close")) @@ -557,7 +559,7 @@ public void closeIsIdempotentAndSendAfterCloseFails() { @Test public void secureSessionUsesWssAndReceivesTypedEvent() throws Exception { server = oneShotWebSocketServer(warningJson()); - BetaVoiceAgentWebSocketSessionAsyncClient session + BetaVoiceAgentsWebSocketSessionAsyncClient session = createAsyncClient(server.port()).openWebSocketSession("secure-agent", tlsOptions()) .block(Duration.ofSeconds(5)); assertEquals("wss", URI.create(session.getEndpoint()).getScheme()); @@ -570,8 +572,8 @@ private AgentsClientBuilder builder(int port) { .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))); } - private BetaVoiceAgentWebSocketAsyncClient createAsyncClient(int port) { - return builder(port).configuration(Configuration.NONE).beta().buildBetaVoiceAgentWebSocketAsyncClient(); + private BetaVoiceAgentsWebSocketAsyncClient createAsyncClient(int port) { + return builder(port).configuration(Configuration.NONE).beta().buildBetaVoiceAgentsWebSocketAsyncClient(); } private static VoiceAgentWebSocketConnectionOptions tlsOptions() { diff --git a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionTests.java b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionTests.java index b4acb9796b16a..e7d60fc6d7744 100644 --- a/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionTests.java +++ b/sdk/ai/azure-ai-agents/src/test/java/com/azure/ai/agents/voice/VoiceAgentWebSocketSessionTests.java @@ -4,8 +4,8 @@ package com.azure.ai.agents.voice; import com.azure.ai.agents.AgentsClientBuilder; -import com.azure.ai.agents.BetaVoiceAgentWebSocketClient; -import com.azure.ai.agents.BetaVoiceAgentWebSocketSessionClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketClient; +import com.azure.ai.agents.BetaVoiceAgentsWebSocketSessionClient; import com.azure.ai.agents.models.RawRealtimeServerEvent; import com.azure.ai.agents.models.RealtimeResponseCreateEvent; import com.azure.ai.agents.models.RealtimeSessionCreatedEvent; @@ -111,8 +111,8 @@ public void handshakeUsesSdkManagedProtocolValues() { new Header("Foundry-Features", "override-feature"), new Header("Sec-WebSocket-Protocol", "override-protocol")))); - BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent name"); + BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent name"); session.close(); assertFalse(session.isOpen()); @@ -149,8 +149,8 @@ public void handshakeUsesHttpLogApplicationIdFallback() { .httpLogOptions(new HttpLogOptions().setApplicationId("log-app")) .clientOptions(new ClientOptions()); - BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent"); + BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent"); session.close(); assertTrue(userAgent.get().startsWith("log-app azsdk-java-azure-ai-agents/"), userAgent.get()); @@ -167,8 +167,8 @@ public void typedStringAndMappingSendsRejectInvalidJson() { .configuration(Configuration.NONE); String raw = "{\"type\": \"response.create\"}"; BinaryData mapping = BinaryData.fromObject(Collections.singletonMap("type", "response.cancel")); - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", tlsOptions())) { assertThrows(IllegalArgumentException.class, () -> session.sendEvent(BinaryData.fromString("not valid json"))); session.sendEvent(new RealtimeResponseCreateEvent()); @@ -200,8 +200,8 @@ public void pingPongFramesAreNotApplicationEvents() { .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) .configuration(Configuration.NONE); List events = new ArrayList<>(); - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", tlsOptions())) { Iterator iterator = session.receiveEvents(Duration.ofSeconds(5)).iterator(); events.add(iterator.next()); events.add(iterator.next()); @@ -224,8 +224,8 @@ public void malformedEventsCanBeReportedAndSkipped() { AgentsClientBuilder builder = new AgentsClientBuilder().endpoint("https://localhost:" + server.port()) .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) .configuration(Configuration.NONE); - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", options)) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", options)) { Iterator events = session.receiveEvents(Duration.ofSeconds(5)).iterator(); assertWarningEvent(events.next()); assertWarningEvent(events.next()); @@ -246,8 +246,8 @@ public void boundedQueuesHonorOverflowPolicies() { .configuration(Configuration.NONE); List received = new ArrayList<>(); boolean overflowError = strategy == VoiceAgentWebSocketOverflowStrategy.ERROR; - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", options)) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", options)) { assertTimeoutPreemptively(Duration.ofSeconds(5), () -> { while (session.isOpen()) { Thread.yield(); @@ -282,8 +282,8 @@ public void messageSizeLimitCannotBeBypassedByRecoveryHandler() { .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) .configuration(Configuration.NONE); assertThrows(RuntimeException.class, () -> { - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", options)) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", options)) { session.receiveEvents(Duration.ofSeconds(5)).iterator().next(); } }); @@ -304,7 +304,7 @@ public void insecureEndpointsAreRejectedBeforeAuthentication() { "https://example.com/#fragment" }) { AgentsClientBuilder builder = new AgentsClientBuilder().endpoint(endpoint).credential(credential); assertThrows(IllegalArgumentException.class, - () -> builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent")); + () -> builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent")); } assertFalse(requested.get()); } @@ -322,13 +322,13 @@ private static VoiceAgentWebSocketConnectionOptions tlsOptions() { public void syncReceiveStreamRejectsSecondIterator() { server = startServer(new CopyOnWriteArrayList<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), new AtomicReference<>(), false); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); - try (BetaVoiceAgentWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { Iterable events = session.receiveEvents(Duration.ofSeconds(5)); events.iterator(); IllegalStateException exception = assertThrows(IllegalStateException.class, events::iterator); @@ -349,8 +349,8 @@ public void rawEventsUseCustomizedTlsTransport() { .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))) .configuration(Configuration.NONE); BinaryData payload = BinaryData.fromString("{\"type\":\"future.event\",\"value\":42}"); - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", tlsOptions())) { assertThrows(IllegalArgumentException.class, () -> session.sendEvent(BinaryData.fromString("[]"))); assertThrows(IllegalArgumentException.class, () -> session.sendEvent(BinaryData.fromString("{} {}"))); session.sendEvent(payload); @@ -368,8 +368,8 @@ public void customCloseFrameAndReceiveTimeout() { AgentsClientBuilder builder = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1)))); - try (BetaVoiceAgentWebSocketSessionClient session - = builder.beta().buildBetaVoiceAgentWebSocketClient().openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session + = builder.beta().buildBetaVoiceAgentsWebSocketClient().openWebSocketSession("agent", tlsOptions())) { Iterator iterator = session.receiveEvents(Duration.ofMillis(20)).iterator(); IllegalStateException timeout = assertThrows(IllegalStateException.class, iterator::hasNext); assertInstanceOf(TimeoutException.class, timeout.getCause()); @@ -400,12 +400,12 @@ static void restoreTlsConfiguration() { public void syncConnectRejectsNullArguments() { TokenCredential credential = request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); NullPointerException agentNameException = assertThrows(NullPointerException.class, () -> client.openWebSocketSession(null, tlsOptions())); @@ -424,12 +424,12 @@ public void syncTokenFailureOccursBeforeNetworkAccess() { return response.send(); }).bindNow(); TokenCredential credential = request -> Mono.error(new IllegalStateException("token unavailable")); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); IllegalStateException exception = assertThrows(IllegalStateException.class, () -> client.openWebSocketSession("agent", tlsOptions())); @@ -446,12 +446,12 @@ public void syncRejectedHandshakeMapsConflictToAzureException() { .bindNow(); TokenCredential credential = request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); ResourceModifiedException exception = assertThrows(ResourceModifiedException.class, () -> client.openWebSocketSession("disabled-agent", tlsOptions())); @@ -463,11 +463,11 @@ public void syncRejectedHandshakeMapsConflictToAzureException() { public void syncClientRejectsEmptyAgentName() { TokenCredential credential = request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client = new AgentsClientBuilder().endpoint("https://example.com") + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://example.com") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> client.openWebSocketSession("", tlsOptions())); @@ -480,14 +480,14 @@ public void syncReceiveBufferOverflowFailsTheEventStream() { server = frameWebSocketServer(frames); TokenCredential credential = request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); - try (BetaVoiceAgentWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { assertTimeoutPreemptively(Duration.ofSeconds(5), () -> { while (session.isOpen()) { Thread.yield(); @@ -505,14 +505,14 @@ public void syncOrderlyClosePreservesFullReceiveBuffer() { server = frameWebSocketServer(frames); TokenCredential credential = request -> Mono.just(new AccessToken("test-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); - try (BetaVoiceAgentWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session = client.openWebSocketSession("agent", tlsOptions())) { assertTimeoutPreemptively(Duration.ofSeconds(5), () -> { Iterator events = session.receiveEvents().iterator(); int eventCount = 0; @@ -536,14 +536,14 @@ public void syncSessionReceivesTypedEventAndCloses() { new AtomicReference<>(), true); TokenCredential credential = request -> Mono.just(new AccessToken("sync-token", OffsetDateTime.now().plusHours(1))); - BetaVoiceAgentWebSocketClient client + BetaVoiceAgentsWebSocketClient client = new AgentsClientBuilder().endpoint("https://localhost:" + server.port() + "/api/projects/project") .credential(credential) .configuration(Configuration.NONE) .beta() - .buildBetaVoiceAgentWebSocketClient(); + .buildBetaVoiceAgentsWebSocketClient(); - try (BetaVoiceAgentWebSocketSessionClient session = client.openWebSocketSession("sync-agent", tlsOptions())) { + try (BetaVoiceAgentsWebSocketSessionClient session = client.openWebSocketSession("sync-agent", tlsOptions())) { Iterator events = session.receiveEvents().iterator(); assertWarningEvent(events.next()); session.sendFunctionCallOutput("call-1", "{\"temperature\":72}"); diff --git a/sdk/ai/azure-ai-agents/tsp-location.yaml b/sdk/ai/azure-ai-agents/tsp-location.yaml index f392952e48d1e..37843c74e8f31 100644 --- a/sdk/ai/azure-ai-agents/tsp-location.yaml +++ b/sdk/ai/azure-ai-agents/tsp-location.yaml @@ -1,5 +1,5 @@ directory: specification/ai-foundry/data-plane/Foundry/src/sdk-java-azure-ai-agents -commit: 4bcf516731e976e6e42997397202b20bed50e9c7 +commit: 0f7c44f0ae45c37986c658e24b17d5e158dfce4d repo: Azure/azure-rest-api-specs additionalDirectories: - specification/ai-foundry/data-plane/Foundry/src/agents diff --git a/sdk/ai/azure-ai-projects/CHANGELOG.md b/sdk/ai/azure-ai-projects/CHANGELOG.md index 83867ceb25c77..dd1452e4801ff 100644 --- a/sdk/ai/azure-ai-projects/CHANGELOG.md +++ b/sdk/ai/azure-ai-projects/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed long-running job polling to recognize the service's `cancelled` status as terminal. + ### Other Changes - Regenerated the client with `@azure-tools/openai-typespec` version `1.33.0`. diff --git a/sdk/ai/azure-ai-projects/customizations/src/main/java/ProjectsCustomizations.java b/sdk/ai/azure-ai-projects/customizations/src/main/java/ProjectsCustomizations.java index f3a5b8c2e66d2..9ad4bd2ae4813 100644 --- a/sdk/ai/azure-ai-projects/customizations/src/main/java/ProjectsCustomizations.java +++ b/sdk/ai/azure-ai-projects/customizations/src/main/java/ProjectsCustomizations.java @@ -3,6 +3,7 @@ import com.azure.autorest.customization.LibraryCustomization; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.Modifier; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.TypeDeclaration; @@ -28,12 +29,41 @@ public class ProjectsCustomizations extends Customization { @Override public void customize(LibraryCustomization libraryCustomization, Logger logger) { + modifyPollingStrategies(libraryCustomization); stopPagingWhenHasMoreIsFalse(libraryCustomization, logger); protectPolymorphicBaseConstructors(libraryCustomization); annotateBetaClients(libraryCustomization, logger); annotateBetaFields(libraryCustomization, loadBetaAnnotations(logger), logger); } + private void modifyPollingStrategies(LibraryCustomization customization) { + customization.getClass("com.azure.ai.projects.implementation", "OperationLocationPollingStrategy") + .customizeAst(ast -> { + ClassOrInterfaceDeclaration clazz = ast.getClassByName("OperationLocationPollingStrategy") + .orElseThrow( + () -> new IllegalStateException("OperationLocationPollingStrategy was not generated.")); + clazz.getMethodsByName("poll").forEach(MethodDeclaration::remove); + clazz.addMember(StaticJavaParser.parseMethodDeclaration("/** {@inheritDoc} */\n" + + "@Override public Mono> poll(PollingContext pollingContext, " + + "TypeReference pollResponseType) {\n" + + " return super.poll(pollingContext, pollResponseType)" + + ".map(ProjectsServicePollUtils::remapStatus);\n" + "}")); + }); + + customization.getClass("com.azure.ai.projects.implementation", "SyncOperationLocationPollingStrategy") + .customizeAst(ast -> { + ClassOrInterfaceDeclaration clazz = ast.getClassByName("SyncOperationLocationPollingStrategy") + .orElseThrow( + () -> new IllegalStateException("SyncOperationLocationPollingStrategy was not generated.")); + clazz.getMethodsByName("poll").forEach(MethodDeclaration::remove); + clazz.addMember(StaticJavaParser.parseMethodDeclaration("/** {@inheritDoc} */\n" + + "@Override public PollResponse poll(PollingContext pollingContext, " + + "TypeReference pollResponseType) {\n" + + " return ProjectsServicePollUtils.remapStatus(super.poll(pollingContext, pollResponseType));\n" + + "}")); + }); + } + private void stopPagingWhenHasMoreIsFalse(LibraryCustomization customization, Logger logger) { int[] customizedMethods = new int[1]; customization.getPackage("com.azure.ai.projects.implementation").listClasses().forEach(classCustomization -> diff --git a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java index c2b496b562bc2..61e65bfc9ac43 100644 --- a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java +++ b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java @@ -135,4 +135,12 @@ public Mono getResult(PollingContext pollingContext, TypeReference resu return super.getResult(pollingContext, resultType); } } + + /** + * {@inheritDoc} + */ + @Override + public Mono> poll(PollingContext pollingContext, TypeReference pollResponseType) { + return super.poll(pollingContext, pollResponseType).map(ProjectsServicePollUtils::remapStatus); + } } diff --git a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/ProjectsServicePollUtils.java b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/ProjectsServicePollUtils.java new file mode 100644 index 0000000000000..500f00e9e922a --- /dev/null +++ b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/ProjectsServicePollUtils.java @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.projects.implementation; + +import com.azure.ai.projects.models.JobStatus; +import com.azure.core.util.polling.LongRunningOperationStatus; +import com.azure.core.util.polling.PollResponse; + +final class ProjectsServicePollUtils { + private ProjectsServicePollUtils() { + } + + static PollResponse remapStatus(PollResponse response) { + if (JobStatus.CANCELLED.toString().equalsIgnoreCase(response.getStatus().toString())) { + return new PollResponse<>(LongRunningOperationStatus.USER_CANCELLED, response.getValue(), + response.getRetryAfter()); + } + return response; + } +} diff --git a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java index 229eeac0141a6..248bf06e5703f 100644 --- a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java +++ b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java @@ -127,4 +127,12 @@ public U getResult(PollingContext pollingContext, TypeReference resultType return super.getResult(pollingContext, resultType); } } + + /** + * {@inheritDoc} + */ + @Override + public PollResponse poll(PollingContext pollingContext, TypeReference pollResponseType) { + return ProjectsServicePollUtils.remapStatus(super.poll(pollingContext, pollResponseType)); + } } diff --git a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/models/DatasetReference.java b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/models/DatasetReference.java index 51e2f10e15b85..d9ed0ef6a7732 100644 --- a/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/models/DatasetReference.java +++ b/sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/models/DatasetReference.java @@ -12,7 +12,7 @@ import java.io.IOException; /** - * Reference to a versioned Foundry Dataset. + * Reference to a Dataset whose concrete version has already been resolved. */ @Immutable public final class DatasetReference implements JsonSerializable { @@ -24,7 +24,7 @@ public final class DatasetReference implements JsonSerializable kinds; - /** - * Creates an instance of EvaluatorGenerationArtifacts class. - * - * @param dataset the dataset value to set. - * @param kinds the kinds value to set. - */ - @Generated - private EvaluatorGenerationArtifacts(DatasetReference dataset, List kinds) { - this.dataset = dataset; - this.kinds = kinds; - } - /** * Get the dataset property: Reference to the single Foundry Dataset (one combined JSONL file, version-aligned to * `EvaluatorVersion.version`) holding all artifacts produced by the generation pipeline. Each row in the JSONL @@ -114,4 +102,16 @@ public static EvaluatorGenerationArtifacts fromJson(JsonReader jsonReader) throw return new EvaluatorGenerationArtifacts(dataset, kinds); }); } + + /** + * Creates an instance of EvaluatorGenerationArtifacts class. + * + * @param dataset the dataset value to set. + * @param kinds the kinds value to set. + */ + @Generated + private EvaluatorGenerationArtifacts(DatasetReference dataset, List kinds) { + this.dataset = dataset; + this.kinds = kinds; + } } diff --git a/sdk/ai/azure-ai-projects/src/main/resources/META-INF/azure-ai-projects_metadata.json b/sdk/ai/azure-ai-projects/src/main/resources/META-INF/azure-ai-projects_metadata.json index 6d7e596e2c780..cb6d4d020b58e 100644 --- a/sdk/ai/azure-ai-projects/src/main/resources/META-INF/azure-ai-projects_metadata.json +++ b/sdk/ai/azure-ai-projects/src/main/resources/META-INF/azure-ai-projects_metadata.json @@ -1 +1 @@ -{"flavor":"azure","apiVersions":{"Azure.AI.Projects":"v1"},"crossLanguagePackageId":"Azure.AI.Projects","crossLanguageVersion":"aea9b4d78bff","crossLanguageDefinitions":{"com.azure.ai.projects.AIProjectClientBuilder":"Azure.AI.Projects","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient":"Azure.AI.Projects.Beta.AgentInsightMonitors","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.beginCreateAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.beginCreateAgentInsightRunWithModel":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.cancelAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.cancelAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.createAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.createAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.deleteAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.deleteAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsightMonitors":"Azure.AI.Projects.AgentInsightMonitors.list","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsightRuns":"Azure.AI.Projects.AgentInsightMonitors.listRuns","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsights":"Azure.AI.Projects.AgentInsightMonitors.listInsights","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.resetAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.resetAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient":"Azure.AI.Projects.Beta.AgentInsightMonitors","com.azure.ai.projects.BetaAgentInsightMonitorsClient.beginCreateAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.beginCreateAgentInsightRunWithModel":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.cancelAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.cancelAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.createAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsClient.createAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsClient.deleteAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsClient.deleteAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsightMonitors":"Azure.AI.Projects.AgentInsightMonitors.list","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsightRuns":"Azure.AI.Projects.AgentInsightMonitors.listRuns","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsights":"Azure.AI.Projects.AgentInsightMonitors.listInsights","com.azure.ai.projects.BetaAgentInsightMonitorsClient.resetAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsClient.resetAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient":"Azure.AI.Projects.Beta.EvaluationTaxonomies","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.createEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.createEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.deleteEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.deleteEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.getEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.getEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.listEvaluationTaxonomies":"Azure.AI.Projects.EvaluationTaxonomies.list","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.updateEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.updateEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesClient":"Azure.AI.Projects.Beta.EvaluationTaxonomies","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.createEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.createEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.deleteEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.deleteEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.getEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.getEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.listEvaluationTaxonomies":"Azure.AI.Projects.EvaluationTaxonomies.list","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.updateEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.updateEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluatorsAsyncClient":"Azure.AI.Projects.Beta.Evaluators","com.azure.ai.projects.BetaEvaluatorsAsyncClient.getCredentials":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsAsyncClient.getCredentialsWithResponse":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsAsyncClient.startPendingUpload":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsAsyncClient.startPendingUploadWithResponse":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsClient":"Azure.AI.Projects.Beta.Evaluators","com.azure.ai.projects.BetaEvaluatorsClient.getCredentials":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsClient.getCredentialsWithResponse":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsClient.startPendingUpload":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsClient.startPendingUploadWithResponse":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaInsightsAsyncClient":"Azure.AI.Projects.Beta.Insights","com.azure.ai.projects.BetaInsightsAsyncClient.generateInsight":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsAsyncClient.generateInsightWithResponse":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsAsyncClient.getInsight":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsAsyncClient.getInsightWithResponse":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsAsyncClient.listInsights":"Azure.AI.Projects.Insights.list","com.azure.ai.projects.BetaInsightsClient":"Azure.AI.Projects.Beta.Insights","com.azure.ai.projects.BetaInsightsClient.generateInsight":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsClient.generateInsightWithResponse":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsClient.getInsight":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsClient.getInsightWithResponse":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsClient.listInsights":"Azure.AI.Projects.Insights.list","com.azure.ai.projects.BetaModelsAsyncClient":"Azure.AI.Projects.Beta.Models","com.azure.ai.projects.BetaModelsAsyncClient.createModelVersionAsyncWithResponse":"Azure.AI.Projects.Models.createAsync","com.azure.ai.projects.BetaModelsAsyncClient.deleteModelVersion":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsAsyncClient.deleteModelVersionWithResponse":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsAsyncClient.getModelCredentials":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsAsyncClient.getModelCredentialsWithResponse":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsAsyncClient.getModelVersion":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsAsyncClient.getModelVersionWithResponse":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsAsyncClient.listLatestModelVersions":"Azure.AI.Projects.Models.listLatest","com.azure.ai.projects.BetaModelsAsyncClient.listModelVersions":"Azure.AI.Projects.Models.listVersions","com.azure.ai.projects.BetaModelsAsyncClient.startModelPendingUpload":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsAsyncClient.startModelPendingUploadWithResponse":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsAsyncClient.updateModelVersion":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsAsyncClient.updateModelVersionWithResponse":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsClient":"Azure.AI.Projects.Beta.Models","com.azure.ai.projects.BetaModelsClient.createModelVersionAsyncWithResponse":"Azure.AI.Projects.Models.createAsync","com.azure.ai.projects.BetaModelsClient.deleteModelVersion":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsClient.deleteModelVersionWithResponse":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsClient.getModelCredentials":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsClient.getModelCredentialsWithResponse":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsClient.getModelVersion":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsClient.getModelVersionWithResponse":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsClient.listLatestModelVersions":"Azure.AI.Projects.Models.listLatest","com.azure.ai.projects.BetaModelsClient.listModelVersions":"Azure.AI.Projects.Models.listVersions","com.azure.ai.projects.BetaModelsClient.startModelPendingUpload":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsClient.startModelPendingUploadWithResponse":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsClient.updateModelVersion":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsClient.updateModelVersionWithResponse":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaRedTeamsAsyncClient":"Azure.AI.Projects.Beta.RedTeams","com.azure.ai.projects.BetaRedTeamsAsyncClient.createRedTeamRun":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsAsyncClient.createRedTeamRunWithResponse":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsAsyncClient.getRedTeam":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsAsyncClient.getRedTeamWithResponse":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsAsyncClient.listRedTeams":"Azure.AI.Projects.RedTeams.list","com.azure.ai.projects.BetaRedTeamsClient":"Azure.AI.Projects.Beta.RedTeams","com.azure.ai.projects.BetaRedTeamsClient.createRedTeamRun":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsClient.createRedTeamRunWithResponse":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsClient.getRedTeam":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsClient.getRedTeamWithResponse":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsClient.listRedTeams":"Azure.AI.Projects.RedTeams.list","com.azure.ai.projects.BetaRoutinesAsyncClient":"Azure.AI.Projects.Beta.Routines","com.azure.ai.projects.BetaRoutinesAsyncClient.createOrUpdateRoutine":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.createOrUpdateRoutineWithResponse":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.deleteRoutine":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.deleteRoutineWithResponse":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.disableRoutine":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.disableRoutineWithResponse":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.dispatchRoutine":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesAsyncClient.dispatchRoutineWithResponse":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesAsyncClient.enableRoutine":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.enableRoutineWithResponse":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.getRoutine":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.getRoutineWithResponse":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.listRoutineRuns":"Azure.AI.Projects.Routines.listRoutineRuns","com.azure.ai.projects.BetaRoutinesAsyncClient.listRoutines":"Azure.AI.Projects.Routines.listRoutines","com.azure.ai.projects.BetaRoutinesClient":"Azure.AI.Projects.Beta.Routines","com.azure.ai.projects.BetaRoutinesClient.createOrUpdateRoutine":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesClient.createOrUpdateRoutineWithResponse":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesClient.deleteRoutine":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesClient.deleteRoutineWithResponse":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesClient.disableRoutine":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesClient.disableRoutineWithResponse":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesClient.dispatchRoutine":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesClient.dispatchRoutineWithResponse":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesClient.enableRoutine":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesClient.enableRoutineWithResponse":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesClient.getRoutine":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesClient.getRoutineWithResponse":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesClient.listRoutineRuns":"Azure.AI.Projects.Routines.listRoutineRuns","com.azure.ai.projects.BetaRoutinesClient.listRoutines":"Azure.AI.Projects.Routines.listRoutines","com.azure.ai.projects.BetaSchedulesAsyncClient":"Azure.AI.Projects.Beta.Schedules","com.azure.ai.projects.BetaSchedulesAsyncClient.createOrUpdateSchedule":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesAsyncClient.createOrUpdateScheduleWithResponse":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesAsyncClient.deleteSchedule":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesAsyncClient.deleteScheduleWithResponse":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesAsyncClient.getSchedule":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleRun":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleRunWithResponse":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleWithResponse":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesAsyncClient.listScheduleRuns":"Azure.AI.Projects.Schedules.listRuns","com.azure.ai.projects.BetaSchedulesAsyncClient.listSchedules":"Azure.AI.Projects.Schedules.list","com.azure.ai.projects.BetaSchedulesClient":"Azure.AI.Projects.Beta.Schedules","com.azure.ai.projects.BetaSchedulesClient.createOrUpdateSchedule":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesClient.createOrUpdateScheduleWithResponse":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesClient.deleteSchedule":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesClient.deleteScheduleWithResponse":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesClient.getSchedule":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesClient.getScheduleRun":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesClient.getScheduleRunWithResponse":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesClient.getScheduleWithResponse":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesClient.listScheduleRuns":"Azure.AI.Projects.Schedules.listRuns","com.azure.ai.projects.BetaSchedulesClient.listSchedules":"Azure.AI.Projects.Schedules.list","com.azure.ai.projects.BetaSkillsAsyncClient":"Azure.AI.Projects.Beta.Skills","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersion":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionFromFiles":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionFromFilesWithResponseInternal":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionWithResponse":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkill":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillContent":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillContentWithResponse":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersion":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionContent":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionContentWithResponse":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionWithResponse":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillWithResponse":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsAsyncClient.listSkillVersions":"Azure.AI.Projects.Skills.listSkillVersions","com.azure.ai.projects.BetaSkillsAsyncClient.listSkills":"Azure.AI.Projects.Skills.listSkills","com.azure.ai.projects.BetaSkillsAsyncClient.updateSkill":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsAsyncClient.updateSkillWithResponse":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsClient":"Azure.AI.Projects.Beta.Skills","com.azure.ai.projects.BetaSkillsClient.createSkillVersion":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsClient.createSkillVersionFromFiles":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsClient.createSkillVersionFromFilesWithResponseInternal":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsClient.createSkillVersionWithResponse":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkill":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsClient.getSkillContent":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsClient.getSkillContentWithResponse":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersion":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkillVersionContent":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersionContentWithResponse":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersionWithResponse":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkillWithResponse":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsClient.listSkillVersions":"Azure.AI.Projects.Skills.listSkillVersions","com.azure.ai.projects.BetaSkillsClient.listSkills":"Azure.AI.Projects.Skills.listSkills","com.azure.ai.projects.BetaSkillsClient.updateSkill":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsClient.updateSkillWithResponse":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.ConnectionsAsyncClient":"Azure.AI.Projects.Connections","com.azure.ai.projects.ConnectionsAsyncClient.getConnection":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithCredentials":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithCredentialsWithResponse":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithResponse":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsAsyncClient.listConnections":"Azure.AI.Projects.Connections.list","com.azure.ai.projects.ConnectionsClient":"Azure.AI.Projects.Connections","com.azure.ai.projects.ConnectionsClient.getConnection":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsClient.getConnectionWithCredentials":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsClient.getConnectionWithCredentialsWithResponse":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsClient.getConnectionWithResponse":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsClient.listConnections":"Azure.AI.Projects.Connections.list","com.azure.ai.projects.DatasetsAsyncClient":"Azure.AI.Projects.Datasets","com.azure.ai.projects.DatasetsAsyncClient.beginCreateGenerationJob":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsAsyncClient.beginCreateGenerationJobWithModel":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsAsyncClient.cancelGenerationJob":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsAsyncClient.cancelGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsAsyncClient.createOrUpdateDatasetVersion":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsAsyncClient.createOrUpdateDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteDatasetVersion":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteGenerationJob":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsAsyncClient.deleteGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsAsyncClient.getCredentials":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsAsyncClient.getCredentialsWithResponse":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsAsyncClient.getDatasetVersion":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsAsyncClient.getDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsAsyncClient.getGenerationJob":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsAsyncClient.getGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsAsyncClient.listDatasetVersions":"Azure.AI.Projects.Datasets.listVersions","com.azure.ai.projects.DatasetsAsyncClient.listGenerationJobs":"Azure.AI.Projects.DataGenerationJobs.list","com.azure.ai.projects.DatasetsAsyncClient.listLatestDatasetVersions":"Azure.AI.Projects.Datasets.listLatest","com.azure.ai.projects.DatasetsAsyncClient.pendingUpload":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsAsyncClient.pendingUploadWithResponse":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsClient":"Azure.AI.Projects.Datasets","com.azure.ai.projects.DatasetsClient.beginCreateGenerationJob":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsClient.beginCreateGenerationJobWithModel":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsClient.cancelGenerationJob":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsClient.cancelGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsClient.createOrUpdateDatasetVersion":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsClient.createOrUpdateDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsClient.deleteDatasetVersion":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsClient.deleteDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsClient.deleteGenerationJob":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsClient.deleteGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsClient.getCredentials":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsClient.getCredentialsWithResponse":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsClient.getDatasetVersion":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsClient.getDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsClient.getGenerationJob":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsClient.getGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsClient.listDatasetVersions":"Azure.AI.Projects.Datasets.listVersions","com.azure.ai.projects.DatasetsClient.listGenerationJobs":"Azure.AI.Projects.DataGenerationJobs.list","com.azure.ai.projects.DatasetsClient.listLatestDatasetVersions":"Azure.AI.Projects.Datasets.listLatest","com.azure.ai.projects.DatasetsClient.pendingUpload":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsClient.pendingUploadWithResponse":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DeploymentsAsyncClient":"Azure.AI.Projects.Deployments","com.azure.ai.projects.DeploymentsAsyncClient.getDeployment":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsAsyncClient.getDeploymentWithResponse":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsAsyncClient.listDeployments":"Azure.AI.Projects.Deployments.list","com.azure.ai.projects.DeploymentsClient":"Azure.AI.Projects.Deployments","com.azure.ai.projects.DeploymentsClient.getDeployment":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsClient.getDeploymentWithResponse":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsClient.listDeployments":"Azure.AI.Projects.Deployments.list","com.azure.ai.projects.EvaluationRulesAsyncClient":"Azure.AI.Projects.EvaluationRules","com.azure.ai.projects.EvaluationRulesAsyncClient.createOrUpdateEvaluationRule":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesAsyncClient.createOrUpdateEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesAsyncClient.deleteEvaluationRule":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesAsyncClient.deleteEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesAsyncClient.getEvaluationRule":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesAsyncClient.getEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesAsyncClient.listEvaluationRules":"Azure.AI.Projects.EvaluationRules.list","com.azure.ai.projects.EvaluationRulesClient":"Azure.AI.Projects.EvaluationRules","com.azure.ai.projects.EvaluationRulesClient.createOrUpdateEvaluationRule":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesClient.createOrUpdateEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesClient.deleteEvaluationRule":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesClient.deleteEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesClient.getEvaluationRule":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesClient.getEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesClient.listEvaluationRules":"Azure.AI.Projects.EvaluationRules.list","com.azure.ai.projects.EvaluatorsAsyncClient":"Azure.AI.Projects.Evaluators","com.azure.ai.projects.EvaluatorsAsyncClient.beginCreateEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsAsyncClient.beginCreateEvaluatorGenerationJobWithModel":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsAsyncClient.cancelEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsAsyncClient.cancelEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsAsyncClient.createEvaluatorVersion":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsAsyncClient.createEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorVersion":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorVersion":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsAsyncClient.listEvaluatorGenerationJobs":"Azure.AI.Projects.EvaluatorGenerationJobs.list","com.azure.ai.projects.EvaluatorsAsyncClient.listEvaluatorVersions":"Azure.AI.Projects.Evaluators.listVersions","com.azure.ai.projects.EvaluatorsAsyncClient.listLatestEvaluatorVersions":"Azure.AI.Projects.Evaluators.listLatestVersions","com.azure.ai.projects.EvaluatorsAsyncClient.updateEvaluatorVersion":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsAsyncClient.updateEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsClient":"Azure.AI.Projects.Evaluators","com.azure.ai.projects.EvaluatorsClient.beginCreateEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsClient.beginCreateEvaluatorGenerationJobWithModel":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsClient.cancelEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsClient.cancelEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsClient.createEvaluatorVersion":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsClient.createEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorVersion":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsClient.getEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsClient.getEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsClient.getEvaluatorVersion":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsClient.getEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsClient.listEvaluatorGenerationJobs":"Azure.AI.Projects.EvaluatorGenerationJobs.list","com.azure.ai.projects.EvaluatorsClient.listEvaluatorVersions":"Azure.AI.Projects.Evaluators.listVersions","com.azure.ai.projects.EvaluatorsClient.listLatestEvaluatorVersions":"Azure.AI.Projects.Evaluators.listLatestVersions","com.azure.ai.projects.EvaluatorsClient.updateEvaluatorVersion":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsClient.updateEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.IndexesAsyncClient":"Azure.AI.Projects.Indexes","com.azure.ai.projects.IndexesAsyncClient.createOrUpdateIndexVersion":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesAsyncClient.createOrUpdateIndexVersionWithResponse":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesAsyncClient.deleteIndexVersion":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesAsyncClient.deleteIndexVersionWithResponse":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesAsyncClient.getIndexVersion":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesAsyncClient.getIndexVersionWithResponse":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesAsyncClient.listIndexVersions":"Azure.AI.Projects.Indexes.listVersions","com.azure.ai.projects.IndexesAsyncClient.listLatestIndexVersions":"Azure.AI.Projects.Indexes.listLatest","com.azure.ai.projects.IndexesClient":"Azure.AI.Projects.Indexes","com.azure.ai.projects.IndexesClient.createOrUpdateIndexVersion":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesClient.createOrUpdateIndexVersionWithResponse":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesClient.deleteIndexVersion":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesClient.deleteIndexVersionWithResponse":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesClient.getIndexVersion":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesClient.getIndexVersionWithResponse":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesClient.listIndexVersions":"Azure.AI.Projects.Indexes.listVersions","com.azure.ai.projects.IndexesClient.listLatestIndexVersions":"Azure.AI.Projects.Indexes.listLatest","com.azure.ai.projects.implementation.models.CreateOrUpdateRoutineRequest":"Azure.AI.Projects.createOrUpdateRoutine.Request.anonymous","com.azure.ai.projects.implementation.models.CreateSkillVersionRequest":"Azure.AI.Projects.createSkillVersion.Request.anonymous","com.azure.ai.projects.implementation.models.DispatchRoutineAsyncRequest":"Azure.AI.Projects.dispatchRoutineAsync.Request.anonymous","com.azure.ai.projects.implementation.models.FoundryFeaturesOptInKeys":"Azure.AI.Projects.FoundryFeaturesOptInKeys","com.azure.ai.projects.implementation.models.UpdateSkillRequest":"Azure.AI.Projects.updateSkill.Request.anonymous","com.azure.ai.projects.models.AIProjectIndex":"Azure.AI.Projects.Index","com.azure.ai.projects.models.AgentClusterInsightRequest":"Azure.AI.Projects.AgentClusterInsightRequest","com.azure.ai.projects.models.AgentClusterInsightResult":"Azure.AI.Projects.AgentClusterInsightResult","com.azure.ai.projects.models.AgentDataGenerationJobSource":"Azure.AI.Projects.AgentDataGenerationJobSource","com.azure.ai.projects.models.AgentEvaluatorGenerationJobSource":"Azure.AI.Projects.AgentEvaluatorGenerationJobSource","com.azure.ai.projects.models.AgentInsight":"Azure.AI.Projects.AgentInsight","com.azure.ai.projects.models.AgentInsightDetails":"Azure.AI.Projects.AgentInsightDetails","com.azure.ai.projects.models.AgentInsightEstimatedCost":"Azure.AI.Projects.AgentInsightEstimatedCost","com.azure.ai.projects.models.AgentInsightHighlightedTrace":"Azure.AI.Projects.AgentInsightHighlightedTrace","com.azure.ai.projects.models.AgentInsightLinkedTrace":"Azure.AI.Projects.AgentInsightLinkedTrace","com.azure.ai.projects.models.AgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitor","com.azure.ai.projects.models.AgentInsightMonitorCreate":"Azure.AI.Projects.AgentInsightMonitorCreate","com.azure.ai.projects.models.AgentInsightMonitorListItem":"Azure.AI.Projects.AgentInsightMonitorListItem","com.azure.ai.projects.models.AgentInsightMonitorUpdate":"Azure.AI.Projects.AgentInsightMonitorUpdate","com.azure.ai.projects.models.AgentInsightOverviewSource":"Azure.AI.Projects.AgentInsightOverviewSource","com.azure.ai.projects.models.AgentInsightPromptSurface":"Azure.AI.Projects.AgentInsightPromptSurface","com.azure.ai.projects.models.AgentInsightProposedFix":"Azure.AI.Projects.AgentInsightProposedFix","com.azure.ai.projects.models.AgentInsightProposedFixChange":"Azure.AI.Projects.AgentInsightProposedFixChange","com.azure.ai.projects.models.AgentInsightProposedFixKind":"Azure.AI.Projects.AgentInsightProposedFixKind","com.azure.ai.projects.models.AgentInsightRecommendedAction":"Azure.AI.Projects.AgentInsightRecommendedAction","com.azure.ai.projects.models.AgentInsightRun":"Azure.AI.Projects.AgentInsightRun","com.azure.ai.projects.models.AgentInsightRunCreate":"Azure.AI.Projects.AgentInsightRunCreate","com.azure.ai.projects.models.AgentInsightRunResult":"Azure.AI.Projects.AgentInsightRunResult","com.azure.ai.projects.models.AgentInsightRunTrigger":"Azure.AI.Projects.AgentInsightRunTrigger","com.azure.ai.projects.models.AgentInsightSeverity":"Azure.AI.Projects.AgentInsightSeverity","com.azure.ai.projects.models.AgentInsightStatus":"Azure.AI.Projects.AgentInsightStatus","com.azure.ai.projects.models.AgentInsightSuspension":"Azure.AI.Projects.AgentInsightSuspension","com.azure.ai.projects.models.AgentInsightTokenUsage":"Azure.AI.Projects.AgentInsightTokenUsage","com.azure.ai.projects.models.AgentInsightUpdate":"Azure.AI.Projects.AgentInsightUpdate","com.azure.ai.projects.models.AgentInsightsOverview":"Azure.AI.Projects.AgentInsightsOverview","com.azure.ai.projects.models.AgentInsightsOverviewOverride":"Azure.AI.Projects.AgentInsightsOverviewOverride","com.azure.ai.projects.models.AgentTaxonomyInput":"Azure.AI.Projects.AgentTaxonomyInput","com.azure.ai.projects.models.AgenticIdentityPreviewCredential":"Azure.AI.Projects.AgenticIdentityPreviewCredentials","com.azure.ai.projects.models.ApiError":"OpenAI.Error","com.azure.ai.projects.models.ApiKeyCredential":"Azure.AI.Projects.ApiKeyCredentials","com.azure.ai.projects.models.ArtifactProfile":"Azure.AI.Projects.ArtifactProfile","com.azure.ai.projects.models.AttackStrategy":"Azure.AI.Projects.AttackStrategy","com.azure.ai.projects.models.AzureAIAgentTarget":"Azure.AI.Projects.AzureAIAgentTarget","com.azure.ai.projects.models.AzureAIModelTarget":"Azure.AI.Projects.AzureAIModelTarget","com.azure.ai.projects.models.AzureAISearchIndex":"Azure.AI.Projects.AzureAISearchIndex","com.azure.ai.projects.models.AzureOpenAIModelConfiguration":"Azure.AI.Projects.AzureOpenAIModelConfiguration","com.azure.ai.projects.models.BaseCredential":"Azure.AI.Projects.BaseCredentials","com.azure.ai.projects.models.BlobReference":"Azure.AI.Projects.BlobReference","com.azure.ai.projects.models.BlobReferenceSasCredential":"Azure.AI.Projects.SasCredential","com.azure.ai.projects.models.ChartCoordinate":"Azure.AI.Projects.ChartCoordinate","com.azure.ai.projects.models.ClusterInsightResult":"Azure.AI.Projects.ClusterInsightResult","com.azure.ai.projects.models.ClusterTokenUsage":"Azure.AI.Projects.ClusterTokenUsage","com.azure.ai.projects.models.CodeBasedEvaluatorDefinition":"Azure.AI.Projects.CodeBasedEvaluatorDefinition","com.azure.ai.projects.models.Connection":"Azure.AI.Projects.Connection","com.azure.ai.projects.models.ConnectionType":"Azure.AI.Projects.ConnectionType","com.azure.ai.projects.models.ContinuousEvaluationRuleAction":"Azure.AI.Projects.ContinuousEvaluationRuleAction","com.azure.ai.projects.models.CosmosDBIndex":"Azure.AI.Projects.CosmosDBIndex","com.azure.ai.projects.models.CreateAsyncResponse":"Azure.AI.Projects.createAsync.Response.anonymous","com.azure.ai.projects.models.CreateSkillVersionFromFilesBody":"Azure.AI.Projects.CreateSkillVersionFromFilesBody","com.azure.ai.projects.models.CredentialType":"Azure.AI.Projects.CredentialType","com.azure.ai.projects.models.CronTrigger":"Azure.AI.Projects.CronTrigger","com.azure.ai.projects.models.CustomCredential":"Azure.AI.Projects.CustomCredential","com.azure.ai.projects.models.CustomRoutineTrigger":"Azure.AI.Projects.CustomRoutineTrigger","com.azure.ai.projects.models.DailyRecurrenceSchedule":"Azure.AI.Projects.DailyRecurrenceSchedule","com.azure.ai.projects.models.DataGenerationJob":"Azure.AI.Projects.DataGenerationJob","com.azure.ai.projects.models.DataGenerationJobConfiguration":"Azure.AI.Projects.DataGenerationJobConfiguration","com.azure.ai.projects.models.DataGenerationJobInputs":"Azure.AI.Projects.DataGenerationJobInputs","com.azure.ai.projects.models.DataGenerationJobOutput":"Azure.AI.Projects.DataGenerationJobOutput","com.azure.ai.projects.models.DataGenerationJobOutputType":"Azure.AI.Projects.DataGenerationJobOutputType","com.azure.ai.projects.models.DataGenerationJobOutputWriteMode":"Azure.AI.Projects.DataGenerationJobOutputWriteMode","com.azure.ai.projects.models.DataGenerationJobResult":"Azure.AI.Projects.DataGenerationJobResult","com.azure.ai.projects.models.DataGenerationJobScenario":"Azure.AI.Projects.DataGenerationJobScenario","com.azure.ai.projects.models.DataGenerationJobSource":"Azure.AI.Projects.DataGenerationJobSource","com.azure.ai.projects.models.DataGenerationJobSourceType":"Azure.AI.Projects.DataGenerationJobSourceType","com.azure.ai.projects.models.DataGenerationJobType":"Azure.AI.Projects.DataGenerationJobType","com.azure.ai.projects.models.DataGenerationModelOptions":"Azure.AI.Projects.DataGenerationModelOptions","com.azure.ai.projects.models.DataGenerationTokenUsage":"Azure.AI.Projects.DataGenerationTokenUsage","com.azure.ai.projects.models.DatasetCredential":"Azure.AI.Projects.AssetCredentialResponse","com.azure.ai.projects.models.DatasetDataGenerationJobOutput":"Azure.AI.Projects.DatasetDataGenerationJobOutput","com.azure.ai.projects.models.DatasetEvaluatorGenerationJobSource":"Azure.AI.Projects.DatasetEvaluatorGenerationJobSource","com.azure.ai.projects.models.DatasetReference":"Azure.AI.Projects.DatasetReference","com.azure.ai.projects.models.DatasetType":"Azure.AI.Projects.DatasetType","com.azure.ai.projects.models.DatasetVersion":"Azure.AI.Projects.DatasetVersion","com.azure.ai.projects.models.Deployment":"Azure.AI.Projects.Deployment","com.azure.ai.projects.models.DeploymentType":"Azure.AI.Projects.DeploymentType","com.azure.ai.projects.models.Dimension":"Azure.AI.Projects.Dimension","com.azure.ai.projects.models.DispatchRoutineResult":"Azure.AI.Projects.DispatchRoutineResponse","com.azure.ai.projects.models.EmbeddingConfiguration":"Azure.AI.Projects.EmbeddingConfiguration","com.azure.ai.projects.models.EndpointBasedEvaluatorDefinition":"Azure.AI.Projects.EndpointBasedEvaluatorDefinition","com.azure.ai.projects.models.EntraIdCredential":"Azure.AI.Projects.EntraIDCredentials","com.azure.ai.projects.models.EvaluationComparisonInsightRequest":"Azure.AI.Projects.EvaluationComparisonInsightRequest","com.azure.ai.projects.models.EvaluationComparisonInsightResult":"Azure.AI.Projects.EvaluationComparisonInsightResult","com.azure.ai.projects.models.EvaluationDataGenerationJob":"Azure.AI.Projects.EvaluationDataGenerationJob","com.azure.ai.projects.models.EvaluationDataGenerationJobInputs":"Azure.AI.Projects.EvaluationDataGenerationJobInputs","com.azure.ai.projects.models.EvaluationDataGenerationJobOutputConfiguration":"Azure.AI.Projects.EvaluationDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.EvaluationLevel":"Azure.AI.Projects.EvaluationLevel","com.azure.ai.projects.models.EvaluationResult":"Azure.AI.Projects.EvalResult","com.azure.ai.projects.models.EvaluationResultSample":"Azure.AI.Projects.EvaluationResultSample","com.azure.ai.projects.models.EvaluationRule":"Azure.AI.Projects.EvaluationRule","com.azure.ai.projects.models.EvaluationRuleAction":"Azure.AI.Projects.EvaluationRuleAction","com.azure.ai.projects.models.EvaluationRuleActionType":"Azure.AI.Projects.EvaluationRuleActionType","com.azure.ai.projects.models.EvaluationRuleEventType":"Azure.AI.Projects.EvaluationRuleEventType","com.azure.ai.projects.models.EvaluationRuleFilter":"Azure.AI.Projects.EvaluationRuleFilter","com.azure.ai.projects.models.EvaluationRunClusterInsightRequest":"Azure.AI.Projects.EvaluationRunClusterInsightRequest","com.azure.ai.projects.models.EvaluationRunClusterInsightResult":"Azure.AI.Projects.EvaluationRunClusterInsightResult","com.azure.ai.projects.models.EvaluationRunResultCompareItem":"Azure.AI.Projects.EvalRunResultCompareItem","com.azure.ai.projects.models.EvaluationRunResultComparison":"Azure.AI.Projects.EvalRunResultComparison","com.azure.ai.projects.models.EvaluationRunResultSummary":"Azure.AI.Projects.EvalRunResultSummary","com.azure.ai.projects.models.EvaluationScheduleTask":"Azure.AI.Projects.EvaluationScheduleTask","com.azure.ai.projects.models.EvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomy","com.azure.ai.projects.models.EvaluationTaxonomyInput":"Azure.AI.Projects.EvaluationTaxonomyInput","com.azure.ai.projects.models.EvaluationTaxonomyInputType":"Azure.AI.Projects.EvaluationTaxonomyInputType","com.azure.ai.projects.models.EvaluatorCategory":"Azure.AI.Projects.EvaluatorCategory","com.azure.ai.projects.models.EvaluatorCredentialInput":"Azure.AI.Projects.EvaluatorCredentialRequest","com.azure.ai.projects.models.EvaluatorDefinition":"Azure.AI.Projects.EvaluatorDefinition","com.azure.ai.projects.models.EvaluatorDefinitionType":"Azure.AI.Projects.EvaluatorDefinitionType","com.azure.ai.projects.models.EvaluatorGenerationArtifacts":"Azure.AI.Projects.EvaluatorGenerationArtifacts","com.azure.ai.projects.models.EvaluatorGenerationInputs":"Azure.AI.Projects.EvaluatorGenerationInputs","com.azure.ai.projects.models.EvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJob","com.azure.ai.projects.models.EvaluatorGenerationJobSource":"Azure.AI.Projects.EvaluatorGenerationJobSource","com.azure.ai.projects.models.EvaluatorGenerationJobSourceType":"Azure.AI.Projects.EvaluatorGenerationJobSourceType","com.azure.ai.projects.models.EvaluatorGenerationTokenUsage":"Azure.AI.Projects.EvaluatorGenerationTokenUsage","com.azure.ai.projects.models.EvaluatorMetric":"Azure.AI.Projects.EvaluatorMetric","com.azure.ai.projects.models.EvaluatorMetricDirection":"Azure.AI.Projects.EvaluatorMetricDirection","com.azure.ai.projects.models.EvaluatorMetricType":"Azure.AI.Projects.EvaluatorMetricType","com.azure.ai.projects.models.EvaluatorType":"Azure.AI.Projects.EvaluatorType","com.azure.ai.projects.models.EvaluatorVersion":"Azure.AI.Projects.EvaluatorVersion","com.azure.ai.projects.models.FieldMapping":"Azure.AI.Projects.FieldMapping","com.azure.ai.projects.models.FileDataGenerationJobOutput":"Azure.AI.Projects.FileDataGenerationJobOutput","com.azure.ai.projects.models.FileDataGenerationJobSource":"Azure.AI.Projects.FileDataGenerationJobSource","com.azure.ai.projects.models.FileDatasetVersion":"Azure.AI.Projects.FileDatasetVersion","com.azure.ai.projects.models.FolderDatasetVersion":"Azure.AI.Projects.FolderDatasetVersion","com.azure.ai.projects.models.FoundryModelArtifactProfileCategory":"Azure.AI.Projects.FoundryModelArtifactProfileCategory","com.azure.ai.projects.models.FoundryModelArtifactProfileSignal":"Azure.AI.Projects.FoundryModelArtifactProfileSignal","com.azure.ai.projects.models.FoundryModelSourceType":"Azure.AI.Projects.FoundryModelSourceType","com.azure.ai.projects.models.FoundryModelWarning":"Azure.AI.Projects.FoundryModelWarning","com.azure.ai.projects.models.FoundryModelWarningCode":"Azure.AI.Projects.FoundryModelWarningCode","com.azure.ai.projects.models.FoundryModelWeightType":"Azure.AI.Projects.FoundryModelWeightType","com.azure.ai.projects.models.GenerationWarningType":"Azure.AI.Projects.GenerationWarningType","com.azure.ai.projects.models.GitHubIssueEvent":"Azure.AI.Projects.GitHubIssueEvent","com.azure.ai.projects.models.GitHubIssueRoutineTrigger":"Azure.AI.Projects.GitHubIssueRoutineTrigger","com.azure.ai.projects.models.GraderAzureAIEvaluator":"Azure.AI.Projects.GraderAzureAIEvaluator","com.azure.ai.projects.models.HourlyRecurrenceSchedule":"Azure.AI.Projects.HourlyRecurrenceSchedule","com.azure.ai.projects.models.HumanEvaluationPreviewRuleAction":"Azure.AI.Projects.HumanEvaluationPreviewRuleAction","com.azure.ai.projects.models.IndexType":"Azure.AI.Projects.IndexType","com.azure.ai.projects.models.Insight":"Azure.AI.Projects.Insight","com.azure.ai.projects.models.InsightCluster":"Azure.AI.Projects.InsightCluster","com.azure.ai.projects.models.InsightModelConfiguration":"Azure.AI.Projects.InsightModelConfiguration","com.azure.ai.projects.models.InsightRequest":"Azure.AI.Projects.InsightRequest","com.azure.ai.projects.models.InsightResult":"Azure.AI.Projects.InsightResult","com.azure.ai.projects.models.InsightSample":"Azure.AI.Projects.InsightSample","com.azure.ai.projects.models.InsightScheduleTask":"Azure.AI.Projects.InsightScheduleTask","com.azure.ai.projects.models.InsightSummary":"Azure.AI.Projects.InsightSummary","com.azure.ai.projects.models.InsightType":"Azure.AI.Projects.InsightType","com.azure.ai.projects.models.InsightsMetadata":"Azure.AI.Projects.InsightsMetadata","com.azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload":"Azure.AI.Projects.InvokeAgentInvocationsApiDispatchPayload","com.azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction":"Azure.AI.Projects.InvokeAgentInvocationsApiRoutineAction","com.azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload":"Azure.AI.Projects.InvokeAgentResponsesApiDispatchPayload","com.azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction":"Azure.AI.Projects.InvokeAgentResponsesApiRoutineAction","com.azure.ai.projects.models.JobStatus":"Azure.AI.Projects.JobStatus","com.azure.ai.projects.models.ListVersionsRequestType":"Azure.AI.Projects.listVersions.RequestType.anonymous","com.azure.ai.projects.models.LoraConfig":"Azure.AI.Projects.LoraConfig","com.azure.ai.projects.models.ManagedAzureAISearchIndex":"Azure.AI.Projects.ManagedAzureAISearchIndex","com.azure.ai.projects.models.ModelCredentialInput":"Azure.AI.Projects.ModelCredentialRequest","com.azure.ai.projects.models.ModelDeployment":"Azure.AI.Projects.ModelDeployment","com.azure.ai.projects.models.ModelDeploymentSku":"Azure.AI.Projects.Sku","com.azure.ai.projects.models.ModelPendingUploadInput":"Azure.AI.Projects.ModelPendingUploadRequest","com.azure.ai.projects.models.ModelPendingUploadResult":"Azure.AI.Projects.ModelPendingUploadResponse","com.azure.ai.projects.models.ModelSamplingParams":"Azure.AI.Projects.ModelSamplingParams","com.azure.ai.projects.models.ModelSourceData":"Azure.AI.Projects.ModelSourceData","com.azure.ai.projects.models.ModelVersion":"Azure.AI.Projects.ModelVersion","com.azure.ai.projects.models.MonthlyRecurrenceSchedule":"Azure.AI.Projects.MonthlyRecurrenceSchedule","com.azure.ai.projects.models.NoAuthenticationCredential":"Azure.AI.Projects.NoAuthenticationCredentials","com.azure.ai.projects.models.OneTimeTrigger":"Azure.AI.Projects.OneTimeTrigger","com.azure.ai.projects.models.OperationStatus":"Azure.Core.Foundations.OperationState","com.azure.ai.projects.models.PendingUploadRequest":"Azure.AI.Projects.PendingUploadRequest","com.azure.ai.projects.models.PendingUploadResponse":"Azure.AI.Projects.PendingUploadResponse","com.azure.ai.projects.models.PendingUploadType":"Azure.AI.Projects.PendingUploadType","com.azure.ai.projects.models.PromptBasedEvaluatorDefinition":"Azure.AI.Projects.PromptBasedEvaluatorDefinition","com.azure.ai.projects.models.PromptDataGenerationJobSource":"Azure.AI.Projects.PromptDataGenerationJobSource","com.azure.ai.projects.models.PromptEvaluatorGenerationJobSource":"Azure.AI.Projects.PromptEvaluatorGenerationJobSource","com.azure.ai.projects.models.RecurrenceSchedule":"Azure.AI.Projects.RecurrenceSchedule","com.azure.ai.projects.models.RecurrenceTrigger":"Azure.AI.Projects.RecurrenceTrigger","com.azure.ai.projects.models.RecurrenceType":"Azure.AI.Projects.RecurrenceType","com.azure.ai.projects.models.RedTeam":"Azure.AI.Projects.RedTeam","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJob":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJob","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJobInputs":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJobInputs","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJobOutputConfiguration":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.RiskCategory":"Azure.AI.Projects.RiskCategory","com.azure.ai.projects.models.Routine":"Azure.AI.Projects.Routine","com.azure.ai.projects.models.RoutineAction":"Azure.AI.Projects.RoutineAction","com.azure.ai.projects.models.RoutineActionType":"Azure.AI.Projects.RoutineActionType","com.azure.ai.projects.models.RoutineAttemptSource":"Azure.AI.Projects.RoutineAttemptSource","com.azure.ai.projects.models.RoutineAuthorization":"Azure.AI.Projects.RoutineAuthorization","com.azure.ai.projects.models.RoutineDispatchIdentity":"Azure.AI.Projects.RoutineDispatchIdentity","com.azure.ai.projects.models.RoutineDispatchPayload":"Azure.AI.Projects.RoutineDispatchPayload","com.azure.ai.projects.models.RoutineDispatchPayloadType":"Azure.AI.Projects.RoutineDispatchPayloadType","com.azure.ai.projects.models.RoutineRun":"Azure.AI.Projects.RoutineRun","com.azure.ai.projects.models.RoutineRunPhase":"Azure.AI.Projects.RoutineRunPhase","com.azure.ai.projects.models.RoutineTrigger":"Azure.AI.Projects.RoutineTrigger","com.azure.ai.projects.models.RoutineTriggerType":"Azure.AI.Projects.RoutineTriggerType","com.azure.ai.projects.models.RubricBasedEvaluatorDefinition":"Azure.AI.Projects.RubricBasedEvaluatorDefinition","com.azure.ai.projects.models.RubricGenerationInputQualityWarning":"Azure.AI.Projects.RubricGenerationInputQualityWarning","com.azure.ai.projects.models.RubricGenerationInputQualityWarningCode":"Azure.AI.Projects.RubricGenerationInputQualityWarningCode","com.azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity":"Azure.AI.Projects.RubricGenerationInputQualityWarningSeverity","com.azure.ai.projects.models.RubricGenerationInputQualityWarningSource":"Azure.AI.Projects.RubricGenerationInputQualityWarningSource","com.azure.ai.projects.models.SampleType":"Azure.AI.Projects.SampleType","com.azure.ai.projects.models.SasCredential":"Azure.AI.Projects.SASCredentials","com.azure.ai.projects.models.Schedule":"Azure.AI.Projects.Schedule","com.azure.ai.projects.models.ScheduleProvisioningStatus":"Azure.AI.Projects.ScheduleProvisioningStatus","com.azure.ai.projects.models.ScheduleRoutineTrigger":"Azure.AI.Projects.ScheduleRoutineTrigger","com.azure.ai.projects.models.ScheduleRun":"Azure.AI.Projects.ScheduleRun","com.azure.ai.projects.models.ScheduleTask":"Azure.AI.Projects.ScheduleTask","com.azure.ai.projects.models.ScheduleTaskType":"Azure.AI.Projects.ScheduleTaskType","com.azure.ai.projects.models.SimpleQnADataGenerationJobConfiguration":"Azure.AI.Projects.SimpleQnADataGenerationJobConfiguration","com.azure.ai.projects.models.SimpleQnAFineTuningQuestionType":"Azure.AI.Projects.SimpleQnAFineTuningQuestionType","com.azure.ai.projects.models.SimulationSeedDataGenerationJobConfiguration":"Azure.AI.Projects.SimulationSeedDataGenerationJobConfiguration","com.azure.ai.projects.models.SkillDetails":"Azure.AI.Projects.Skill","com.azure.ai.projects.models.SkillFileDetails":"TypeSpec.Http.File","com.azure.ai.projects.models.SkillInlineContent":"Azure.AI.Projects.SkillInlineContent","com.azure.ai.projects.models.SkillVersion":"Azure.AI.Projects.SkillVersion","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJob":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJob","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJobInputs":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJobInputs","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJobOutputConfiguration":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.Target":"Azure.AI.Projects.FoundryEvaluationTarget","com.azure.ai.projects.models.TargetConfig":"Azure.AI.Projects.RedTeamTargetConfig","com.azure.ai.projects.models.TaxonomyCategory":"Azure.AI.Projects.TaxonomyCategory","com.azure.ai.projects.models.TaxonomySubCategory":"Azure.AI.Projects.TaxonomySubCategory","com.azure.ai.projects.models.TestingCriterionAzureAIEvaluator":"Azure.AI.Projects.TestingCriterionAzureAIEvaluator","com.azure.ai.projects.models.TimerRoutineTrigger":"Azure.AI.Projects.TimerRoutineTrigger","com.azure.ai.projects.models.ToolDescription":"Azure.AI.Projects.ToolDescription","com.azure.ai.projects.models.ToolUseFineTuningDataGenerationJobConfiguration":"Azure.AI.Projects.ToolUseFineTuningDataGenerationJobConfiguration","com.azure.ai.projects.models.TracesDataGenerationJobConfiguration":"Azure.AI.Projects.TracesDataGenerationJobConfiguration","com.azure.ai.projects.models.TracesDataGenerationJobSource":"Azure.AI.Projects.TracesDataGenerationJobSource","com.azure.ai.projects.models.TracesEvaluatorGenerationJobSource":"Azure.AI.Projects.TracesEvaluatorGenerationJobSource","com.azure.ai.projects.models.TreatmentEffectType":"Azure.AI.Projects.TreatmentEffectType","com.azure.ai.projects.models.Trigger":"Azure.AI.Projects.Trigger","com.azure.ai.projects.models.TriggerType":"Azure.AI.Projects.TriggerType","com.azure.ai.projects.models.UpdateModelVersionInput":"Azure.AI.Projects.UpdateModelVersionRequest","com.azure.ai.projects.models.WeeklyRecurrenceSchedule":"Azure.AI.Projects.WeeklyRecurrenceSchedule"},"generatedFiles":["src/main/java/com/azure/ai/projects/AIProjectClientBuilder.java","src/main/java/com/azure/ai/projects/AIProjectsServiceVersion.java","src/main/java/com/azure/ai/projects/BetaAgentInsightMonitorsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaAgentInsightMonitorsClient.java","src/main/java/com/azure/ai/projects/BetaEvaluationTaxonomiesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaEvaluationTaxonomiesClient.java","src/main/java/com/azure/ai/projects/BetaEvaluatorsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaEvaluatorsClient.java","src/main/java/com/azure/ai/projects/BetaInsightsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaInsightsClient.java","src/main/java/com/azure/ai/projects/BetaModelsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaModelsClient.java","src/main/java/com/azure/ai/projects/BetaRedTeamsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaRedTeamsClient.java","src/main/java/com/azure/ai/projects/BetaRoutinesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaRoutinesClient.java","src/main/java/com/azure/ai/projects/BetaSchedulesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaSchedulesClient.java","src/main/java/com/azure/ai/projects/BetaSkillsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaSkillsClient.java","src/main/java/com/azure/ai/projects/ConnectionsAsyncClient.java","src/main/java/com/azure/ai/projects/ConnectionsClient.java","src/main/java/com/azure/ai/projects/DatasetsAsyncClient.java","src/main/java/com/azure/ai/projects/DatasetsClient.java","src/main/java/com/azure/ai/projects/DeploymentsAsyncClient.java","src/main/java/com/azure/ai/projects/DeploymentsClient.java","src/main/java/com/azure/ai/projects/EvaluationRulesAsyncClient.java","src/main/java/com/azure/ai/projects/EvaluationRulesClient.java","src/main/java/com/azure/ai/projects/EvaluatorsAsyncClient.java","src/main/java/com/azure/ai/projects/EvaluatorsClient.java","src/main/java/com/azure/ai/projects/IndexesAsyncClient.java","src/main/java/com/azure/ai/projects/IndexesClient.java","src/main/java/com/azure/ai/projects/implementation/AIProjectClientImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaAgentInsightMonitorsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaEvaluationTaxonomiesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaEvaluatorsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaInsightsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaModelsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaRedTeamsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaRoutinesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaSchedulesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaSkillsImpl.java","src/main/java/com/azure/ai/projects/implementation/ConnectionsImpl.java","src/main/java/com/azure/ai/projects/implementation/DatasetsImpl.java","src/main/java/com/azure/ai/projects/implementation/DeploymentsImpl.java","src/main/java/com/azure/ai/projects/implementation/EvaluationRulesImpl.java","src/main/java/com/azure/ai/projects/implementation/EvaluatorsImpl.java","src/main/java/com/azure/ai/projects/implementation/IndexesImpl.java","src/main/java/com/azure/ai/projects/implementation/JsonMergePatchHelper.java","src/main/java/com/azure/ai/projects/implementation/MultipartFormDataHelper.java","src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java","src/main/java/com/azure/ai/projects/implementation/PollingUtils.java","src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java","src/main/java/com/azure/ai/projects/implementation/models/CreateOrUpdateRoutineRequest.java","src/main/java/com/azure/ai/projects/implementation/models/CreateSkillVersionRequest.java","src/main/java/com/azure/ai/projects/implementation/models/DispatchRoutineAsyncRequest.java","src/main/java/com/azure/ai/projects/implementation/models/FoundryFeaturesOptInKeys.java","src/main/java/com/azure/ai/projects/implementation/models/UpdateSkillRequest.java","src/main/java/com/azure/ai/projects/implementation/models/package-info.java","src/main/java/com/azure/ai/projects/implementation/package-info.java","src/main/java/com/azure/ai/projects/models/AIProjectIndex.java","src/main/java/com/azure/ai/projects/models/AgentClusterInsightRequest.java","src/main/java/com/azure/ai/projects/models/AgentClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/AgentDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/AgentEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/AgentInsight.java","src/main/java/com/azure/ai/projects/models/AgentInsightDetails.java","src/main/java/com/azure/ai/projects/models/AgentInsightEstimatedCost.java","src/main/java/com/azure/ai/projects/models/AgentInsightHighlightedTrace.java","src/main/java/com/azure/ai/projects/models/AgentInsightLinkedTrace.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitor.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorCreate.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorListItem.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorUpdate.java","src/main/java/com/azure/ai/projects/models/AgentInsightOverviewSource.java","src/main/java/com/azure/ai/projects/models/AgentInsightPromptSurface.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFix.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFixChange.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFixKind.java","src/main/java/com/azure/ai/projects/models/AgentInsightRecommendedAction.java","src/main/java/com/azure/ai/projects/models/AgentInsightRun.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunCreate.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunResult.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunTrigger.java","src/main/java/com/azure/ai/projects/models/AgentInsightSeverity.java","src/main/java/com/azure/ai/projects/models/AgentInsightStatus.java","src/main/java/com/azure/ai/projects/models/AgentInsightSuspension.java","src/main/java/com/azure/ai/projects/models/AgentInsightTokenUsage.java","src/main/java/com/azure/ai/projects/models/AgentInsightUpdate.java","src/main/java/com/azure/ai/projects/models/AgentInsightsOverview.java","src/main/java/com/azure/ai/projects/models/AgentInsightsOverviewOverride.java","src/main/java/com/azure/ai/projects/models/AgentTaxonomyInput.java","src/main/java/com/azure/ai/projects/models/AgenticIdentityPreviewCredential.java","src/main/java/com/azure/ai/projects/models/ApiError.java","src/main/java/com/azure/ai/projects/models/ApiKeyCredential.java","src/main/java/com/azure/ai/projects/models/ArtifactProfile.java","src/main/java/com/azure/ai/projects/models/AttackStrategy.java","src/main/java/com/azure/ai/projects/models/AzureAIAgentTarget.java","src/main/java/com/azure/ai/projects/models/AzureAIModelTarget.java","src/main/java/com/azure/ai/projects/models/AzureAISearchIndex.java","src/main/java/com/azure/ai/projects/models/AzureOpenAIModelConfiguration.java","src/main/java/com/azure/ai/projects/models/BaseCredential.java","src/main/java/com/azure/ai/projects/models/BlobReference.java","src/main/java/com/azure/ai/projects/models/BlobReferenceSasCredential.java","src/main/java/com/azure/ai/projects/models/ChartCoordinate.java","src/main/java/com/azure/ai/projects/models/ClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/ClusterTokenUsage.java","src/main/java/com/azure/ai/projects/models/CodeBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/Connection.java","src/main/java/com/azure/ai/projects/models/ConnectionType.java","src/main/java/com/azure/ai/projects/models/ContinuousEvaluationRuleAction.java","src/main/java/com/azure/ai/projects/models/CosmosDBIndex.java","src/main/java/com/azure/ai/projects/models/CreateAsyncResponse.java","src/main/java/com/azure/ai/projects/models/CreateSkillVersionFromFilesBody.java","src/main/java/com/azure/ai/projects/models/CredentialType.java","src/main/java/com/azure/ai/projects/models/CronTrigger.java","src/main/java/com/azure/ai/projects/models/CustomCredential.java","src/main/java/com/azure/ai/projects/models/CustomRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/DailyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/DataGenerationJob.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutputType.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutputWriteMode.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobResult.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobScenario.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobSourceType.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobType.java","src/main/java/com/azure/ai/projects/models/DataGenerationModelOptions.java","src/main/java/com/azure/ai/projects/models/DataGenerationTokenUsage.java","src/main/java/com/azure/ai/projects/models/DatasetCredential.java","src/main/java/com/azure/ai/projects/models/DatasetDataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/DatasetEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/DatasetReference.java","src/main/java/com/azure/ai/projects/models/DatasetType.java","src/main/java/com/azure/ai/projects/models/DatasetVersion.java","src/main/java/com/azure/ai/projects/models/Deployment.java","src/main/java/com/azure/ai/projects/models/DeploymentType.java","src/main/java/com/azure/ai/projects/models/Dimension.java","src/main/java/com/azure/ai/projects/models/DispatchRoutineResult.java","src/main/java/com/azure/ai/projects/models/EmbeddingConfiguration.java","src/main/java/com/azure/ai/projects/models/EndpointBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/EntraIdCredential.java","src/main/java/com/azure/ai/projects/models/EvaluationComparisonInsightRequest.java","src/main/java/com/azure/ai/projects/models/EvaluationComparisonInsightResult.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/EvaluationLevel.java","src/main/java/com/azure/ai/projects/models/EvaluationResult.java","src/main/java/com/azure/ai/projects/models/EvaluationResultSample.java","src/main/java/com/azure/ai/projects/models/EvaluationRule.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleAction.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleActionType.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleEventType.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleFilter.java","src/main/java/com/azure/ai/projects/models/EvaluationRunClusterInsightRequest.java","src/main/java/com/azure/ai/projects/models/EvaluationRunClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultCompareItem.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultComparison.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultSummary.java","src/main/java/com/azure/ai/projects/models/EvaluationScheduleTask.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomy.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomyInput.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomyInputType.java","src/main/java/com/azure/ai/projects/models/EvaluatorCategory.java","src/main/java/com/azure/ai/projects/models/EvaluatorCredentialInput.java","src/main/java/com/azure/ai/projects/models/EvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/EvaluatorDefinitionType.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationArtifacts.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationInputs.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJob.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJobSourceType.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationTokenUsage.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetric.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetricDirection.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetricType.java","src/main/java/com/azure/ai/projects/models/EvaluatorType.java","src/main/java/com/azure/ai/projects/models/EvaluatorVersion.java","src/main/java/com/azure/ai/projects/models/FieldMapping.java","src/main/java/com/azure/ai/projects/models/FileDataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/FileDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/FileDatasetVersion.java","src/main/java/com/azure/ai/projects/models/FolderDatasetVersion.java","src/main/java/com/azure/ai/projects/models/FoundryModelArtifactProfileCategory.java","src/main/java/com/azure/ai/projects/models/FoundryModelArtifactProfileSignal.java","src/main/java/com/azure/ai/projects/models/FoundryModelSourceType.java","src/main/java/com/azure/ai/projects/models/FoundryModelWarning.java","src/main/java/com/azure/ai/projects/models/FoundryModelWarningCode.java","src/main/java/com/azure/ai/projects/models/FoundryModelWeightType.java","src/main/java/com/azure/ai/projects/models/GenerationWarningType.java","src/main/java/com/azure/ai/projects/models/GitHubIssueEvent.java","src/main/java/com/azure/ai/projects/models/GitHubIssueRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/GraderAzureAIEvaluator.java","src/main/java/com/azure/ai/projects/models/HourlyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/HumanEvaluationPreviewRuleAction.java","src/main/java/com/azure/ai/projects/models/IndexType.java","src/main/java/com/azure/ai/projects/models/Insight.java","src/main/java/com/azure/ai/projects/models/InsightCluster.java","src/main/java/com/azure/ai/projects/models/InsightModelConfiguration.java","src/main/java/com/azure/ai/projects/models/InsightRequest.java","src/main/java/com/azure/ai/projects/models/InsightResult.java","src/main/java/com/azure/ai/projects/models/InsightSample.java","src/main/java/com/azure/ai/projects/models/InsightScheduleTask.java","src/main/java/com/azure/ai/projects/models/InsightSummary.java","src/main/java/com/azure/ai/projects/models/InsightType.java","src/main/java/com/azure/ai/projects/models/InsightsMetadata.java","src/main/java/com/azure/ai/projects/models/InvokeAgentInvocationsApiDispatchPayload.java","src/main/java/com/azure/ai/projects/models/InvokeAgentInvocationsApiRoutineAction.java","src/main/java/com/azure/ai/projects/models/InvokeAgentResponsesApiDispatchPayload.java","src/main/java/com/azure/ai/projects/models/InvokeAgentResponsesApiRoutineAction.java","src/main/java/com/azure/ai/projects/models/JobStatus.java","src/main/java/com/azure/ai/projects/models/ListVersionsRequestType.java","src/main/java/com/azure/ai/projects/models/LoraConfig.java","src/main/java/com/azure/ai/projects/models/ManagedAzureAISearchIndex.java","src/main/java/com/azure/ai/projects/models/ModelCredentialInput.java","src/main/java/com/azure/ai/projects/models/ModelDeployment.java","src/main/java/com/azure/ai/projects/models/ModelDeploymentSku.java","src/main/java/com/azure/ai/projects/models/ModelPendingUploadInput.java","src/main/java/com/azure/ai/projects/models/ModelPendingUploadResult.java","src/main/java/com/azure/ai/projects/models/ModelSamplingParams.java","src/main/java/com/azure/ai/projects/models/ModelSourceData.java","src/main/java/com/azure/ai/projects/models/ModelVersion.java","src/main/java/com/azure/ai/projects/models/MonthlyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/NoAuthenticationCredential.java","src/main/java/com/azure/ai/projects/models/OneTimeTrigger.java","src/main/java/com/azure/ai/projects/models/OperationStatus.java","src/main/java/com/azure/ai/projects/models/PendingUploadRequest.java","src/main/java/com/azure/ai/projects/models/PendingUploadResponse.java","src/main/java/com/azure/ai/projects/models/PendingUploadType.java","src/main/java/com/azure/ai/projects/models/PromptBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/PromptDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/PromptEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/RecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/RecurrenceTrigger.java","src/main/java/com/azure/ai/projects/models/RecurrenceType.java","src/main/java/com/azure/ai/projects/models/RedTeam.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/RiskCategory.java","src/main/java/com/azure/ai/projects/models/Routine.java","src/main/java/com/azure/ai/projects/models/RoutineAction.java","src/main/java/com/azure/ai/projects/models/RoutineActionType.java","src/main/java/com/azure/ai/projects/models/RoutineAttemptSource.java","src/main/java/com/azure/ai/projects/models/RoutineAuthorization.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchIdentity.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchPayload.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchPayloadType.java","src/main/java/com/azure/ai/projects/models/RoutineRun.java","src/main/java/com/azure/ai/projects/models/RoutineRunPhase.java","src/main/java/com/azure/ai/projects/models/RoutineTrigger.java","src/main/java/com/azure/ai/projects/models/RoutineTriggerType.java","src/main/java/com/azure/ai/projects/models/RubricBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarning.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningCode.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningSeverity.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningSource.java","src/main/java/com/azure/ai/projects/models/SampleType.java","src/main/java/com/azure/ai/projects/models/SasCredential.java","src/main/java/com/azure/ai/projects/models/Schedule.java","src/main/java/com/azure/ai/projects/models/ScheduleProvisioningStatus.java","src/main/java/com/azure/ai/projects/models/ScheduleRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/ScheduleRun.java","src/main/java/com/azure/ai/projects/models/ScheduleTask.java","src/main/java/com/azure/ai/projects/models/ScheduleTaskType.java","src/main/java/com/azure/ai/projects/models/SimpleQnADataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/SimpleQnAFineTuningQuestionType.java","src/main/java/com/azure/ai/projects/models/SimulationSeedDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/SkillDetails.java","src/main/java/com/azure/ai/projects/models/SkillFileDetails.java","src/main/java/com/azure/ai/projects/models/SkillInlineContent.java","src/main/java/com/azure/ai/projects/models/SkillVersion.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/Target.java","src/main/java/com/azure/ai/projects/models/TargetConfig.java","src/main/java/com/azure/ai/projects/models/TaxonomyCategory.java","src/main/java/com/azure/ai/projects/models/TaxonomySubCategory.java","src/main/java/com/azure/ai/projects/models/TestingCriterionAzureAIEvaluator.java","src/main/java/com/azure/ai/projects/models/TimerRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/ToolDescription.java","src/main/java/com/azure/ai/projects/models/ToolUseFineTuningDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/TracesDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/TracesDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/TracesEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/TreatmentEffectType.java","src/main/java/com/azure/ai/projects/models/Trigger.java","src/main/java/com/azure/ai/projects/models/TriggerType.java","src/main/java/com/azure/ai/projects/models/UpdateModelVersionInput.java","src/main/java/com/azure/ai/projects/models/WeeklyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/package-info.java","src/main/java/com/azure/ai/projects/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file +{"flavor":"azure","apiVersions":{"Azure.AI.Projects":"v1"},"crossLanguagePackageId":"Azure.AI.Projects","crossLanguageVersion":"d1994575e3f7","crossLanguageDefinitions":{"com.azure.ai.projects.AIProjectClientBuilder":"Azure.AI.Projects","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient":"Azure.AI.Projects.Beta.AgentInsightMonitors","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.beginCreateAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.beginCreateAgentInsightRunWithModel":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.cancelAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.cancelAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.createAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.createAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.deleteAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.deleteAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.getAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsightMonitors":"Azure.AI.Projects.AgentInsightMonitors.list","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsightRuns":"Azure.AI.Projects.AgentInsightMonitors.listRuns","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.listAgentInsights":"Azure.AI.Projects.AgentInsightMonitors.listInsights","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.resetAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.resetAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsAsyncClient.updateAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient":"Azure.AI.Projects.Beta.AgentInsightMonitors","com.azure.ai.projects.BetaAgentInsightMonitorsClient.beginCreateAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.beginCreateAgentInsightRunWithModel":"Azure.AI.Projects.AgentInsightMonitors.createRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.cancelAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.cancelAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.cancelRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.createAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsClient.createAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.create","com.azure.ai.projects.BetaAgentInsightMonitorsClient.deleteAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsClient.deleteAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.delete","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.get","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightRun":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightRunWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getRun","com.azure.ai.projects.BetaAgentInsightMonitorsClient.getAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.getInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsightMonitors":"Azure.AI.Projects.AgentInsightMonitors.list","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsightRuns":"Azure.AI.Projects.AgentInsightMonitors.listRuns","com.azure.ai.projects.BetaAgentInsightMonitorsClient.listAgentInsights":"Azure.AI.Projects.AgentInsightMonitors.listInsights","com.azure.ai.projects.BetaAgentInsightMonitorsClient.resetAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsClient.resetAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.reset","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsight":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightMonitorWithResponse":"Azure.AI.Projects.AgentInsightMonitors.update","com.azure.ai.projects.BetaAgentInsightMonitorsClient.updateAgentInsightWithResponse":"Azure.AI.Projects.AgentInsightMonitors.updateInsight","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient":"Azure.AI.Projects.Beta.EvaluationTaxonomies","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.createEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.createEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.deleteEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.deleteEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.getEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.getEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.listEvaluationTaxonomies":"Azure.AI.Projects.EvaluationTaxonomies.list","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.updateEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesAsyncClient.updateEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesClient":"Azure.AI.Projects.Beta.EvaluationTaxonomies","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.createEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.createEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.create","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.deleteEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.deleteEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.delete","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.getEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.getEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.get","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.listEvaluationTaxonomies":"Azure.AI.Projects.EvaluationTaxonomies.list","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.updateEvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluationTaxonomiesClient.updateEvaluationTaxonomyWithResponse":"Azure.AI.Projects.EvaluationTaxonomies.update","com.azure.ai.projects.BetaEvaluatorsAsyncClient":"Azure.AI.Projects.Beta.Evaluators","com.azure.ai.projects.BetaEvaluatorsAsyncClient.getCredentials":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsAsyncClient.getCredentialsWithResponse":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsAsyncClient.startPendingUpload":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsAsyncClient.startPendingUploadWithResponse":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsClient":"Azure.AI.Projects.Beta.Evaluators","com.azure.ai.projects.BetaEvaluatorsClient.getCredentials":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsClient.getCredentialsWithResponse":"Azure.AI.Projects.Evaluators.getCredentials","com.azure.ai.projects.BetaEvaluatorsClient.startPendingUpload":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaEvaluatorsClient.startPendingUploadWithResponse":"Azure.AI.Projects.Evaluators.startPendingUpload","com.azure.ai.projects.BetaInsightsAsyncClient":"Azure.AI.Projects.Beta.Insights","com.azure.ai.projects.BetaInsightsAsyncClient.generateInsight":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsAsyncClient.generateInsightWithResponse":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsAsyncClient.getInsight":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsAsyncClient.getInsightWithResponse":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsAsyncClient.listInsights":"Azure.AI.Projects.Insights.list","com.azure.ai.projects.BetaInsightsClient":"Azure.AI.Projects.Beta.Insights","com.azure.ai.projects.BetaInsightsClient.generateInsight":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsClient.generateInsightWithResponse":"Azure.AI.Projects.Insights.generate","com.azure.ai.projects.BetaInsightsClient.getInsight":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsClient.getInsightWithResponse":"Azure.AI.Projects.Insights.get","com.azure.ai.projects.BetaInsightsClient.listInsights":"Azure.AI.Projects.Insights.list","com.azure.ai.projects.BetaModelsAsyncClient":"Azure.AI.Projects.Beta.Models","com.azure.ai.projects.BetaModelsAsyncClient.createModelVersionAsyncWithResponse":"Azure.AI.Projects.Models.createAsync","com.azure.ai.projects.BetaModelsAsyncClient.deleteModelVersion":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsAsyncClient.deleteModelVersionWithResponse":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsAsyncClient.getModelCredentials":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsAsyncClient.getModelCredentialsWithResponse":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsAsyncClient.getModelVersion":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsAsyncClient.getModelVersionWithResponse":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsAsyncClient.listLatestModelVersions":"Azure.AI.Projects.Models.listLatest","com.azure.ai.projects.BetaModelsAsyncClient.listModelVersions":"Azure.AI.Projects.Models.listVersions","com.azure.ai.projects.BetaModelsAsyncClient.startModelPendingUpload":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsAsyncClient.startModelPendingUploadWithResponse":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsAsyncClient.updateModelVersion":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsAsyncClient.updateModelVersionWithResponse":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsClient":"Azure.AI.Projects.Beta.Models","com.azure.ai.projects.BetaModelsClient.createModelVersionAsyncWithResponse":"Azure.AI.Projects.Models.createAsync","com.azure.ai.projects.BetaModelsClient.deleteModelVersion":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsClient.deleteModelVersionWithResponse":"Azure.AI.Projects.Models.deleteVersion","com.azure.ai.projects.BetaModelsClient.getModelCredentials":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsClient.getModelCredentialsWithResponse":"Azure.AI.Projects.Models.getCredentials","com.azure.ai.projects.BetaModelsClient.getModelVersion":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsClient.getModelVersionWithResponse":"Azure.AI.Projects.Models.getVersion","com.azure.ai.projects.BetaModelsClient.listLatestModelVersions":"Azure.AI.Projects.Models.listLatest","com.azure.ai.projects.BetaModelsClient.listModelVersions":"Azure.AI.Projects.Models.listVersions","com.azure.ai.projects.BetaModelsClient.startModelPendingUpload":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsClient.startModelPendingUploadWithResponse":"Azure.AI.Projects.Models.startPendingUpload","com.azure.ai.projects.BetaModelsClient.updateModelVersion":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaModelsClient.updateModelVersionWithResponse":"Azure.AI.Projects.Models.createOrUpdateVersion","com.azure.ai.projects.BetaRedTeamsAsyncClient":"Azure.AI.Projects.Beta.RedTeams","com.azure.ai.projects.BetaRedTeamsAsyncClient.createRedTeamRun":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsAsyncClient.createRedTeamRunWithResponse":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsAsyncClient.getRedTeam":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsAsyncClient.getRedTeamWithResponse":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsAsyncClient.listRedTeams":"Azure.AI.Projects.RedTeams.list","com.azure.ai.projects.BetaRedTeamsClient":"Azure.AI.Projects.Beta.RedTeams","com.azure.ai.projects.BetaRedTeamsClient.createRedTeamRun":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsClient.createRedTeamRunWithResponse":"Azure.AI.Projects.RedTeams.create","com.azure.ai.projects.BetaRedTeamsClient.getRedTeam":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsClient.getRedTeamWithResponse":"Azure.AI.Projects.RedTeams.get","com.azure.ai.projects.BetaRedTeamsClient.listRedTeams":"Azure.AI.Projects.RedTeams.list","com.azure.ai.projects.BetaRoutinesAsyncClient":"Azure.AI.Projects.Beta.Routines","com.azure.ai.projects.BetaRoutinesAsyncClient.createOrUpdateRoutine":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.createOrUpdateRoutineWithResponse":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.deleteRoutine":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.deleteRoutineWithResponse":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.disableRoutine":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.disableRoutineWithResponse":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.dispatchRoutine":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesAsyncClient.dispatchRoutineWithResponse":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesAsyncClient.enableRoutine":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.enableRoutineWithResponse":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.getRoutine":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.getRoutineWithResponse":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesAsyncClient.listRoutineRuns":"Azure.AI.Projects.Routines.listRoutineRuns","com.azure.ai.projects.BetaRoutinesAsyncClient.listRoutines":"Azure.AI.Projects.Routines.listRoutines","com.azure.ai.projects.BetaRoutinesClient":"Azure.AI.Projects.Beta.Routines","com.azure.ai.projects.BetaRoutinesClient.createOrUpdateRoutine":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesClient.createOrUpdateRoutineWithResponse":"Azure.AI.Projects.Routines.createOrUpdateRoutine","com.azure.ai.projects.BetaRoutinesClient.deleteRoutine":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesClient.deleteRoutineWithResponse":"Azure.AI.Projects.Routines.deleteRoutine","com.azure.ai.projects.BetaRoutinesClient.disableRoutine":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesClient.disableRoutineWithResponse":"Azure.AI.Projects.Routines.disableRoutine","com.azure.ai.projects.BetaRoutinesClient.dispatchRoutine":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesClient.dispatchRoutineWithResponse":"Azure.AI.Projects.Routines.dispatchRoutineAsync","com.azure.ai.projects.BetaRoutinesClient.enableRoutine":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesClient.enableRoutineWithResponse":"Azure.AI.Projects.Routines.enableRoutine","com.azure.ai.projects.BetaRoutinesClient.getRoutine":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesClient.getRoutineWithResponse":"Azure.AI.Projects.Routines.getRoutine","com.azure.ai.projects.BetaRoutinesClient.listRoutineRuns":"Azure.AI.Projects.Routines.listRoutineRuns","com.azure.ai.projects.BetaRoutinesClient.listRoutines":"Azure.AI.Projects.Routines.listRoutines","com.azure.ai.projects.BetaSchedulesAsyncClient":"Azure.AI.Projects.Beta.Schedules","com.azure.ai.projects.BetaSchedulesAsyncClient.createOrUpdateSchedule":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesAsyncClient.createOrUpdateScheduleWithResponse":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesAsyncClient.deleteSchedule":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesAsyncClient.deleteScheduleWithResponse":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesAsyncClient.getSchedule":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleRun":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleRunWithResponse":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesAsyncClient.getScheduleWithResponse":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesAsyncClient.listScheduleRuns":"Azure.AI.Projects.Schedules.listRuns","com.azure.ai.projects.BetaSchedulesAsyncClient.listSchedules":"Azure.AI.Projects.Schedules.list","com.azure.ai.projects.BetaSchedulesClient":"Azure.AI.Projects.Beta.Schedules","com.azure.ai.projects.BetaSchedulesClient.createOrUpdateSchedule":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesClient.createOrUpdateScheduleWithResponse":"Azure.AI.Projects.Schedules.createOrUpdate","com.azure.ai.projects.BetaSchedulesClient.deleteSchedule":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesClient.deleteScheduleWithResponse":"Azure.AI.Projects.Schedules.delete","com.azure.ai.projects.BetaSchedulesClient.getSchedule":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesClient.getScheduleRun":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesClient.getScheduleRunWithResponse":"Azure.AI.Projects.Schedules.getRun","com.azure.ai.projects.BetaSchedulesClient.getScheduleWithResponse":"Azure.AI.Projects.Schedules.get","com.azure.ai.projects.BetaSchedulesClient.listScheduleRuns":"Azure.AI.Projects.Schedules.listRuns","com.azure.ai.projects.BetaSchedulesClient.listSchedules":"Azure.AI.Projects.Schedules.list","com.azure.ai.projects.BetaSkillsAsyncClient":"Azure.AI.Projects.Beta.Skills","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersion":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionFromFiles":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionFromFilesWithResponseInternal":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsAsyncClient.createSkillVersionWithResponse":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkill":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillContent":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillContentWithResponse":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersion":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionContent":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionContentWithResponse":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillVersionWithResponse":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsAsyncClient.getSkillWithResponse":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsAsyncClient.listSkillVersions":"Azure.AI.Projects.Skills.listSkillVersions","com.azure.ai.projects.BetaSkillsAsyncClient.listSkills":"Azure.AI.Projects.Skills.listSkills","com.azure.ai.projects.BetaSkillsAsyncClient.updateSkill":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsAsyncClient.updateSkillWithResponse":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsClient":"Azure.AI.Projects.Beta.Skills","com.azure.ai.projects.BetaSkillsClient.createSkillVersion":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsClient.createSkillVersionFromFiles":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsClient.createSkillVersionFromFilesWithResponseInternal":"Azure.AI.Projects.Skills.createSkillVersionFromFiles","com.azure.ai.projects.BetaSkillsClient.createSkillVersionWithResponse":"Azure.AI.Projects.Skills.createSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkill":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsClient.getSkillContent":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsClient.getSkillContentWithResponse":"Azure.AI.Projects.Skills.getSkillContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersion":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkillVersionContent":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersionContentWithResponse":"Azure.AI.Projects.Skills.getSkillVersionContent","com.azure.ai.projects.BetaSkillsClient.getSkillVersionWithResponse":"Azure.AI.Projects.Skills.getSkillVersion","com.azure.ai.projects.BetaSkillsClient.getSkillWithResponse":"Azure.AI.Projects.Skills.getSkill","com.azure.ai.projects.BetaSkillsClient.listSkillVersions":"Azure.AI.Projects.Skills.listSkillVersions","com.azure.ai.projects.BetaSkillsClient.listSkills":"Azure.AI.Projects.Skills.listSkills","com.azure.ai.projects.BetaSkillsClient.updateSkill":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.BetaSkillsClient.updateSkillWithResponse":"Azure.AI.Projects.Skills.updateSkill","com.azure.ai.projects.ConnectionsAsyncClient":"Azure.AI.Projects.Connections","com.azure.ai.projects.ConnectionsAsyncClient.getConnection":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithCredentials":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithCredentialsWithResponse":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsAsyncClient.getConnectionWithResponse":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsAsyncClient.listConnections":"Azure.AI.Projects.Connections.list","com.azure.ai.projects.ConnectionsClient":"Azure.AI.Projects.Connections","com.azure.ai.projects.ConnectionsClient.getConnection":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsClient.getConnectionWithCredentials":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsClient.getConnectionWithCredentialsWithResponse":"Azure.AI.Projects.Connections.getWithCredentials","com.azure.ai.projects.ConnectionsClient.getConnectionWithResponse":"Azure.AI.Projects.Connections.get","com.azure.ai.projects.ConnectionsClient.listConnections":"Azure.AI.Projects.Connections.list","com.azure.ai.projects.DatasetsAsyncClient":"Azure.AI.Projects.Datasets","com.azure.ai.projects.DatasetsAsyncClient.beginCreateGenerationJob":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsAsyncClient.beginCreateGenerationJobWithModel":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsAsyncClient.cancelGenerationJob":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsAsyncClient.cancelGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsAsyncClient.createOrUpdateDatasetVersion":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsAsyncClient.createOrUpdateDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteDatasetVersion":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsAsyncClient.deleteGenerationJob":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsAsyncClient.deleteGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsAsyncClient.getCredentials":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsAsyncClient.getCredentialsWithResponse":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsAsyncClient.getDatasetVersion":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsAsyncClient.getDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsAsyncClient.getGenerationJob":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsAsyncClient.getGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsAsyncClient.listDatasetVersions":"Azure.AI.Projects.Datasets.listVersions","com.azure.ai.projects.DatasetsAsyncClient.listGenerationJobs":"Azure.AI.Projects.DataGenerationJobs.list","com.azure.ai.projects.DatasetsAsyncClient.listLatestDatasetVersions":"Azure.AI.Projects.Datasets.listLatest","com.azure.ai.projects.DatasetsAsyncClient.pendingUpload":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsAsyncClient.pendingUploadWithResponse":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsClient":"Azure.AI.Projects.Datasets","com.azure.ai.projects.DatasetsClient.beginCreateGenerationJob":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsClient.beginCreateGenerationJobWithModel":"Azure.AI.Projects.DataGenerationJobs.create","com.azure.ai.projects.DatasetsClient.cancelGenerationJob":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsClient.cancelGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.cancel","com.azure.ai.projects.DatasetsClient.createOrUpdateDatasetVersion":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsClient.createOrUpdateDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.createOrUpdateVersion","com.azure.ai.projects.DatasetsClient.deleteDatasetVersion":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsClient.deleteDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.deleteVersion","com.azure.ai.projects.DatasetsClient.deleteGenerationJob":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsClient.deleteGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.delete","com.azure.ai.projects.DatasetsClient.getCredentials":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsClient.getCredentialsWithResponse":"Azure.AI.Projects.Datasets.getCredentials","com.azure.ai.projects.DatasetsClient.getDatasetVersion":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsClient.getDatasetVersionWithResponse":"Azure.AI.Projects.Datasets.getVersion","com.azure.ai.projects.DatasetsClient.getGenerationJob":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsClient.getGenerationJobWithResponse":"Azure.AI.Projects.DataGenerationJobs.get","com.azure.ai.projects.DatasetsClient.listDatasetVersions":"Azure.AI.Projects.Datasets.listVersions","com.azure.ai.projects.DatasetsClient.listGenerationJobs":"Azure.AI.Projects.DataGenerationJobs.list","com.azure.ai.projects.DatasetsClient.listLatestDatasetVersions":"Azure.AI.Projects.Datasets.listLatest","com.azure.ai.projects.DatasetsClient.pendingUpload":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DatasetsClient.pendingUploadWithResponse":"Azure.AI.Projects.Datasets.startPendingUploadVersion","com.azure.ai.projects.DeploymentsAsyncClient":"Azure.AI.Projects.Deployments","com.azure.ai.projects.DeploymentsAsyncClient.getDeployment":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsAsyncClient.getDeploymentWithResponse":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsAsyncClient.listDeployments":"Azure.AI.Projects.Deployments.list","com.azure.ai.projects.DeploymentsClient":"Azure.AI.Projects.Deployments","com.azure.ai.projects.DeploymentsClient.getDeployment":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsClient.getDeploymentWithResponse":"Azure.AI.Projects.Deployments.get","com.azure.ai.projects.DeploymentsClient.listDeployments":"Azure.AI.Projects.Deployments.list","com.azure.ai.projects.EvaluationRulesAsyncClient":"Azure.AI.Projects.EvaluationRules","com.azure.ai.projects.EvaluationRulesAsyncClient.createOrUpdateEvaluationRule":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesAsyncClient.createOrUpdateEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesAsyncClient.deleteEvaluationRule":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesAsyncClient.deleteEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesAsyncClient.getEvaluationRule":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesAsyncClient.getEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesAsyncClient.listEvaluationRules":"Azure.AI.Projects.EvaluationRules.list","com.azure.ai.projects.EvaluationRulesClient":"Azure.AI.Projects.EvaluationRules","com.azure.ai.projects.EvaluationRulesClient.createOrUpdateEvaluationRule":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesClient.createOrUpdateEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.createOrUpdate","com.azure.ai.projects.EvaluationRulesClient.deleteEvaluationRule":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesClient.deleteEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.delete","com.azure.ai.projects.EvaluationRulesClient.getEvaluationRule":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesClient.getEvaluationRuleWithResponse":"Azure.AI.Projects.EvaluationRules.get","com.azure.ai.projects.EvaluationRulesClient.listEvaluationRules":"Azure.AI.Projects.EvaluationRules.list","com.azure.ai.projects.EvaluatorsAsyncClient":"Azure.AI.Projects.Evaluators","com.azure.ai.projects.EvaluatorsAsyncClient.beginCreateEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsAsyncClient.beginCreateEvaluatorGenerationJobWithModel":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsAsyncClient.cancelEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsAsyncClient.cancelEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsAsyncClient.createEvaluatorVersion":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsAsyncClient.createEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorVersion":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsAsyncClient.deleteEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorVersion":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsAsyncClient.getEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsAsyncClient.listEvaluatorGenerationJobs":"Azure.AI.Projects.EvaluatorGenerationJobs.list","com.azure.ai.projects.EvaluatorsAsyncClient.listEvaluatorVersions":"Azure.AI.Projects.Evaluators.listVersions","com.azure.ai.projects.EvaluatorsAsyncClient.listLatestEvaluatorVersions":"Azure.AI.Projects.Evaluators.listLatestVersions","com.azure.ai.projects.EvaluatorsAsyncClient.updateEvaluatorVersion":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsAsyncClient.updateEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsClient":"Azure.AI.Projects.Evaluators","com.azure.ai.projects.EvaluatorsClient.beginCreateEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsClient.beginCreateEvaluatorGenerationJobWithModel":"Azure.AI.Projects.EvaluatorGenerationJobs.create","com.azure.ai.projects.EvaluatorsClient.cancelEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsClient.cancelEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.cancel","com.azure.ai.projects.EvaluatorsClient.createEvaluatorVersion":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsClient.createEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.createVersion","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.delete","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorVersion":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsClient.deleteEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.deleteVersion","com.azure.ai.projects.EvaluatorsClient.getEvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsClient.getEvaluatorGenerationJobWithResponse":"Azure.AI.Projects.EvaluatorGenerationJobs.get","com.azure.ai.projects.EvaluatorsClient.getEvaluatorVersion":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsClient.getEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.getVersion","com.azure.ai.projects.EvaluatorsClient.listEvaluatorGenerationJobs":"Azure.AI.Projects.EvaluatorGenerationJobs.list","com.azure.ai.projects.EvaluatorsClient.listEvaluatorVersions":"Azure.AI.Projects.Evaluators.listVersions","com.azure.ai.projects.EvaluatorsClient.listLatestEvaluatorVersions":"Azure.AI.Projects.Evaluators.listLatestVersions","com.azure.ai.projects.EvaluatorsClient.updateEvaluatorVersion":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.EvaluatorsClient.updateEvaluatorVersionWithResponse":"Azure.AI.Projects.Evaluators.updateVersion","com.azure.ai.projects.IndexesAsyncClient":"Azure.AI.Projects.Indexes","com.azure.ai.projects.IndexesAsyncClient.createOrUpdateIndexVersion":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesAsyncClient.createOrUpdateIndexVersionWithResponse":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesAsyncClient.deleteIndexVersion":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesAsyncClient.deleteIndexVersionWithResponse":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesAsyncClient.getIndexVersion":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesAsyncClient.getIndexVersionWithResponse":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesAsyncClient.listIndexVersions":"Azure.AI.Projects.Indexes.listVersions","com.azure.ai.projects.IndexesAsyncClient.listLatestIndexVersions":"Azure.AI.Projects.Indexes.listLatest","com.azure.ai.projects.IndexesClient":"Azure.AI.Projects.Indexes","com.azure.ai.projects.IndexesClient.createOrUpdateIndexVersion":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesClient.createOrUpdateIndexVersionWithResponse":"Azure.AI.Projects.Indexes.createOrUpdateVersion","com.azure.ai.projects.IndexesClient.deleteIndexVersion":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesClient.deleteIndexVersionWithResponse":"Azure.AI.Projects.Indexes.deleteVersion","com.azure.ai.projects.IndexesClient.getIndexVersion":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesClient.getIndexVersionWithResponse":"Azure.AI.Projects.Indexes.getVersion","com.azure.ai.projects.IndexesClient.listIndexVersions":"Azure.AI.Projects.Indexes.listVersions","com.azure.ai.projects.IndexesClient.listLatestIndexVersions":"Azure.AI.Projects.Indexes.listLatest","com.azure.ai.projects.implementation.models.CreateOrUpdateRoutineRequest":"Azure.AI.Projects.createOrUpdateRoutine.Request.anonymous","com.azure.ai.projects.implementation.models.CreateSkillVersionRequest":"Azure.AI.Projects.createSkillVersion.Request.anonymous","com.azure.ai.projects.implementation.models.DispatchRoutineAsyncRequest":"Azure.AI.Projects.dispatchRoutineAsync.Request.anonymous","com.azure.ai.projects.implementation.models.FoundryFeaturesOptInKeys":"Azure.AI.Projects.FoundryFeaturesOptInKeys","com.azure.ai.projects.implementation.models.UpdateSkillRequest":"Azure.AI.Projects.updateSkill.Request.anonymous","com.azure.ai.projects.models.AIProjectIndex":"Azure.AI.Projects.Index","com.azure.ai.projects.models.AgentClusterInsightRequest":"Azure.AI.Projects.AgentClusterInsightRequest","com.azure.ai.projects.models.AgentClusterInsightResult":"Azure.AI.Projects.AgentClusterInsightResult","com.azure.ai.projects.models.AgentDataGenerationJobSource":"Azure.AI.Projects.AgentDataGenerationJobSource","com.azure.ai.projects.models.AgentEvaluatorGenerationJobSource":"Azure.AI.Projects.AgentEvaluatorGenerationJobSource","com.azure.ai.projects.models.AgentInsight":"Azure.AI.Projects.AgentInsight","com.azure.ai.projects.models.AgentInsightDetails":"Azure.AI.Projects.AgentInsightDetails","com.azure.ai.projects.models.AgentInsightEstimatedCost":"Azure.AI.Projects.AgentInsightEstimatedCost","com.azure.ai.projects.models.AgentInsightHighlightedTrace":"Azure.AI.Projects.AgentInsightHighlightedTrace","com.azure.ai.projects.models.AgentInsightLinkedTrace":"Azure.AI.Projects.AgentInsightLinkedTrace","com.azure.ai.projects.models.AgentInsightMonitor":"Azure.AI.Projects.AgentInsightMonitor","com.azure.ai.projects.models.AgentInsightMonitorCreate":"Azure.AI.Projects.AgentInsightMonitorCreate","com.azure.ai.projects.models.AgentInsightMonitorListItem":"Azure.AI.Projects.AgentInsightMonitorListItem","com.azure.ai.projects.models.AgentInsightMonitorUpdate":"Azure.AI.Projects.AgentInsightMonitorUpdate","com.azure.ai.projects.models.AgentInsightOverviewSource":"Azure.AI.Projects.AgentInsightOverviewSource","com.azure.ai.projects.models.AgentInsightPromptSurface":"Azure.AI.Projects.AgentInsightPromptSurface","com.azure.ai.projects.models.AgentInsightProposedFix":"Azure.AI.Projects.AgentInsightProposedFix","com.azure.ai.projects.models.AgentInsightProposedFixChange":"Azure.AI.Projects.AgentInsightProposedFixChange","com.azure.ai.projects.models.AgentInsightProposedFixKind":"Azure.AI.Projects.AgentInsightProposedFixKind","com.azure.ai.projects.models.AgentInsightRecommendedAction":"Azure.AI.Projects.AgentInsightRecommendedAction","com.azure.ai.projects.models.AgentInsightRun":"Azure.AI.Projects.AgentInsightRun","com.azure.ai.projects.models.AgentInsightRunCreate":"Azure.AI.Projects.AgentInsightRunCreate","com.azure.ai.projects.models.AgentInsightRunResult":"Azure.AI.Projects.AgentInsightRunResult","com.azure.ai.projects.models.AgentInsightRunTrigger":"Azure.AI.Projects.AgentInsightRunTrigger","com.azure.ai.projects.models.AgentInsightSeverity":"Azure.AI.Projects.AgentInsightSeverity","com.azure.ai.projects.models.AgentInsightStatus":"Azure.AI.Projects.AgentInsightStatus","com.azure.ai.projects.models.AgentInsightSuspension":"Azure.AI.Projects.AgentInsightSuspension","com.azure.ai.projects.models.AgentInsightTokenUsage":"Azure.AI.Projects.AgentInsightTokenUsage","com.azure.ai.projects.models.AgentInsightUpdate":"Azure.AI.Projects.AgentInsightUpdate","com.azure.ai.projects.models.AgentInsightsOverview":"Azure.AI.Projects.AgentInsightsOverview","com.azure.ai.projects.models.AgentInsightsOverviewOverride":"Azure.AI.Projects.AgentInsightsOverviewOverride","com.azure.ai.projects.models.AgentTaxonomyInput":"Azure.AI.Projects.AgentTaxonomyInput","com.azure.ai.projects.models.AgenticIdentityPreviewCredential":"Azure.AI.Projects.AgenticIdentityPreviewCredentials","com.azure.ai.projects.models.ApiError":"OpenAI.Error","com.azure.ai.projects.models.ApiKeyCredential":"Azure.AI.Projects.ApiKeyCredentials","com.azure.ai.projects.models.ArtifactProfile":"Azure.AI.Projects.ArtifactProfile","com.azure.ai.projects.models.AttackStrategy":"Azure.AI.Projects.AttackStrategy","com.azure.ai.projects.models.AzureAIAgentTarget":"Azure.AI.Projects.AzureAIAgentTarget","com.azure.ai.projects.models.AzureAIModelTarget":"Azure.AI.Projects.AzureAIModelTarget","com.azure.ai.projects.models.AzureAISearchIndex":"Azure.AI.Projects.AzureAISearchIndex","com.azure.ai.projects.models.AzureOpenAIModelConfiguration":"Azure.AI.Projects.AzureOpenAIModelConfiguration","com.azure.ai.projects.models.BaseCredential":"Azure.AI.Projects.BaseCredentials","com.azure.ai.projects.models.BlobReference":"Azure.AI.Projects.BlobReference","com.azure.ai.projects.models.BlobReferenceSasCredential":"Azure.AI.Projects.SasCredential","com.azure.ai.projects.models.ChartCoordinate":"Azure.AI.Projects.ChartCoordinate","com.azure.ai.projects.models.ClusterInsightResult":"Azure.AI.Projects.ClusterInsightResult","com.azure.ai.projects.models.ClusterTokenUsage":"Azure.AI.Projects.ClusterTokenUsage","com.azure.ai.projects.models.CodeBasedEvaluatorDefinition":"Azure.AI.Projects.CodeBasedEvaluatorDefinition","com.azure.ai.projects.models.Connection":"Azure.AI.Projects.Connection","com.azure.ai.projects.models.ConnectionType":"Azure.AI.Projects.ConnectionType","com.azure.ai.projects.models.ContinuousEvaluationRuleAction":"Azure.AI.Projects.ContinuousEvaluationRuleAction","com.azure.ai.projects.models.CosmosDBIndex":"Azure.AI.Projects.CosmosDBIndex","com.azure.ai.projects.models.CreateAsyncResponse":"Azure.AI.Projects.createAsync.Response.anonymous","com.azure.ai.projects.models.CreateSkillVersionFromFilesBody":"Azure.AI.Projects.CreateSkillVersionFromFilesBody","com.azure.ai.projects.models.CredentialType":"Azure.AI.Projects.CredentialType","com.azure.ai.projects.models.CronTrigger":"Azure.AI.Projects.CronTrigger","com.azure.ai.projects.models.CustomCredential":"Azure.AI.Projects.CustomCredential","com.azure.ai.projects.models.CustomRoutineTrigger":"Azure.AI.Projects.CustomRoutineTrigger","com.azure.ai.projects.models.DailyRecurrenceSchedule":"Azure.AI.Projects.DailyRecurrenceSchedule","com.azure.ai.projects.models.DataGenerationJob":"Azure.AI.Projects.DataGenerationJob","com.azure.ai.projects.models.DataGenerationJobConfiguration":"Azure.AI.Projects.DataGenerationJobConfiguration","com.azure.ai.projects.models.DataGenerationJobInputs":"Azure.AI.Projects.DataGenerationJobInputs","com.azure.ai.projects.models.DataGenerationJobOutput":"Azure.AI.Projects.DataGenerationJobOutput","com.azure.ai.projects.models.DataGenerationJobOutputType":"Azure.AI.Projects.DataGenerationJobOutputType","com.azure.ai.projects.models.DataGenerationJobOutputWriteMode":"Azure.AI.Projects.DataGenerationJobOutputWriteMode","com.azure.ai.projects.models.DataGenerationJobResult":"Azure.AI.Projects.DataGenerationJobResult","com.azure.ai.projects.models.DataGenerationJobScenario":"Azure.AI.Projects.DataGenerationJobScenario","com.azure.ai.projects.models.DataGenerationJobSource":"Azure.AI.Projects.DataGenerationJobSource","com.azure.ai.projects.models.DataGenerationJobSourceType":"Azure.AI.Projects.DataGenerationJobSourceType","com.azure.ai.projects.models.DataGenerationJobType":"Azure.AI.Projects.DataGenerationJobType","com.azure.ai.projects.models.DataGenerationModelOptions":"Azure.AI.Projects.DataGenerationModelOptions","com.azure.ai.projects.models.DataGenerationTokenUsage":"Azure.AI.Projects.DataGenerationTokenUsage","com.azure.ai.projects.models.DatasetCredential":"Azure.AI.Projects.AssetCredentialResponse","com.azure.ai.projects.models.DatasetDataGenerationJobOutput":"Azure.AI.Projects.DatasetDataGenerationJobOutput","com.azure.ai.projects.models.DatasetEvaluatorGenerationJobSource":"Azure.AI.Projects.DatasetEvaluatorGenerationJobSource","com.azure.ai.projects.models.DatasetReference":"Azure.AI.Projects.VersionedDatasetReference","com.azure.ai.projects.models.DatasetType":"Azure.AI.Projects.DatasetType","com.azure.ai.projects.models.DatasetVersion":"Azure.AI.Projects.DatasetVersion","com.azure.ai.projects.models.Deployment":"Azure.AI.Projects.Deployment","com.azure.ai.projects.models.DeploymentType":"Azure.AI.Projects.DeploymentType","com.azure.ai.projects.models.Dimension":"Azure.AI.Projects.Dimension","com.azure.ai.projects.models.DispatchRoutineResult":"Azure.AI.Projects.DispatchRoutineResponse","com.azure.ai.projects.models.EmbeddingConfiguration":"Azure.AI.Projects.EmbeddingConfiguration","com.azure.ai.projects.models.EndpointBasedEvaluatorDefinition":"Azure.AI.Projects.EndpointBasedEvaluatorDefinition","com.azure.ai.projects.models.EntraIdCredential":"Azure.AI.Projects.EntraIDCredentials","com.azure.ai.projects.models.EvaluationComparisonInsightRequest":"Azure.AI.Projects.EvaluationComparisonInsightRequest","com.azure.ai.projects.models.EvaluationComparisonInsightResult":"Azure.AI.Projects.EvaluationComparisonInsightResult","com.azure.ai.projects.models.EvaluationDataGenerationJob":"Azure.AI.Projects.EvaluationDataGenerationJob","com.azure.ai.projects.models.EvaluationDataGenerationJobInputs":"Azure.AI.Projects.EvaluationDataGenerationJobInputs","com.azure.ai.projects.models.EvaluationDataGenerationJobOutputConfiguration":"Azure.AI.Projects.EvaluationDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.EvaluationLevel":"Azure.AI.Projects.EvaluationLevel","com.azure.ai.projects.models.EvaluationResult":"Azure.AI.Projects.EvalResult","com.azure.ai.projects.models.EvaluationResultSample":"Azure.AI.Projects.EvaluationResultSample","com.azure.ai.projects.models.EvaluationRule":"Azure.AI.Projects.EvaluationRule","com.azure.ai.projects.models.EvaluationRuleAction":"Azure.AI.Projects.EvaluationRuleAction","com.azure.ai.projects.models.EvaluationRuleActionType":"Azure.AI.Projects.EvaluationRuleActionType","com.azure.ai.projects.models.EvaluationRuleEventType":"Azure.AI.Projects.EvaluationRuleEventType","com.azure.ai.projects.models.EvaluationRuleFilter":"Azure.AI.Projects.EvaluationRuleFilter","com.azure.ai.projects.models.EvaluationRunClusterInsightRequest":"Azure.AI.Projects.EvaluationRunClusterInsightRequest","com.azure.ai.projects.models.EvaluationRunClusterInsightResult":"Azure.AI.Projects.EvaluationRunClusterInsightResult","com.azure.ai.projects.models.EvaluationRunResultCompareItem":"Azure.AI.Projects.EvalRunResultCompareItem","com.azure.ai.projects.models.EvaluationRunResultComparison":"Azure.AI.Projects.EvalRunResultComparison","com.azure.ai.projects.models.EvaluationRunResultSummary":"Azure.AI.Projects.EvalRunResultSummary","com.azure.ai.projects.models.EvaluationScheduleTask":"Azure.AI.Projects.EvaluationScheduleTask","com.azure.ai.projects.models.EvaluationTaxonomy":"Azure.AI.Projects.EvaluationTaxonomy","com.azure.ai.projects.models.EvaluationTaxonomyInput":"Azure.AI.Projects.EvaluationTaxonomyInput","com.azure.ai.projects.models.EvaluationTaxonomyInputType":"Azure.AI.Projects.EvaluationTaxonomyInputType","com.azure.ai.projects.models.EvaluatorCategory":"Azure.AI.Projects.EvaluatorCategory","com.azure.ai.projects.models.EvaluatorCredentialInput":"Azure.AI.Projects.EvaluatorCredentialRequest","com.azure.ai.projects.models.EvaluatorDefinition":"Azure.AI.Projects.EvaluatorDefinition","com.azure.ai.projects.models.EvaluatorDefinitionType":"Azure.AI.Projects.EvaluatorDefinitionType","com.azure.ai.projects.models.EvaluatorGenerationArtifacts":"Azure.AI.Projects.EvaluatorGenerationArtifacts","com.azure.ai.projects.models.EvaluatorGenerationInputs":"Azure.AI.Projects.EvaluatorGenerationInputs","com.azure.ai.projects.models.EvaluatorGenerationJob":"Azure.AI.Projects.EvaluatorGenerationJob","com.azure.ai.projects.models.EvaluatorGenerationJobSource":"Azure.AI.Projects.EvaluatorGenerationJobSource","com.azure.ai.projects.models.EvaluatorGenerationJobSourceType":"Azure.AI.Projects.EvaluatorGenerationJobSourceType","com.azure.ai.projects.models.EvaluatorGenerationTokenUsage":"Azure.AI.Projects.EvaluatorGenerationTokenUsage","com.azure.ai.projects.models.EvaluatorMetric":"Azure.AI.Projects.EvaluatorMetric","com.azure.ai.projects.models.EvaluatorMetricDirection":"Azure.AI.Projects.EvaluatorMetricDirection","com.azure.ai.projects.models.EvaluatorMetricType":"Azure.AI.Projects.EvaluatorMetricType","com.azure.ai.projects.models.EvaluatorType":"Azure.AI.Projects.EvaluatorType","com.azure.ai.projects.models.EvaluatorVersion":"Azure.AI.Projects.EvaluatorVersion","com.azure.ai.projects.models.FieldMapping":"Azure.AI.Projects.FieldMapping","com.azure.ai.projects.models.FileDataGenerationJobOutput":"Azure.AI.Projects.FileDataGenerationJobOutput","com.azure.ai.projects.models.FileDataGenerationJobSource":"Azure.AI.Projects.FileDataGenerationJobSource","com.azure.ai.projects.models.FileDatasetVersion":"Azure.AI.Projects.FileDatasetVersion","com.azure.ai.projects.models.FolderDatasetVersion":"Azure.AI.Projects.FolderDatasetVersion","com.azure.ai.projects.models.FoundryModelArtifactProfileCategory":"Azure.AI.Projects.FoundryModelArtifactProfileCategory","com.azure.ai.projects.models.FoundryModelArtifactProfileSignal":"Azure.AI.Projects.FoundryModelArtifactProfileSignal","com.azure.ai.projects.models.FoundryModelSourceType":"Azure.AI.Projects.FoundryModelSourceType","com.azure.ai.projects.models.FoundryModelWarning":"Azure.AI.Projects.FoundryModelWarning","com.azure.ai.projects.models.FoundryModelWarningCode":"Azure.AI.Projects.FoundryModelWarningCode","com.azure.ai.projects.models.FoundryModelWeightType":"Azure.AI.Projects.FoundryModelWeightType","com.azure.ai.projects.models.GenerationWarningType":"Azure.AI.Projects.GenerationWarningType","com.azure.ai.projects.models.GitHubIssueEvent":"Azure.AI.Projects.GitHubIssueEvent","com.azure.ai.projects.models.GitHubIssueRoutineTrigger":"Azure.AI.Projects.GitHubIssueRoutineTrigger","com.azure.ai.projects.models.GraderAzureAIEvaluator":"Azure.AI.Projects.GraderAzureAIEvaluator","com.azure.ai.projects.models.HourlyRecurrenceSchedule":"Azure.AI.Projects.HourlyRecurrenceSchedule","com.azure.ai.projects.models.HumanEvaluationPreviewRuleAction":"Azure.AI.Projects.HumanEvaluationPreviewRuleAction","com.azure.ai.projects.models.IndexType":"Azure.AI.Projects.IndexType","com.azure.ai.projects.models.Insight":"Azure.AI.Projects.Insight","com.azure.ai.projects.models.InsightCluster":"Azure.AI.Projects.InsightCluster","com.azure.ai.projects.models.InsightModelConfiguration":"Azure.AI.Projects.InsightModelConfiguration","com.azure.ai.projects.models.InsightRequest":"Azure.AI.Projects.InsightRequest","com.azure.ai.projects.models.InsightResult":"Azure.AI.Projects.InsightResult","com.azure.ai.projects.models.InsightSample":"Azure.AI.Projects.InsightSample","com.azure.ai.projects.models.InsightScheduleTask":"Azure.AI.Projects.InsightScheduleTask","com.azure.ai.projects.models.InsightSummary":"Azure.AI.Projects.InsightSummary","com.azure.ai.projects.models.InsightType":"Azure.AI.Projects.InsightType","com.azure.ai.projects.models.InsightsMetadata":"Azure.AI.Projects.InsightsMetadata","com.azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload":"Azure.AI.Projects.InvokeAgentInvocationsApiDispatchPayload","com.azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction":"Azure.AI.Projects.InvokeAgentInvocationsApiRoutineAction","com.azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload":"Azure.AI.Projects.InvokeAgentResponsesApiDispatchPayload","com.azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction":"Azure.AI.Projects.InvokeAgentResponsesApiRoutineAction","com.azure.ai.projects.models.JobStatus":"Azure.AI.Projects.JobStatus","com.azure.ai.projects.models.ListVersionsRequestType":"Azure.AI.Projects.listVersions.RequestType.anonymous","com.azure.ai.projects.models.LoraConfig":"Azure.AI.Projects.LoraConfig","com.azure.ai.projects.models.ManagedAzureAISearchIndex":"Azure.AI.Projects.ManagedAzureAISearchIndex","com.azure.ai.projects.models.ModelCredentialInput":"Azure.AI.Projects.ModelCredentialRequest","com.azure.ai.projects.models.ModelDeployment":"Azure.AI.Projects.ModelDeployment","com.azure.ai.projects.models.ModelDeploymentSku":"Azure.AI.Projects.Sku","com.azure.ai.projects.models.ModelPendingUploadInput":"Azure.AI.Projects.ModelPendingUploadRequest","com.azure.ai.projects.models.ModelPendingUploadResult":"Azure.AI.Projects.ModelPendingUploadResponse","com.azure.ai.projects.models.ModelSamplingParams":"Azure.AI.Projects.ModelSamplingParams","com.azure.ai.projects.models.ModelSourceData":"Azure.AI.Projects.ModelSourceData","com.azure.ai.projects.models.ModelVersion":"Azure.AI.Projects.ModelVersion","com.azure.ai.projects.models.MonthlyRecurrenceSchedule":"Azure.AI.Projects.MonthlyRecurrenceSchedule","com.azure.ai.projects.models.NoAuthenticationCredential":"Azure.AI.Projects.NoAuthenticationCredentials","com.azure.ai.projects.models.OneTimeTrigger":"Azure.AI.Projects.OneTimeTrigger","com.azure.ai.projects.models.OperationStatus":"Azure.Core.Foundations.OperationState","com.azure.ai.projects.models.PendingUploadRequest":"Azure.AI.Projects.PendingUploadRequest","com.azure.ai.projects.models.PendingUploadResponse":"Azure.AI.Projects.PendingUploadResponse","com.azure.ai.projects.models.PendingUploadType":"Azure.AI.Projects.PendingUploadType","com.azure.ai.projects.models.PromptBasedEvaluatorDefinition":"Azure.AI.Projects.PromptBasedEvaluatorDefinition","com.azure.ai.projects.models.PromptDataGenerationJobSource":"Azure.AI.Projects.PromptDataGenerationJobSource","com.azure.ai.projects.models.PromptEvaluatorGenerationJobSource":"Azure.AI.Projects.PromptEvaluatorGenerationJobSource","com.azure.ai.projects.models.RecurrenceSchedule":"Azure.AI.Projects.RecurrenceSchedule","com.azure.ai.projects.models.RecurrenceTrigger":"Azure.AI.Projects.RecurrenceTrigger","com.azure.ai.projects.models.RecurrenceType":"Azure.AI.Projects.RecurrenceType","com.azure.ai.projects.models.RedTeam":"Azure.AI.Projects.RedTeam","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJob":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJob","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJobInputs":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJobInputs","com.azure.ai.projects.models.ReinforcementFineTuningDataGenerationJobOutputConfiguration":"Azure.AI.Projects.ReinforcementFineTuningDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.RiskCategory":"Azure.AI.Projects.RiskCategory","com.azure.ai.projects.models.Routine":"Azure.AI.Projects.Routine","com.azure.ai.projects.models.RoutineAction":"Azure.AI.Projects.RoutineAction","com.azure.ai.projects.models.RoutineActionType":"Azure.AI.Projects.RoutineActionType","com.azure.ai.projects.models.RoutineAttemptSource":"Azure.AI.Projects.RoutineAttemptSource","com.azure.ai.projects.models.RoutineAuthorization":"Azure.AI.Projects.RoutineAuthorization","com.azure.ai.projects.models.RoutineDispatchIdentity":"Azure.AI.Projects.RoutineDispatchIdentity","com.azure.ai.projects.models.RoutineDispatchPayload":"Azure.AI.Projects.RoutineDispatchPayload","com.azure.ai.projects.models.RoutineDispatchPayloadType":"Azure.AI.Projects.RoutineDispatchPayloadType","com.azure.ai.projects.models.RoutineRun":"Azure.AI.Projects.RoutineRun","com.azure.ai.projects.models.RoutineRunPhase":"Azure.AI.Projects.RoutineRunPhase","com.azure.ai.projects.models.RoutineTrigger":"Azure.AI.Projects.RoutineTrigger","com.azure.ai.projects.models.RoutineTriggerType":"Azure.AI.Projects.RoutineTriggerType","com.azure.ai.projects.models.RubricBasedEvaluatorDefinition":"Azure.AI.Projects.RubricBasedEvaluatorDefinition","com.azure.ai.projects.models.RubricGenerationInputQualityWarning":"Azure.AI.Projects.RubricGenerationInputQualityWarning","com.azure.ai.projects.models.RubricGenerationInputQualityWarningCode":"Azure.AI.Projects.RubricGenerationInputQualityWarningCode","com.azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity":"Azure.AI.Projects.RubricGenerationInputQualityWarningSeverity","com.azure.ai.projects.models.RubricGenerationInputQualityWarningSource":"Azure.AI.Projects.RubricGenerationInputQualityWarningSource","com.azure.ai.projects.models.SampleType":"Azure.AI.Projects.SampleType","com.azure.ai.projects.models.SasCredential":"Azure.AI.Projects.SASCredentials","com.azure.ai.projects.models.Schedule":"Azure.AI.Projects.Schedule","com.azure.ai.projects.models.ScheduleProvisioningStatus":"Azure.AI.Projects.ScheduleProvisioningStatus","com.azure.ai.projects.models.ScheduleRoutineTrigger":"Azure.AI.Projects.ScheduleRoutineTrigger","com.azure.ai.projects.models.ScheduleRun":"Azure.AI.Projects.ScheduleRun","com.azure.ai.projects.models.ScheduleTask":"Azure.AI.Projects.ScheduleTask","com.azure.ai.projects.models.ScheduleTaskType":"Azure.AI.Projects.ScheduleTaskType","com.azure.ai.projects.models.SimpleQnADataGenerationJobConfiguration":"Azure.AI.Projects.SimpleQnADataGenerationJobConfiguration","com.azure.ai.projects.models.SimpleQnAFineTuningQuestionType":"Azure.AI.Projects.SimpleQnAFineTuningQuestionType","com.azure.ai.projects.models.SimulationSeedDataGenerationJobConfiguration":"Azure.AI.Projects.SimulationSeedDataGenerationJobConfiguration","com.azure.ai.projects.models.SkillDetails":"Azure.AI.Projects.Skill","com.azure.ai.projects.models.SkillFileDetails":"TypeSpec.Http.File","com.azure.ai.projects.models.SkillInlineContent":"Azure.AI.Projects.SkillInlineContent","com.azure.ai.projects.models.SkillVersion":"Azure.AI.Projects.SkillVersion","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJob":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJob","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJobInputs":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJobInputs","com.azure.ai.projects.models.SupervisedFineTuningDataGenerationJobOutputConfiguration":"Azure.AI.Projects.SupervisedFineTuningDataGenerationJobOutputConfiguration","com.azure.ai.projects.models.Target":"Azure.AI.Projects.FoundryEvaluationTarget","com.azure.ai.projects.models.TargetConfig":"Azure.AI.Projects.RedTeamTargetConfig","com.azure.ai.projects.models.TaxonomyCategory":"Azure.AI.Projects.TaxonomyCategory","com.azure.ai.projects.models.TaxonomySubCategory":"Azure.AI.Projects.TaxonomySubCategory","com.azure.ai.projects.models.TestingCriterionAzureAIEvaluator":"Azure.AI.Projects.TestingCriterionAzureAIEvaluator","com.azure.ai.projects.models.TimerRoutineTrigger":"Azure.AI.Projects.TimerRoutineTrigger","com.azure.ai.projects.models.ToolDescription":"Azure.AI.Projects.ToolDescription","com.azure.ai.projects.models.ToolUseFineTuningDataGenerationJobConfiguration":"Azure.AI.Projects.ToolUseFineTuningDataGenerationJobConfiguration","com.azure.ai.projects.models.TracesDataGenerationJobConfiguration":"Azure.AI.Projects.TracesDataGenerationJobConfiguration","com.azure.ai.projects.models.TracesDataGenerationJobSource":"Azure.AI.Projects.TracesDataGenerationJobSource","com.azure.ai.projects.models.TracesEvaluatorGenerationJobSource":"Azure.AI.Projects.TracesEvaluatorGenerationJobSource","com.azure.ai.projects.models.TreatmentEffectType":"Azure.AI.Projects.TreatmentEffectType","com.azure.ai.projects.models.Trigger":"Azure.AI.Projects.Trigger","com.azure.ai.projects.models.TriggerType":"Azure.AI.Projects.TriggerType","com.azure.ai.projects.models.UpdateModelVersionInput":"Azure.AI.Projects.UpdateModelVersionRequest","com.azure.ai.projects.models.WeeklyRecurrenceSchedule":"Azure.AI.Projects.WeeklyRecurrenceSchedule"},"generatedFiles":["src/main/java/com/azure/ai/projects/AIProjectClientBuilder.java","src/main/java/com/azure/ai/projects/AIProjectsServiceVersion.java","src/main/java/com/azure/ai/projects/BetaAgentInsightMonitorsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaAgentInsightMonitorsClient.java","src/main/java/com/azure/ai/projects/BetaEvaluationTaxonomiesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaEvaluationTaxonomiesClient.java","src/main/java/com/azure/ai/projects/BetaEvaluatorsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaEvaluatorsClient.java","src/main/java/com/azure/ai/projects/BetaInsightsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaInsightsClient.java","src/main/java/com/azure/ai/projects/BetaModelsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaModelsClient.java","src/main/java/com/azure/ai/projects/BetaRedTeamsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaRedTeamsClient.java","src/main/java/com/azure/ai/projects/BetaRoutinesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaRoutinesClient.java","src/main/java/com/azure/ai/projects/BetaSchedulesAsyncClient.java","src/main/java/com/azure/ai/projects/BetaSchedulesClient.java","src/main/java/com/azure/ai/projects/BetaSkillsAsyncClient.java","src/main/java/com/azure/ai/projects/BetaSkillsClient.java","src/main/java/com/azure/ai/projects/ConnectionsAsyncClient.java","src/main/java/com/azure/ai/projects/ConnectionsClient.java","src/main/java/com/azure/ai/projects/DatasetsAsyncClient.java","src/main/java/com/azure/ai/projects/DatasetsClient.java","src/main/java/com/azure/ai/projects/DeploymentsAsyncClient.java","src/main/java/com/azure/ai/projects/DeploymentsClient.java","src/main/java/com/azure/ai/projects/EvaluationRulesAsyncClient.java","src/main/java/com/azure/ai/projects/EvaluationRulesClient.java","src/main/java/com/azure/ai/projects/EvaluatorsAsyncClient.java","src/main/java/com/azure/ai/projects/EvaluatorsClient.java","src/main/java/com/azure/ai/projects/IndexesAsyncClient.java","src/main/java/com/azure/ai/projects/IndexesClient.java","src/main/java/com/azure/ai/projects/implementation/AIProjectClientImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaAgentInsightMonitorsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaEvaluationTaxonomiesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaEvaluatorsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaInsightsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaModelsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaRedTeamsImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaRoutinesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaSchedulesImpl.java","src/main/java/com/azure/ai/projects/implementation/BetaSkillsImpl.java","src/main/java/com/azure/ai/projects/implementation/ConnectionsImpl.java","src/main/java/com/azure/ai/projects/implementation/DatasetsImpl.java","src/main/java/com/azure/ai/projects/implementation/DeploymentsImpl.java","src/main/java/com/azure/ai/projects/implementation/EvaluationRulesImpl.java","src/main/java/com/azure/ai/projects/implementation/EvaluatorsImpl.java","src/main/java/com/azure/ai/projects/implementation/IndexesImpl.java","src/main/java/com/azure/ai/projects/implementation/JsonMergePatchHelper.java","src/main/java/com/azure/ai/projects/implementation/MultipartFormDataHelper.java","src/main/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategy.java","src/main/java/com/azure/ai/projects/implementation/PollingUtils.java","src/main/java/com/azure/ai/projects/implementation/SyncOperationLocationPollingStrategy.java","src/main/java/com/azure/ai/projects/implementation/models/CreateOrUpdateRoutineRequest.java","src/main/java/com/azure/ai/projects/implementation/models/CreateSkillVersionRequest.java","src/main/java/com/azure/ai/projects/implementation/models/DispatchRoutineAsyncRequest.java","src/main/java/com/azure/ai/projects/implementation/models/FoundryFeaturesOptInKeys.java","src/main/java/com/azure/ai/projects/implementation/models/UpdateSkillRequest.java","src/main/java/com/azure/ai/projects/implementation/models/package-info.java","src/main/java/com/azure/ai/projects/implementation/package-info.java","src/main/java/com/azure/ai/projects/models/AIProjectIndex.java","src/main/java/com/azure/ai/projects/models/AgentClusterInsightRequest.java","src/main/java/com/azure/ai/projects/models/AgentClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/AgentDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/AgentEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/AgentInsight.java","src/main/java/com/azure/ai/projects/models/AgentInsightDetails.java","src/main/java/com/azure/ai/projects/models/AgentInsightEstimatedCost.java","src/main/java/com/azure/ai/projects/models/AgentInsightHighlightedTrace.java","src/main/java/com/azure/ai/projects/models/AgentInsightLinkedTrace.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitor.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorCreate.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorListItem.java","src/main/java/com/azure/ai/projects/models/AgentInsightMonitorUpdate.java","src/main/java/com/azure/ai/projects/models/AgentInsightOverviewSource.java","src/main/java/com/azure/ai/projects/models/AgentInsightPromptSurface.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFix.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFixChange.java","src/main/java/com/azure/ai/projects/models/AgentInsightProposedFixKind.java","src/main/java/com/azure/ai/projects/models/AgentInsightRecommendedAction.java","src/main/java/com/azure/ai/projects/models/AgentInsightRun.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunCreate.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunResult.java","src/main/java/com/azure/ai/projects/models/AgentInsightRunTrigger.java","src/main/java/com/azure/ai/projects/models/AgentInsightSeverity.java","src/main/java/com/azure/ai/projects/models/AgentInsightStatus.java","src/main/java/com/azure/ai/projects/models/AgentInsightSuspension.java","src/main/java/com/azure/ai/projects/models/AgentInsightTokenUsage.java","src/main/java/com/azure/ai/projects/models/AgentInsightUpdate.java","src/main/java/com/azure/ai/projects/models/AgentInsightsOverview.java","src/main/java/com/azure/ai/projects/models/AgentInsightsOverviewOverride.java","src/main/java/com/azure/ai/projects/models/AgentTaxonomyInput.java","src/main/java/com/azure/ai/projects/models/AgenticIdentityPreviewCredential.java","src/main/java/com/azure/ai/projects/models/ApiError.java","src/main/java/com/azure/ai/projects/models/ApiKeyCredential.java","src/main/java/com/azure/ai/projects/models/ArtifactProfile.java","src/main/java/com/azure/ai/projects/models/AttackStrategy.java","src/main/java/com/azure/ai/projects/models/AzureAIAgentTarget.java","src/main/java/com/azure/ai/projects/models/AzureAIModelTarget.java","src/main/java/com/azure/ai/projects/models/AzureAISearchIndex.java","src/main/java/com/azure/ai/projects/models/AzureOpenAIModelConfiguration.java","src/main/java/com/azure/ai/projects/models/BaseCredential.java","src/main/java/com/azure/ai/projects/models/BlobReference.java","src/main/java/com/azure/ai/projects/models/BlobReferenceSasCredential.java","src/main/java/com/azure/ai/projects/models/ChartCoordinate.java","src/main/java/com/azure/ai/projects/models/ClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/ClusterTokenUsage.java","src/main/java/com/azure/ai/projects/models/CodeBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/Connection.java","src/main/java/com/azure/ai/projects/models/ConnectionType.java","src/main/java/com/azure/ai/projects/models/ContinuousEvaluationRuleAction.java","src/main/java/com/azure/ai/projects/models/CosmosDBIndex.java","src/main/java/com/azure/ai/projects/models/CreateAsyncResponse.java","src/main/java/com/azure/ai/projects/models/CreateSkillVersionFromFilesBody.java","src/main/java/com/azure/ai/projects/models/CredentialType.java","src/main/java/com/azure/ai/projects/models/CronTrigger.java","src/main/java/com/azure/ai/projects/models/CustomCredential.java","src/main/java/com/azure/ai/projects/models/CustomRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/DailyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/DataGenerationJob.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutputType.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobOutputWriteMode.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobResult.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobScenario.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobSourceType.java","src/main/java/com/azure/ai/projects/models/DataGenerationJobType.java","src/main/java/com/azure/ai/projects/models/DataGenerationModelOptions.java","src/main/java/com/azure/ai/projects/models/DataGenerationTokenUsage.java","src/main/java/com/azure/ai/projects/models/DatasetCredential.java","src/main/java/com/azure/ai/projects/models/DatasetDataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/DatasetEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/DatasetReference.java","src/main/java/com/azure/ai/projects/models/DatasetType.java","src/main/java/com/azure/ai/projects/models/DatasetVersion.java","src/main/java/com/azure/ai/projects/models/Deployment.java","src/main/java/com/azure/ai/projects/models/DeploymentType.java","src/main/java/com/azure/ai/projects/models/Dimension.java","src/main/java/com/azure/ai/projects/models/DispatchRoutineResult.java","src/main/java/com/azure/ai/projects/models/EmbeddingConfiguration.java","src/main/java/com/azure/ai/projects/models/EndpointBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/EntraIdCredential.java","src/main/java/com/azure/ai/projects/models/EvaluationComparisonInsightRequest.java","src/main/java/com/azure/ai/projects/models/EvaluationComparisonInsightResult.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/EvaluationDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/EvaluationLevel.java","src/main/java/com/azure/ai/projects/models/EvaluationResult.java","src/main/java/com/azure/ai/projects/models/EvaluationResultSample.java","src/main/java/com/azure/ai/projects/models/EvaluationRule.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleAction.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleActionType.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleEventType.java","src/main/java/com/azure/ai/projects/models/EvaluationRuleFilter.java","src/main/java/com/azure/ai/projects/models/EvaluationRunClusterInsightRequest.java","src/main/java/com/azure/ai/projects/models/EvaluationRunClusterInsightResult.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultCompareItem.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultComparison.java","src/main/java/com/azure/ai/projects/models/EvaluationRunResultSummary.java","src/main/java/com/azure/ai/projects/models/EvaluationScheduleTask.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomy.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomyInput.java","src/main/java/com/azure/ai/projects/models/EvaluationTaxonomyInputType.java","src/main/java/com/azure/ai/projects/models/EvaluatorCategory.java","src/main/java/com/azure/ai/projects/models/EvaluatorCredentialInput.java","src/main/java/com/azure/ai/projects/models/EvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/EvaluatorDefinitionType.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationArtifacts.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationInputs.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJob.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationJobSourceType.java","src/main/java/com/azure/ai/projects/models/EvaluatorGenerationTokenUsage.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetric.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetricDirection.java","src/main/java/com/azure/ai/projects/models/EvaluatorMetricType.java","src/main/java/com/azure/ai/projects/models/EvaluatorType.java","src/main/java/com/azure/ai/projects/models/EvaluatorVersion.java","src/main/java/com/azure/ai/projects/models/FieldMapping.java","src/main/java/com/azure/ai/projects/models/FileDataGenerationJobOutput.java","src/main/java/com/azure/ai/projects/models/FileDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/FileDatasetVersion.java","src/main/java/com/azure/ai/projects/models/FolderDatasetVersion.java","src/main/java/com/azure/ai/projects/models/FoundryModelArtifactProfileCategory.java","src/main/java/com/azure/ai/projects/models/FoundryModelArtifactProfileSignal.java","src/main/java/com/azure/ai/projects/models/FoundryModelSourceType.java","src/main/java/com/azure/ai/projects/models/FoundryModelWarning.java","src/main/java/com/azure/ai/projects/models/FoundryModelWarningCode.java","src/main/java/com/azure/ai/projects/models/FoundryModelWeightType.java","src/main/java/com/azure/ai/projects/models/GenerationWarningType.java","src/main/java/com/azure/ai/projects/models/GitHubIssueEvent.java","src/main/java/com/azure/ai/projects/models/GitHubIssueRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/GraderAzureAIEvaluator.java","src/main/java/com/azure/ai/projects/models/HourlyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/HumanEvaluationPreviewRuleAction.java","src/main/java/com/azure/ai/projects/models/IndexType.java","src/main/java/com/azure/ai/projects/models/Insight.java","src/main/java/com/azure/ai/projects/models/InsightCluster.java","src/main/java/com/azure/ai/projects/models/InsightModelConfiguration.java","src/main/java/com/azure/ai/projects/models/InsightRequest.java","src/main/java/com/azure/ai/projects/models/InsightResult.java","src/main/java/com/azure/ai/projects/models/InsightSample.java","src/main/java/com/azure/ai/projects/models/InsightScheduleTask.java","src/main/java/com/azure/ai/projects/models/InsightSummary.java","src/main/java/com/azure/ai/projects/models/InsightType.java","src/main/java/com/azure/ai/projects/models/InsightsMetadata.java","src/main/java/com/azure/ai/projects/models/InvokeAgentInvocationsApiDispatchPayload.java","src/main/java/com/azure/ai/projects/models/InvokeAgentInvocationsApiRoutineAction.java","src/main/java/com/azure/ai/projects/models/InvokeAgentResponsesApiDispatchPayload.java","src/main/java/com/azure/ai/projects/models/InvokeAgentResponsesApiRoutineAction.java","src/main/java/com/azure/ai/projects/models/JobStatus.java","src/main/java/com/azure/ai/projects/models/ListVersionsRequestType.java","src/main/java/com/azure/ai/projects/models/LoraConfig.java","src/main/java/com/azure/ai/projects/models/ManagedAzureAISearchIndex.java","src/main/java/com/azure/ai/projects/models/ModelCredentialInput.java","src/main/java/com/azure/ai/projects/models/ModelDeployment.java","src/main/java/com/azure/ai/projects/models/ModelDeploymentSku.java","src/main/java/com/azure/ai/projects/models/ModelPendingUploadInput.java","src/main/java/com/azure/ai/projects/models/ModelPendingUploadResult.java","src/main/java/com/azure/ai/projects/models/ModelSamplingParams.java","src/main/java/com/azure/ai/projects/models/ModelSourceData.java","src/main/java/com/azure/ai/projects/models/ModelVersion.java","src/main/java/com/azure/ai/projects/models/MonthlyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/NoAuthenticationCredential.java","src/main/java/com/azure/ai/projects/models/OneTimeTrigger.java","src/main/java/com/azure/ai/projects/models/OperationStatus.java","src/main/java/com/azure/ai/projects/models/PendingUploadRequest.java","src/main/java/com/azure/ai/projects/models/PendingUploadResponse.java","src/main/java/com/azure/ai/projects/models/PendingUploadType.java","src/main/java/com/azure/ai/projects/models/PromptBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/PromptDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/PromptEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/RecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/RecurrenceTrigger.java","src/main/java/com/azure/ai/projects/models/RecurrenceType.java","src/main/java/com/azure/ai/projects/models/RedTeam.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/ReinforcementFineTuningDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/RiskCategory.java","src/main/java/com/azure/ai/projects/models/Routine.java","src/main/java/com/azure/ai/projects/models/RoutineAction.java","src/main/java/com/azure/ai/projects/models/RoutineActionType.java","src/main/java/com/azure/ai/projects/models/RoutineAttemptSource.java","src/main/java/com/azure/ai/projects/models/RoutineAuthorization.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchIdentity.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchPayload.java","src/main/java/com/azure/ai/projects/models/RoutineDispatchPayloadType.java","src/main/java/com/azure/ai/projects/models/RoutineRun.java","src/main/java/com/azure/ai/projects/models/RoutineRunPhase.java","src/main/java/com/azure/ai/projects/models/RoutineTrigger.java","src/main/java/com/azure/ai/projects/models/RoutineTriggerType.java","src/main/java/com/azure/ai/projects/models/RubricBasedEvaluatorDefinition.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarning.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningCode.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningSeverity.java","src/main/java/com/azure/ai/projects/models/RubricGenerationInputQualityWarningSource.java","src/main/java/com/azure/ai/projects/models/SampleType.java","src/main/java/com/azure/ai/projects/models/SasCredential.java","src/main/java/com/azure/ai/projects/models/Schedule.java","src/main/java/com/azure/ai/projects/models/ScheduleProvisioningStatus.java","src/main/java/com/azure/ai/projects/models/ScheduleRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/ScheduleRun.java","src/main/java/com/azure/ai/projects/models/ScheduleTask.java","src/main/java/com/azure/ai/projects/models/ScheduleTaskType.java","src/main/java/com/azure/ai/projects/models/SimpleQnADataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/SimpleQnAFineTuningQuestionType.java","src/main/java/com/azure/ai/projects/models/SimulationSeedDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/SkillDetails.java","src/main/java/com/azure/ai/projects/models/SkillFileDetails.java","src/main/java/com/azure/ai/projects/models/SkillInlineContent.java","src/main/java/com/azure/ai/projects/models/SkillVersion.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJob.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJobInputs.java","src/main/java/com/azure/ai/projects/models/SupervisedFineTuningDataGenerationJobOutputConfiguration.java","src/main/java/com/azure/ai/projects/models/Target.java","src/main/java/com/azure/ai/projects/models/TargetConfig.java","src/main/java/com/azure/ai/projects/models/TaxonomyCategory.java","src/main/java/com/azure/ai/projects/models/TaxonomySubCategory.java","src/main/java/com/azure/ai/projects/models/TestingCriterionAzureAIEvaluator.java","src/main/java/com/azure/ai/projects/models/TimerRoutineTrigger.java","src/main/java/com/azure/ai/projects/models/ToolDescription.java","src/main/java/com/azure/ai/projects/models/ToolUseFineTuningDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/TracesDataGenerationJobConfiguration.java","src/main/java/com/azure/ai/projects/models/TracesDataGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/TracesEvaluatorGenerationJobSource.java","src/main/java/com/azure/ai/projects/models/TreatmentEffectType.java","src/main/java/com/azure/ai/projects/models/Trigger.java","src/main/java/com/azure/ai/projects/models/TriggerType.java","src/main/java/com/azure/ai/projects/models/UpdateModelVersionInput.java","src/main/java/com/azure/ai/projects/models/WeeklyRecurrenceSchedule.java","src/main/java/com/azure/ai/projects/models/package-info.java","src/main/java/com/azure/ai/projects/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/src/test/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategyTest.java b/sdk/ai/azure-ai-projects/src/test/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategyTest.java new file mode 100644 index 0000000000000..8f0a0431e198d --- /dev/null +++ b/sdk/ai/azure-ai-projects/src/test/java/com/azure/ai/projects/implementation/OperationLocationPollingStrategyTest.java @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.projects.implementation; + +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpHeaderName; +import com.azure.core.http.HttpHeaders; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.HttpPipeline; +import com.azure.core.http.HttpPipelineBuilder; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.test.http.MockHttpResponse; +import com.azure.core.util.BinaryData; +import com.azure.core.util.polling.LongRunningOperationStatus; +import com.azure.core.util.polling.PollResponse; +import com.azure.core.util.polling.PollerFlux; +import com.azure.core.util.polling.PollingStrategyOptions; +import com.azure.core.util.polling.SyncPoller; +import com.azure.core.util.serializer.TypeReference; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OperationLocationPollingStrategyTest { + private static final String ENDPOINT = "https://example.test"; + private static final Duration RETRY_AFTER = Duration.ofSeconds(5); + + static Stream pollingStatusCases() { + return Stream.of(false, true) + .flatMap(async -> Stream.of(Arguments.of(async, "cancelled", LongRunningOperationStatus.USER_CANCELLED), + Arguments.of(async, "CANCELLED", LongRunningOperationStatus.USER_CANCELLED), + Arguments.of(async, "succeeded", LongRunningOperationStatus.SUCCESSFULLY_COMPLETED), + Arguments.of(async, "failed", LongRunningOperationStatus.FAILED), + Arguments.of(async, "queued", LongRunningOperationStatus.fromString("queued", false)))); + } + + @ParameterizedTest + @MethodSource("pollingStatusCases") + void pollingNormalizesCancellationAndPreservesResponse(boolean async, String status, + LongRunningOperationStatus expected) { + String body = "{\"id\":\"job\",\"status\":\"" + status + "\"}"; + HttpClient httpClient = request -> { + assertEquals(HttpMethod.GET, request.getHttpMethod()); + assertEquals("/jobs/job", request.getUrl().getPath()); + return Mono.just(new MockHttpResponse(request, 200, new HttpHeaders().set(HttpHeaderName.RETRY_AFTER, "5"), + body.getBytes(StandardCharsets.UTF_8)) { + @Override + public BinaryData getBodyAsBinaryData() { + return BinaryData.fromString(body); + } + }); + }; + HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(httpClient).build(); + PollingStrategyOptions options = new PollingStrategyOptions(pipeline).setEndpoint(ENDPOINT); + Response initial = new SimpleResponse<>(new HttpRequest(HttpMethod.POST, ENDPOINT + "/jobs"), 201, + new HttpHeaders().set("Operation-Location", ENDPOINT + "/jobs/job"), + BinaryData.fromString("{\"id\":\"job\",\"status\":\"queued\"}")); + TypeReference responseType = TypeReference.createInstance(BinaryData.class); + + if (async) { + OperationLocationPollingStrategy strategy + = new OperationLocationPollingStrategy<>(options, "result"); + StepVerifier.create( + PollerFlux.create(Duration.ofMillis(1), () -> Mono.just(initial), strategy, responseType, responseType) + .next()) + .assertNext(response -> { + assertEquals(expected, response.getStatus()); + assertEquals(expected.isComplete(), response.getStatus().isComplete()); + assertEquals(body, response.getValue().toString()); + }) + .verifyComplete(); + } else { + SyncOperationLocationPollingStrategy strategy + = new SyncOperationLocationPollingStrategy<>(options, "result"); + assertPollResponse( + SyncPoller.createPoller(Duration.ofMillis(1), () -> initial, strategy, responseType, responseType) + .poll(), + expected, body); + } + } + + private static void assertPollResponse(PollResponse response, LongRunningOperationStatus expected, + String body) { + assertEquals(expected, response.getStatus()); + assertEquals(expected.isComplete(), response.getStatus().isComplete()); + assertEquals(body, response.getValue().toString()); + assertEquals(RETRY_AFTER, response.getRetryAfter()); + } +} diff --git a/sdk/ai/azure-ai-projects/tsp-location.yaml b/sdk/ai/azure-ai-projects/tsp-location.yaml index 43f85b4d85f92..11b01f3e88d69 100644 --- a/sdk/ai/azure-ai-projects/tsp-location.yaml +++ b/sdk/ai/azure-ai-projects/tsp-location.yaml @@ -1,5 +1,5 @@ directory: specification/ai-foundry/data-plane/Foundry/src/sdk-java-azure-ai-projects -commit: 4c0bca84cb8862569a22ec3f8fae2a6e14871a97 +commit: c86ce135659e8f59369e602a97166428de4639eb repo: Azure/azure-rest-api-specs additionalDirectories: - specification/ai-foundry/data-plane/Foundry/src/sdk-common