Skip to content

Fix binary response inference for empty media types#151

Merged
github-actions[bot] merged 1 commit intomainfrom
codex/issue-150-binary-response-inference
Mar 13, 2026
Merged

Fix binary response inference for empty media types#151
github-actions[bot] merged 1 commit intomainfrom
codex/issue-150-binary-response-inference

Conversation

@HavenDV
Copy link
Collaborator

@HavenDV HavenDV commented Mar 13, 2026

Summary by CodeRabbit

  • New Features

    • Enhanced binary response handling for audio and file downloads with improved content type detection.
    • Async methods now properly return raw byte arrays for binary content endpoints.
  • Bug Fixes

    • Fixed response processing for binary media types to ensure correct content delivery without unnecessary conversion overhead.
  • Tests

    • Added comprehensive test coverage for binary response type inference and content serialization.

@github-actions github-actions bot merged commit 6db935f into main Mar 13, 2026
3 of 4 checks passed
@HavenDV HavenDV deleted the codex/issue-150-binary-response-inference branch March 13, 2026 13:20
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Walkthrough

This PR enhances binary response handling by introducing a new MIME type detection extension and updating response processing logic. Generated API methods for binary content now return Task<byte[]> instead of Task, with responses read as raw bytes rather than deserialized strings. Multiple snapshot tests updated to reflect these signature changes.

Changes

Cohort / File(s) Summary
Binary Detection Extension
src/libs/AutoSDK/Extensions/MimeTypeExtensions.cs
New IsBinaryResponseMimeType extension method that identifies binary MIME types (application/octet-stream, application/zip, audio/\*) by checking normalized MIME strings.
Response Selection & Processing
src/libs/AutoSDK/Models/EndPoint.cs, src/libs/AutoSDK/Models/EndPointResponse.cs
Enhanced response selection logic to prioritize 2XX responses with non-empty CSharpTypeRaw. Updated binary detection to use composite checks: MIME type inspection, C# byte[] type detection, and IsBinary flag. Supports preferred MIME type filtering.
ElevenLabs NewtonsoftJson API Stubs
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AudioIsolationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.IAgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.IAudioIsolationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.ISamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SpeechHistoryClient.CreateHistoryDownload.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.StudioClient.CreateStudioProjectsByProjectIdSnapshotsByProjectSnapshotIdArchive.g.verified.cs
Updated audio/binary endpoint methods to return Task<byte[]> instead of Task. Response content read as byte[] via ReadAsByteArrayAsync. Removed JSON deserialization of binary content. Added ProcessXxxResponseContent(ref byte[] content) partial methods. Simplified error handling to use response reason phrase instead of content.
ElevenLabs SystemTextJson API Stubs
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AudioIsolationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.IAgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.IAudioIsolationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.ISamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.*.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.SpeechHistoryClient.CreateHistoryDownload.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.StudioClient.CreateStudioProjectsByProjectIdSnapshotsByProjectSnapshotIdArchive.g.verified.cs
Parallel updates to SystemTextJson variants: return type changed from Task to Task<byte[]>, byte-based content reading, removal of JSON deserialization, and addition of ProcessXxxResponseContent(ref byte[] content) hooks with aligned error handling.
Ultravox API Stubs
src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs, src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/SystemTextJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
Updated binary recording retrieval endpoints to use ref byte[] content in processing methods. Changed from string-based reads to ReadAsByteArrayAsync. Removed JSON deserialization and intermediate ProcessResponseContent calls. Adjusted exception handling to rely on reason phrase.
Binary Response Type Tests
src/tests/AutoSDK.UnitTests/ResponseTypeInferenceTests.cs
New test suite validating binary response type inference. Tests verify that binary MIME types (audio/mpeg, audio/\*, application/octet-stream, application/zip, application/pdf with binary schema) correctly generate Task<byte[]> return types and ReadAsByteArrayAsync invocations. Includes integration tests against real ElevenLabs endpoint definitions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 Hark! A binary renaissance, hail!
No more strings, but bytes that prevail,
From audio to zip, each byte doth shine,
Response hooks await—extensibility divine!
Task<byte[]> now flows, no more shall we fail! 🎵

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.62% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix binary response inference for empty media types' clearly describes the main change in the PR, which is improving how the system handles binary responses when media types are empty or missing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/issue-150-binary-response-inference
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (12)
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs (1)

168-180: ⚠️ Potential issue | 🟠 Major

Missing ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent call in the else branch.

The partial method hook is invoked in the if (ReadResponseAsString) branch (lines 143-146) but is absent in this else branch. This asymmetry means consumers implementing the partial method won't have their hook called when ReadResponseAsString is false.

🐛 Proposed fix to add the missing partial method call
                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs
around lines 168 - 180, The else branch after reading the byte[] (__content) is
missing a call to the partial hook
ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent,
causing consumers to miss the hook when ReadResponseAsString is false; update
the else branch in the
GetPronunciationDictionariesByDictionaryIdByVersionIdDownload response handling
to invoke
ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent(__response,
__content, __headers) (matching the call made in the ReadResponseAsString
branch) before returning __content so the partial method is always executed
regardless of ReadResponseAsString.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs (1)

168-195: ⚠️ Potential issue | 🟡 Minor

Missing ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent hook call in the else branch.

The ReadResponseAsString=true branch (lines 143-146) calls ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent, but the else branch does not. This creates inconsistent behavior where implementers of the partial method would have their hook invoked only when ReadResponseAsString is true.

For consistent behavior, the hook should be called in both branches before returning:

🔧 Proposed fix
                 try
                 {
                     __response.EnsureSuccessStatusCode();

                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
around lines 168 - 195, The else branch that returns the byte[] response misses
calling the partial hook
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent, causing
inconsistent behavior vs the ReadResponseAsString branch; to fix, invoke
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent in the else
branch after reading __content and before returning, passing the same parameters
used in the ReadResponseAsString branch (the response, the response content
representation used there, and any headers/status info) so implementers get the
hook in both code paths.
src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs (1)

99-102: ⚠️ Potential issue | 🟡 Minor

Unused stream read in 302 error handling.

__contentStream_302 is assigned but never used, resulting in unnecessary I/O. If the stream content isn't needed for the exception, consider removing this branch or using the stream data.

Suggested fix
                     else
                     {
-                        var __contentStream_302 = await __response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+                        // Stream content not needed for redirect handling
                     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
around lines 99 - 102, The else branch currently reads the response stream into
the unused local __contentStream_302 causing unnecessary I/O; either remove that
branch entirely or consume/dispose the stream content appropriately: locate the
302 error handling block where __contentStream_302 is assigned (the else branch
after the 302 response check) and either delete the await
__response.Content.ReadAsStreamAsync(...) call or replace it with code that
reads/disposes the stream (e.g., copy to a buffer, call ReadAsStringAsync, or
use a using/Dispose) so the stream is not leaked and no unused variable remains.
src/tests/AutoSDK.SnapshotTests/Snapshots/CLI/ultravox/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs (1)

99-102: ⚠️ Potential issue | 🟡 Minor

Unused stream read in 302 error handling.

Same issue as in the NewtonsoftJson variant: __contentStream_302 is read but never used.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/CLI/ultravox/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
around lines 99 - 102, The else block in the CallsRecordingRetrieve test reads a
response stream into __contentStream_302 but never uses it; remove the unused
ReadAsStreamAsync call or wrap it in a using/dispose if you intend to consume it
(e.g., for logging). Locate the else branch that declares __contentStream_302 in
the CallsRecordingRetrieve-generated snapshot test and either delete the await
__response.Content.ReadAsStreamAsync(...) assignment or change it to a properly
disposed/used stream (or read to a string for logging) so the variable is not
allocated and leaked unused.
src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/SystemTextJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs (1)

155-167: ⚠️ Potential issue | 🟠 Major

Invoke response-content hook in both byte[] paths.

ProcessCallsRecordingRetrieveResponseContent is skipped when ReadResponseAsString is false (Line 161 onward). Since both branches now read byte[], this creates inconsistent behavior based on an unrelated flag.

Proposed fix
             else
             {
                 try
                 {
                     __response.EnsureSuccessStatusCode();

                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessCallsRecordingRetrieveResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/SystemTextJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
around lines 155 - 167, The response-content hook
ProcessCallsRecordingRetrieveResponseContent must be invoked regardless of
ReadResponseAsString; update the code paths in the method handling
CallsClient.CallsRecordingRetrieve (the branch that reads byte[] into __content
and the other byte[] branch) to call
ProcessCallsRecordingRetrieveResponseContent(__response, __content) before
returning, ensuring the hook runs for both byte[] flows and not only when
ReadResponseAsString is true; locate the usages around
__response.EnsureSuccessStatusCode(), the __content variable assignments, and
the early return statements and insert the hook invocation in both byte[] return
paths.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs (2)

245-259: ⚠️ Potential issue | 🟡 Minor

Add explicit null checks for non-nullable wrapper parameters.

audio and audioname are non-nullable, but there are no guard clauses before building the request object. Add explicit checks to match project standards and fail fast.

Proposed fix
         public async global::System.Threading.Tasks.Task<byte[]> CreateAudioIsolationAsync(
             byte[] audio,
             string audioname,
             string? xiApiKey = default,
             global::G.BodyAudioIsolationV1AudioIsolationPostFileFormat2? fileFormat = default,
             string? previewB64 = default,
             global::System.Threading.CancellationToken cancellationToken = default)
         {
+            audio = audio ?? throw new global::System.ArgumentNullException(nameof(audio));
+            audioname = audioname ?? throw new global::System.ArgumentNullException(nameof(audioname));
+
             var __request = new global::G.BodyAudioIsolationV1AudioIsolationPost
             {
                 Audio = audio,
                 Audioname = audioname,
                 FileFormat = fileFormat,
                 PreviewB64 = previewB64,
             };
As per coding guidelines "Validate parameters with explicit null checks in C# code".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs
around lines 245 - 259, The CreateAudioIsolationAsync method builds a request
from parameters that are declared non-nullable (audio and audioname) but lacks
guard clauses; add explicit null checks at the start of
CreateAudioIsolationAsync to throw ArgumentNullException for audio and audioname
(use nameof(audio)/nameof(audioname)) before constructing the
global::G.BodyAudioIsolationV1AudioIsolationPost request so the method fails
fast and follows the project's parameter validation guidelines.

193-206: ⚠️ Potential issue | 🟠 Major

Invoke response-content hook in the non-string branch too.

Line 205 returns raw bytes without calling ProcessCreateAudioIsolationResponseContent, so behavior differs based on ReadResponseAsString. That can skip custom binary post-processing unexpectedly.

Proposed fix
             else
             {
                 try
                 {
                     __response.EnsureSuccessStatusCode();

                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessCreateAudioIsolationResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;
                 }
                 catch (global::System.Exception __ex)
                 {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs
around lines 193 - 206, The non-string branch currently returns raw bytes after
EnsureSuccessStatusCode without invoking the response-content hook; call
ProcessCreateAudioIsolationResponseContent (passing __response and the byte[]
__content) and use its returned/possibly-processed bytes before returning,
mirroring the string branch behavior; update the path around
EnsureSuccessStatusCode in the CreateAudioIsolation method to invoke
ProcessCreateAudioIsolationResponseContent with __response and __content and
return that value instead of the raw __content.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs (1)

237-250: ⚠️ Potential issue | 🟠 Major

Invoke ProcessCreateMusicStemSeparationResponseContent in the non-string path too.

Line 243-249 returns bytes without running the response-content partial hook, unlike Line 212-215. This makes behavior depend on ReadResponseAsString and can silently bypass custom post-processing.

Proposed fix
                 try
                 {
                     __response.EnsureSuccessStatusCode();

                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessCreateMusicStemSeparationResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs
around lines 237 - 250, The non-string response path returns raw bytes without
invoking the post-processing hook; call
ProcessCreateMusicStemSeparationResponseContent before returning bytes in the
else branch. Specifically, after __response.EnsureSuccessStatusCode() and after
reading __content via __response.Content.ReadAsByteArrayAsync, invoke
ProcessCreateMusicStemSeparationResponseContent(__response, __content,
ReadResponseAsString) (or the overload used elsewhere) to run the partial hook,
then return the (possibly modified) byte[] result; mirror how the string path
around ProcessCreateMusicStemSeparationResponseContent is used to ensure
consistent behavior.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.CreateMusicStream.g.verified.cs (2)

154-157: ⚠️ Potential issue | 🟠 Major

Keep the byte[] content hook on both success paths.

ProcessCreateMusicStreamResponseContent only runs when ReadResponseAsString is true. With the current split, consumers lose their partial post-processing as soon as that flag is false, even though both branches now return the same byte[] payload.

💡 Minimal fix
                     var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                         cancellationToken
 `#endif`
                     ).ConfigureAwait(false);

+                    ProcessCreateMusicStreamResponseContent(
+                        httpClient: HttpClient,
+                        httpResponseMessage: __response,
+                        content: ref __content);
+
                     return __content;

Also applies to: 181-191

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.MusicGenerationClient.CreateMusicStream.g.verified.cs
around lines 154 - 157, The response post-processing hook
ProcessCreateMusicStreamResponseContent is only invoked when
ReadResponseAsString is true, causing consumers to miss the byte[] content hook
on the alternate success path; update the CreateMusicStream response handling so
that ProcessCreateMusicStreamResponseContent(httpClient: HttpClient,
httpResponseMessage: __response, content: ref __content) is called in both
success branches (the ReadResponseAsString true branch and the byte[] return
branch) before returning, ensuring both paths invoke the same post-processing;
do the same change for the other occurrence mentioned (the block around lines
181-191) so both success paths consistently call the hook.

167-176: ⚠️ Potential issue | 🟠 Major

Don't drop the buffered error payload here.

At this point __content has already been read, but the new ApiException only keeps ReasonPhrase. For unmodeled 4xx/5xx responses that still return JSON/text, that throws away the server's actual diagnostic message.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.MusicGenerationClient.CreateMusicStream.g.verified.cs
around lines 167 - 176, The generated exception drops the buffered response body
(__content) and only uses __response.ReasonPhrase; update the ApiException
construction in CreateMusicStream (where __response, __ex and __content are in
scope) to preserve the response payload by including __content: either append it
to the message passed to new global::G.ApiException or assign it to a
response-body property on the exception instance (e.g., set a
ResponseBody/Content property on the returned ApiException) and keep
ResponseHeaders as-is so unmodeled 4xx/5xx JSON/text payloads are retained for
diagnostics.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs (1)

245-264: ⚠️ Potential issue | 🟠 Major

Fail fast on null audio and audioname in the convenience overload.

From nullable-oblivious callers, audio = null currently turns into Array.Empty<byte>() and audioname = null into an empty multipart filename later in this generated path, so invalid input gets serialized instead of rejected. Add explicit guards before constructing __request.

🛡️ Proposed fix
         public async global::System.Threading.Tasks.Task<byte[]> CreateAudioIsolationAsync(
             byte[] audio,
             string audioname,
             string? xiApiKey = default,
             global::G.BodyAudioIsolationV1AudioIsolationPostFileFormat2? fileFormat = default,
             string? previewB64 = default,
             global::System.Threading.CancellationToken cancellationToken = default)
         {
+            audio = audio ?? throw new global::System.ArgumentNullException(nameof(audio));
+            audioname = audioname ?? throw new global::System.ArgumentNullException(nameof(audioname));
+
             var __request = new global::G.BodyAudioIsolationV1AudioIsolationPost
             {
                 Audio = audio,
                 Audioname = audioname,
                 FileFormat = fileFormat,
As per coding guidelines, "Validate parameters with explicit null checks in C# code."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs
around lines 245 - 264, In the CreateAudioIsolationAsync convenience overload,
add explicit null checks for the audio and audioname parameters before
constructing __request: if audio is null throw new
ArgumentNullException(nameof(audio)) and if audioname is null throw new
ArgumentNullException(nameof(audioname)). Update the method
(CreateAudioIsolationAsync that builds the
global::G.BodyAudioIsolationV1AudioIsolationPost __request) to perform these
guards so invalid input is rejected rather than being converted to empty values
downstream.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs (1)

127-172: ⚠️ Potential issue | 🟠 Major

Invoke the byte[] response hook in both runtime modes.

ProcessGetConvaiConversationsByConversationIdAudioResponseContent only runs in the ReadResponseAsString branch, and there it runs before EnsureSuccessStatusCode(). With ReadResponseAsString == false, custom partial implementations never see successful responses; with true, they also see failed ones. Please move the hook behind the success check and execute it for both paths, or collapse the duplicated branches into a single byte[] success path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs
around lines 127 - 172, The response processing hook
ProcessGetConvaiConversationsByConversationIdAudioResponseContent is only
invoked in the ReadResponseAsString branch and before EnsureSuccessStatusCode(),
so custom partials see failed responses in one path and no successful responses
in the other; fix this by collapsing the two byte[] paths into a single success
path: call __response.EnsureSuccessStatusCode() first, then read the bytes via
__response.Content.ReadAsByteArrayAsync(...) into __content, then invoke
ProcessGetConvaiConversationsByConversationIdAudioResponseContent(httpClient:
HttpClient, httpResponseMessage: __response, content: ref __content), and
finally return __content (preserving the ReadResponseAsString conditional only
if other behavior depends on it).
🧹 Nitpick comments (7)
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs (1)

135-141: Consider renaming or documenting ReadResponseAsString usage for binary endpoints.

The ReadResponseAsString flag name is now semantically misleading since both branches call ReadAsByteArrayAsync for binary responses. This is likely a generator-level concern rather than something to fix in this snapshot, but worth noting for clarity in the generated code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs
around lines 135 - 141, The flag ReadResponseAsString is misleading for binary
endpoints because both branches call ReadAsByteArrayAsync; update the generator
or surrounding code to either rename the flag to something like
ReadResponseAsBytes/ReadResponseAsBinary or add an inline comment/documentation
next to the ReadResponseAsString usage in the generated method (the conditional
block that reads __response.Content.ReadAsByteArrayAsync) clarifying that this
flag controls response reading behavior for binary payloads and that both
true/false branches will use byte-array reads for this endpoint; ensure
references to ReadResponseAsString in the method and any generation templates
(the conditional around ReadAsByteArrayAsync) are updated consistently.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs (1)

135-167: Minor naming inconsistency: ReadResponseAsString now reads bytes.

The condition if (ReadResponseAsString) at line 135 is semantically misleading since the code now reads the response as a byte array via ReadAsByteArrayAsync. This is likely an artifact of the code generation template that originally handled string responses.

If this is generated code, consider updating the generator's template or the flag name (e.g., ReadResponseBuffered or BufferResponseContent) to better reflect its actual behavior for binary content scenarios.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
around lines 135 - 167, The flag ReadResponseAsString is misleading because the
code path reads a byte array; update usages and the flag name to reflect
buffered/binary handling (e.g., rename ReadResponseAsString to
ReadResponseBuffered or BufferResponseContent) and adjust all references in the
same generated client code path (including the conditional around
ReadResponseAsString and any related logic in
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent and
response-returning methods) so the boolean name matches behavior, or change the
condition to a properly named flag in the generator template so generated
methods consistently use the new name.
src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs (1)

141-153: Consider: Error diagnostics may lose response body information.

When an exception occurs, ResponseBody is no longer populated since content is now byte[]. This is understandable for binary responses, but if the server returns an error with a text body, that diagnostic information is lost. This may be acceptable for binary endpoints, but worth noting for the generator logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
around lines 141 - 153, The catch block that throws G.ApiException currently
only sets ResponseHeaders and loses response body content because content is a
byte[]; update the catch in the same method that builds the ApiException (the
catch handling __ex and constructing new global::G.ApiException) to attempt to
read __response.Content as a byte[] and then: if the bytes decode as UTF-8 (or
other expected text encoding) set the exception's ResponseBody to the decoded
string, otherwise set ResponseBody to a safe representation (e.g., base64 or
null) so binary payloads are preserved; ensure you use the existing
__response.Content and set the ResponseBody property on the created
global::G.ApiException before throwing.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs (1)

223-227: Consider preserving response-body context in non-422 error exceptions.

Line 226 now uses only ReasonPhrase for message text. For non-422 failures, this drops useful server diagnostics that were previously easier to surface.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs
around lines 223 - 227, The current catch in CreateMusicStemSeparation throws
G.ApiException using only __response.ReasonPhrase, which loses server
diagnostics; update the throw to include the response body content when
available (e.g., read __response.Content.ReadAsStringAsync() and append or
interpolate it into the message for non-422 errors) while preserving the
existing innerException (__ex) and other exception fields so the full response
context is surfaced in G.ApiException.
src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs (1)

154-166: Error handling omits response body for binary content.

The ApiException thrown here no longer sets ResponseBody, which differs from the 422 error handling (lines 121-132). This is likely intentional since binary data can't be meaningfully displayed as a string message, but verify this is the expected behavior for debugging/logging purposes.

Consider whether it would be useful to include a hex dump or length indicator of the byte content in error scenarios for debugging purposes, or document why ResponseBody is intentionally omitted for binary responses.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs
around lines 154 - 166, The catch block that throws new global::G.ApiException
in GetPronunciationDictionariesByDictionaryIdByVersionIdDownload currently omits
ResponseBody for binary responses; update this block to populate
ApiException.ResponseBody with a concise debug-friendly indicator (e.g.,
"<binary N bytes>" and optionally a short hex/snippet of the first 16 bytes)
rather than the full binary payload, by reading __response.Content as a
byte[]/stream to determine length and snippet before throwing, and ensure you
still set ResponseHeaders and other fields; alternatively, if omission is
intentional, add a brief comment in the catch explaining why ResponseBody is not
set for binary responses.
src/libs/AutoSDK/Extensions/MimeTypeExtensions.cs (1)

14-16: Consider expanding binary MIME type coverage.

The current implementation handles application/octet-stream, application/zip, and audio/*. If this extension is intended for broader use across the SDK, you may want to consider adding other common binary types such as video/*, image/*, or application/pdf.

If the current set is intentionally scoped to the ElevenLabs API responses (which are predominantly audio), this is fine as-is.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/libs/AutoSDK/Extensions/MimeTypeExtensions.cs` around lines 14 - 16, The
current binary-detection logic in MimeTypeExtensions (the method that compares
normalizedMimeType to "application/octet-stream", "application/zip" and
"audio/*") is too narrow; update that method to also treat "video/*", "image/*"
and "application/pdf" as binary by adding
normalizedMimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase),
normalizedMimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase), and
normalizedMimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase)
(keeping the existing checks for audio, zip, and octet-stream).
src/tests/AutoSDK.UnitTests/ResponseTypeInferenceTests.cs (1)

42-47: Cover the non-string byte[] path explicitly.

These assertions prove byte[] inference, but they would still pass if the generator skipped Process...ResponseContent whenever ReadResponseAsString is false. Please add an assertion around the generated hook placement, or a runtime test that exercises both ReadResponseAsString modes, so this regression is covered.

Also applies to: 75-78, 106-108

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tests/AutoSDK.UnitTests/ResponseTypeInferenceTests.cs` around lines 42 -
47, The test currently asserts byte[] inference via GeneratedEndPoint output
(GenerateEndPoint) but doesn't verify that the generator emits the
Process...ResponseContent hook when ReadResponseAsString is false; add an
assertion that the generated code contains the response-processing hook
placement (e.g., contains a call or method named "Process" + operation name +
"ResponseContent" or the explicit "Process" method string used by the generator)
when ReadResponseAsString == false, and add a complementary assertion or small
runtime test that toggles ReadResponseAsString true/false to ensure the code
path that calls ReadAsByteArrayAsync and returns __content is only present when
the non-string branch is used; update ResponseTypeInferenceTests (the
GenerateEndPoint-based assertions around
GetAudioAsync/ReadAsByteArrayAsync/return __content) to include these
hook-placement checks for the same cases around lines referenced (also replicate
similar checks for the other two test blocks mentioned).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.MusicGenerationClient.CreateMusicDetailed.g.verified.cs:
- Around line 185-191: The non-ReadResponseAsString branch returns raw bytes
directly and skips the response-content hook; ensure the bytes are passed
through the same hook used in the ReadResponseAsString path by invoking
ProcessCreateMusicDetailedResponseContent(__response, __content, __headers) (or
the existing ProcessCreateMusicDetailedResponseContent method) before returning
from the method that currently returns __content; update the return path in
CreateMusicDetailed/ProcessCreateMusicDetailedResponseContent flow so both
branches apply the hook consistently (use the same parameters the
ReadResponseAsString branch provides).

---

Outside diff comments:
In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/CLI/ultravox/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs:
- Around line 99-102: The else block in the CallsRecordingRetrieve test reads a
response stream into __contentStream_302 but never uses it; remove the unused
ReadAsStreamAsync call or wrap it in a using/dispose if you intend to consume it
(e.g., for logging). Locate the else branch that declares __contentStream_302 in
the CallsRecordingRetrieve-generated snapshot test and either delete the await
__response.Content.ReadAsStreamAsync(...) assignment or change it to a properly
disposed/used stream (or read to a string for logging) so the variable is not
allocated and leaked unused.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs:
- Around line 245-259: The CreateAudioIsolationAsync method builds a request
from parameters that are declared non-nullable (audio and audioname) but lacks
guard clauses; add explicit null checks at the start of
CreateAudioIsolationAsync to throw ArgumentNullException for audio and audioname
(use nameof(audio)/nameof(audioname)) before constructing the
global::G.BodyAudioIsolationV1AudioIsolationPost request so the method fails
fast and follows the project's parameter validation guidelines.
- Around line 193-206: The non-string branch currently returns raw bytes after
EnsureSuccessStatusCode without invoking the response-content hook; call
ProcessCreateAudioIsolationResponseContent (passing __response and the byte[]
__content) and use its returned/possibly-processed bytes before returning,
mirroring the string branch behavior; update the path around
EnsureSuccessStatusCode in the CreateAudioIsolation method to invoke
ProcessCreateAudioIsolationResponseContent with __response and __content and
return that value instead of the raw __content.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs:
- Around line 237-250: The non-string response path returns raw bytes without
invoking the post-processing hook; call
ProcessCreateMusicStemSeparationResponseContent before returning bytes in the
else branch. Specifically, after __response.EnsureSuccessStatusCode() and after
reading __content via __response.Content.ReadAsByteArrayAsync, invoke
ProcessCreateMusicStemSeparationResponseContent(__response, __content,
ReadResponseAsString) (or the overload used elsewhere) to run the partial hook,
then return the (possibly modified) byte[] result; mirror how the string path
around ProcessCreateMusicStemSeparationResponseContent is used to ensure
consistent behavior.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs:
- Around line 168-195: The else branch that returns the byte[] response misses
calling the partial hook
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent, causing
inconsistent behavior vs the ReadResponseAsString branch; to fix, invoke
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent in the else
branch after reading __content and before returning, passing the same parameters
used in the ReadResponseAsString branch (the response, the response content
representation used there, and any headers/status info) so implementers get the
hook in both code paths.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs:
- Around line 127-172: The response processing hook
ProcessGetConvaiConversationsByConversationIdAudioResponseContent is only
invoked in the ReadResponseAsString branch and before EnsureSuccessStatusCode(),
so custom partials see failed responses in one path and no successful responses
in the other; fix this by collapsing the two byte[] paths into a single success
path: call __response.EnsureSuccessStatusCode() first, then read the bytes via
__response.Content.ReadAsByteArrayAsync(...) into __content, then invoke
ProcessGetConvaiConversationsByConversationIdAudioResponseContent(httpClient:
HttpClient, httpResponseMessage: __response, content: ref __content), and
finally return __content (preserving the ReadResponseAsString conditional only
if other behavior depends on it).

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs:
- Around line 245-264: In the CreateAudioIsolationAsync convenience overload,
add explicit null checks for the audio and audioname parameters before
constructing __request: if audio is null throw new
ArgumentNullException(nameof(audio)) and if audioname is null throw new
ArgumentNullException(nameof(audioname)). Update the method
(CreateAudioIsolationAsync that builds the
global::G.BodyAudioIsolationV1AudioIsolationPost __request) to perform these
guards so invalid input is rejected rather than being converted to empty values
downstream.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.MusicGenerationClient.CreateMusicStream.g.verified.cs:
- Around line 154-157: The response post-processing hook
ProcessCreateMusicStreamResponseContent is only invoked when
ReadResponseAsString is true, causing consumers to miss the byte[] content hook
on the alternate success path; update the CreateMusicStream response handling so
that ProcessCreateMusicStreamResponseContent(httpClient: HttpClient,
httpResponseMessage: __response, content: ref __content) is called in both
success branches (the ReadResponseAsString true branch and the byte[] return
branch) before returning, ensuring both paths invoke the same post-processing;
do the same change for the other occurrence mentioned (the block around lines
181-191) so both success paths consistently call the hook.
- Around line 167-176: The generated exception drops the buffered response body
(__content) and only uses __response.ReasonPhrase; update the ApiException
construction in CreateMusicStream (where __response, __ex and __content are in
scope) to preserve the response payload by including __content: either append it
to the message passed to new global::G.ApiException or assign it to a
response-body property on the exception instance (e.g., set a
ResponseBody/Content property on the returned ApiException) and keep
ResponseHeaders as-is so unmodeled 4xx/5xx JSON/text payloads are retained for
diagnostics.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs:
- Around line 168-180: The else branch after reading the byte[] (__content) is
missing a call to the partial hook
ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent,
causing consumers to miss the hook when ReadResponseAsString is false; update
the else branch in the
GetPronunciationDictionariesByDictionaryIdByVersionIdDownload response handling
to invoke
ProcessGetPronunciationDictionariesByDictionaryIdByVersionIdDownloadResponseContent(__response,
__content, __headers) (matching the call made in the ReadResponseAsString
branch) before returning __content so the partial method is always executed
regardless of ReadResponseAsString.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs:
- Around line 99-102: The else branch currently reads the response stream into
the unused local __contentStream_302 causing unnecessary I/O; either remove that
branch entirely or consume/dispose the stream content appropriately: locate the
302 error handling block where __contentStream_302 is assigned (the else branch
after the 302 response check) and either delete the await
__response.Content.ReadAsStreamAsync(...) call or replace it with code that
reads/disposes the stream (e.g., copy to a buffer, call ReadAsStringAsync, or
use a using/Dispose) so the stream is not leaked and no unused variable remains.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/SystemTextJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs:
- Around line 155-167: The response-content hook
ProcessCallsRecordingRetrieveResponseContent must be invoked regardless of
ReadResponseAsString; update the code paths in the method handling
CallsClient.CallsRecordingRetrieve (the branch that reads byte[] into __content
and the other byte[] branch) to call
ProcessCallsRecordingRetrieveResponseContent(__response, __content) before
returning, ensuring the hook runs for both byte[] flows and not only when
ReadResponseAsString is true; locate the usages around
__response.EnsureSuccessStatusCode(), the __content variable assignments, and
the early return statements and insert the hook invocation in both byte[] return
paths.

---

Nitpick comments:
In `@src/libs/AutoSDK/Extensions/MimeTypeExtensions.cs`:
- Around line 14-16: The current binary-detection logic in MimeTypeExtensions
(the method that compares normalizedMimeType to "application/octet-stream",
"application/zip" and "audio/*") is too narrow; update that method to also treat
"video/*", "image/*" and "application/pdf" as binary by adding
normalizedMimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase),
normalizedMimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase), and
normalizedMimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase)
(keeping the existing checks for audio, zip, and octet-stream).

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs:
- Around line 223-227: The current catch in CreateMusicStemSeparation throws
G.ApiException using only __response.ReasonPhrase, which loses server
diagnostics; update the throw to include the response body content when
available (e.g., read __response.Content.ReadAsStringAsync() and append or
interpolate it into the message for non-422 errors) while preserving the
existing innerException (__ex) and other exception fields so the full response
context is surfaced in G.ApiException.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs:
- Around line 154-166: The catch block that throws new global::G.ApiException in
GetPronunciationDictionariesByDictionaryIdByVersionIdDownload currently omits
ResponseBody for binary responses; update this block to populate
ApiException.ResponseBody with a concise debug-friendly indicator (e.g.,
"<binary N bytes>" and optionally a short hex/snippet of the first 16 bytes)
rather than the full binary payload, by reading __response.Content as a
byte[]/stream to determine length and snippet before throwing, and ensure you
still set ResponseHeaders and other fields; alternatively, if omission is
intentional, add a brief comment in the catch explaining why ResponseBody is not
set for binary responses.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_`#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs:
- Around line 135-167: The flag ReadResponseAsString is misleading because the
code path reads a byte array; update usages and the flag name to reflect
buffered/binary handling (e.g., rename ReadResponseAsString to
ReadResponseBuffered or BufferResponseContent) and adjust all references in the
same generated client code path (including the conditional around
ReadResponseAsString and any related logic in
ProcessGetVoicesByVoiceIdSamplesBySampleIdAudioResponseContent and
response-returning methods) so the boolean name matches behavior, or change the
condition to a properly named flag in the generator template so generated
methods consistently use the new name.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs:
- Around line 135-141: The flag ReadResponseAsString is misleading for binary
endpoints because both branches call ReadAsByteArrayAsync; update the generator
or surrounding code to either rename the flag to something like
ReadResponseAsBytes/ReadResponseAsBinary or add an inline comment/documentation
next to the ReadResponseAsString usage in the generated method (the conditional
block that reads __response.Content.ReadAsByteArrayAsync) clarifying that this
flag controls response reading behavior for binary payloads and that both
true/false branches will use byte-array reads for this endpoint; ensure
references to ReadResponseAsString in the method and any generation templates
(the conditional around ReadAsByteArrayAsync) are updated consistently.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_`#G.CallsClient.CallsRecordingRetrieve.g.verified.cs:
- Around line 141-153: The catch block that throws G.ApiException currently only
sets ResponseHeaders and loses response body content because content is a
byte[]; update the catch in the same method that builds the ApiException (the
catch handling __ex and constructing new global::G.ApiException) to attempt to
read __response.Content as a byte[] and then: if the bytes decode as UTF-8 (or
other expected text encoding) set the exception's ResponseBody to the decoded
string, otherwise set ResponseBody to a safe representation (e.g., base64 or
null) so binary payloads are preserved; ensure you use the existing
__response.Content and set the ResponseBody property on the created
global::G.ApiException before throwing.

In `@src/tests/AutoSDK.UnitTests/ResponseTypeInferenceTests.cs`:
- Around line 42-47: The test currently asserts byte[] inference via
GeneratedEndPoint output (GenerateEndPoint) but doesn't verify that the
generator emits the Process...ResponseContent hook when ReadResponseAsString is
false; add an assertion that the generated code contains the response-processing
hook placement (e.g., contains a call or method named "Process" + operation name
+ "ResponseContent" or the explicit "Process" method string used by the
generator) when ReadResponseAsString == false, and add a complementary assertion
or small runtime test that toggles ReadResponseAsString true/false to ensure the
code path that calls ReadAsByteArrayAsync and returns __content is only present
when the non-string branch is used; update ResponseTypeInferenceTests (the
GenerateEndPoint-based assertions around
GetAudioAsync/ReadAsByteArrayAsync/return __content) to include these
hook-placement checks for the same cases around lines referenced (also replicate
similar checks for the other two test blocks mentioned).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 53b25f34-df4e-43d8-9e97-5ffef5f16fde

📥 Commits

Reviewing files that changed from the base of the PR and between 9d8270a and 2438ba0.

📒 Files selected for processing (37)
  • src/libs/AutoSDK/Extensions/MimeTypeExtensions.cs
  • src/libs/AutoSDK/Models/EndPoint.cs
  • src/libs/AutoSDK/Models/EndPointResponse.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/CLI/ultravox/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.AudioIsolationClient.CreateAudioIsolationStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.IAgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.IAudioIsolationClient.CreateAudioIsolation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.IAudioIsolationClient.CreateAudioIsolationStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.ISamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusic.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusicDetailed.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.MusicGenerationClient.CreateMusicStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.SpeechHistoryClient.CreateHistoryDownload.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/NewtonsoftJson/_#G.StudioClient.CreateStudioProjectsByProjectIdSnapshotsByProjectSnapshotIdArchive.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AudioIsolationClient.CreateAudioIsolation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.AudioIsolationClient.CreateAudioIsolationStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.IAgentsPlatformClient.GetConvaiConversationsByConversationIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.IAudioIsolationClient.CreateAudioIsolation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.IAudioIsolationClient.CreateAudioIsolationStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.ISamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.CreateMusic.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.CreateMusicDetailed.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.CreateMusicStemSeparation.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.MusicGenerationClient.CreateMusicStream.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.PronunciationDictionaryClient.GetPronunciationDictionariesByDictionaryIdByVersionIdDownload.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.SamplesClient.GetVoicesByVoiceIdSamplesBySampleIdAudio.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.SpeechHistoryClient.CreateHistoryDownload.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_#G.StudioClient.CreateStudioProjectsByProjectIdSnapshotsByProjectSnapshotIdArchive.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/NewtonsoftJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
  • src/tests/AutoSDK.SnapshotTests/Snapshots/ultravox/SystemTextJson/_#G.CallsClient.CallsRecordingRetrieve.g.verified.cs
  • src/tests/AutoSDK.UnitTests/ResponseTypeInferenceTests.cs

Comment on lines +185 to +191
var __content = await __response.Content.ReadAsByteArrayAsync(
#if NET5_0_OR_GREATER
cancellationToken
#endif
).ConfigureAwait(false);

return
await global::System.Text.Json.JsonSerializer.DeserializeAsync<byte[]?>(__content, JsonSerializerOptions).ConfigureAwait(false) ??
throw new global::System.InvalidOperationException("Response deserialization failed.");
return __content;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Invoke ProcessCreateMusicDetailedResponseContent in the non-ReadResponseAsString path too.

Line 154-157 applies the response-content hook, but Line 185-191 returns raw bytes without that hook. This makes partial customization behavior inconsistent based on ReadResponseAsString.

Suggested fix
                 var __content = await __response.Content.ReadAsByteArrayAsync(
 `#if` NET5_0_OR_GREATER
                     cancellationToken
 `#endif`
                 ).ConfigureAwait(false);

+                ProcessCreateMusicDetailedResponseContent(
+                    httpClient: HttpClient,
+                    httpResponseMessage: __response,
+                    content: ref __content);
+
                 return __content;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var __content = await __response.Content.ReadAsByteArrayAsync(
#if NET5_0_OR_GREATER
cancellationToken
#endif
).ConfigureAwait(false);
return
await global::System.Text.Json.JsonSerializer.DeserializeAsync<byte[]?>(__content, JsonSerializerOptions).ConfigureAwait(false) ??
throw new global::System.InvalidOperationException("Response deserialization failed.");
return __content;
var __content = await __response.Content.ReadAsByteArrayAsync(
`#if` NET5_0_OR_GREATER
cancellationToken
`#endif`
).ConfigureAwait(false);
ProcessCreateMusicDetailedResponseContent(
httpClient: HttpClient,
httpResponseMessage: __response,
content: ref __content);
return __content;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/tests/AutoSDK.SnapshotTests/Snapshots/elevenlabs/SystemTextJson/_`#G.MusicGenerationClient.CreateMusicDetailed.g.verified.cs
around lines 185 - 191, The non-ReadResponseAsString branch returns raw bytes
directly and skips the response-content hook; ensure the bytes are passed
through the same hook used in the ReadResponseAsString path by invoking
ProcessCreateMusicDetailedResponseContent(__response, __content, __headers) (or
the existing ProcessCreateMusicDetailedResponseContent method) before returning
from the method that currently returns __content; update the return path in
CreateMusicDetailed/ProcessCreateMusicDetailedResponseContent flow so both
branches apply the hook consistently (use the same parameters the
ReadResponseAsString branch provides).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant