Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;

namespace GenerativeAI.Types;

/// <summary>
/// The configuration for the multi-speaker setup.
/// </summary>
/// <seealso href="https://ai.google.dev/api/generate-content#MultiSpeakerVoiceConfig">See Official API Documentation</seealso>
public class MultiSpeakerVoiceConfig
{
/// <summary>
/// Required. All the enabled speaker voices.
/// </summary>
[JsonPropertyName("speakerVoiceConfigs")]
public List<SpeakerVoiceConfig>? SpeakerVoiceConfigs { get; set; }
Comment on lines +11 to +15
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Inconsistency between "Required" documentation and nullable type.

The property is documented as "Required" but is declared as a nullable type (List<SpeakerVoiceConfig>?). This creates confusion about the API contract.

Please verify the Google API requirements and either:

  1. Remove the ? to make the property non-nullable if it is truly required, or
  2. Change the XML documentation from "Required" to "Optional" if nullable is correct

🌐 Web query:

Google Generative AI MultiSpeakerVoiceConfig required fields

💡 Result:

Required fields for MultiSpeakerVoiceConfig (Google Generative AI / Gemini TTS):

  • speakerVoiceConfigs (array) — required; must contain exactly two SpeakerVoiceConfig entries. [1][2]

Each SpeakerVoiceConfig must include:

  • speaker (string) — required; the speaker name/alias used in the prompt. [1][2]
  • voiceConfig (object) — required; the voice configuration for that speaker (e.g., a PrebuiltVoiceConfig with voiceName). [1][2]

Sources:
[1] Google Generative AI / GenerationConfig (MultiSpeakerVoiceConfig, SpeakerVoiceConfig).
[2] Cloud Text‑to‑Speech / MultiSpeakerVoiceConfig (MultispeakerPrebuiltVoice: speakerAlias, speakerId).


Remove nullable annotation to align with required API contract.

The speakerVoiceConfigs field is required by the Google Generative AI API, but the property is declared as nullable (List<SpeakerVoiceConfig>?). This contradicts the "Required" documentation and creates an invalid API contract.

Change public List<SpeakerVoiceConfig>? SpeakerVoiceConfigs to public List<SpeakerVoiceConfig> SpeakerVoiceConfigs (remove the ?).

🤖 Prompt for AI Agents
In src/GenerativeAI/Types/ContentGeneration/Config/MultiSpeakerVoiceConfig.cs
around lines 11-15, the SpeakerVoiceConfigs property is declared nullable
despite being required by the API; change the property signature from a nullable
List<SpeakerVoiceConfig>? to a non-nullable List<SpeakerVoiceConfig> (remove the
'?'), and ensure it's either initialized (e.g., new List<SpeakerVoiceConfig>()
in the declaration or constructor) or validated so it can never be null at
runtime; also remove or update any downstream null-checks that assume it may be
null.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;

namespace GenerativeAI.Types;

/// <summary>
/// The configuration for a single speaker in a multi speaker setup.
/// </summary>
/// <seealso href="https://ai.google.dev/api/generate-content#SpeakerVoiceConfig">See Official API Documentation</seealso>
public class SpeakerVoiceConfig
{
/// <summary>
/// Required. The name of the speaker to use. Should be the same as in the prompt.
/// </summary>
[JsonPropertyName("speaker")]
public string? Speaker { get; set; }

/// <summary>
/// Required. The configuration for the voice to use.
/// </summary>
[JsonPropertyName("voiceConfig")]
public VoiceConfig? VoiceConfig { get; set; }
Comment on lines +11 to +21
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

Inconsistency: "Required" properties are nullable types.

Both properties are documented as "Required" but are declared as nullable types (string? and VoiceConfig?). This creates ambiguity in the API contract and could lead to runtime errors if consumers assume non-null values based on the documentation.

Consider one of these solutions:

Option 1 (C# 11+): Use the required modifier to enforce initialization:

     /// <summary>
     /// Required. The name of the speaker to use. Should be the same as in the prompt.
     /// </summary>
     [JsonPropertyName("speaker")]
-    public string? Speaker { get; set; }
+    public required string Speaker { get; set; }

     /// <summary>
     /// Required. The configuration for the voice to use.
     /// </summary>
     [JsonPropertyName("voiceConfig")]
-    public VoiceConfig? VoiceConfig { get; set; }
+    public required VoiceConfig VoiceConfig { get; set; }

Option 2: If the properties are truly optional (e.g., for deserialization scenarios), update the documentation to remove "Required":

     /// <summary>
-    /// Required. The name of the speaker to use. Should be the same as in the prompt.
+    /// The name of the speaker to use. Should be the same as in the prompt.
     /// </summary>
     [JsonPropertyName("speaker")]
     public string? Speaker { get; set; }

     /// <summary>
-    /// Required. The configuration for the voice to use.
+    /// The configuration for the voice to use.
     /// </summary>
     [JsonPropertyName("voiceConfig")]
     public VoiceConfig? VoiceConfig { get; set; }
📝 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
/// <summary>
/// Required. The name of the speaker to use. Should be the same as in the prompt.
/// </summary>
[JsonPropertyName("speaker")]
public string? Speaker { get; set; }
/// <summary>
/// Required. The configuration for the voice to use.
/// </summary>
[JsonPropertyName("voiceConfig")]
public VoiceConfig? VoiceConfig { get; set; }
/// <summary>
/// Required. The name of the speaker to use. Should be the same as in the prompt.
/// </summary>
[JsonPropertyName("speaker")]
public required string Speaker { get; set; }
/// <summary>
/// Required. The configuration for the voice to use.
/// </summary>
[JsonPropertyName("voiceConfig")]
public required VoiceConfig VoiceConfig { get; set; }
Suggested change
/// <summary>
/// Required. The name of the speaker to use. Should be the same as in the prompt.
/// </summary>
[JsonPropertyName("speaker")]
public string? Speaker { get; set; }
/// <summary>
/// Required. The configuration for the voice to use.
/// </summary>
[JsonPropertyName("voiceConfig")]
public VoiceConfig? VoiceConfig { get; set; }
/// <summary>
/// The name of the speaker to use. Should be the same as in the prompt.
/// </summary>
[JsonPropertyName("speaker")]
public string? Speaker { get; set; }
/// <summary>
/// The configuration for the voice to use.
/// </summary>
[JsonPropertyName("voiceConfig")]
public VoiceConfig? VoiceConfig { get; set; }
🤖 Prompt for AI Agents
In src/GenerativeAI/Types/ContentGeneration/Config/SpeakerVoiceConfig.cs around
lines 11 to 21, the XML docs mark Speaker and VoiceConfig as "Required" yet the
properties are declared nullable (string? and VoiceConfig?), creating an
inconsistent API contract; fix by making the contract consistent: either (A)
enforce non-nullable initialization by removing the nullable mark and using the
C# 11+ required modifier (or add constructor enforcement/validation) so the
properties are non-nullable, or (B) if they truly can be missing for
deserialization, update the XML docs to remove "Required" (and optionally add
[JsonIgnore(Condition = WhenWritingNull)] or validation logic) — pick one
approach and apply it consistently to both properties.

}
14 changes: 14 additions & 0 deletions src/GenerativeAI/Types/ContentGeneration/Config/SpeechConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,18 @@ public class SpeechConfig
/// </summary>
[JsonPropertyName("voiceConfig")]
public VoiceConfig? VoiceConfig { get; set; }

/// <summary>
/// Optional. The configuration for the multi-speaker setup.
/// It is mutually exclusive with the <see cref="VoiceConfig"/> field.
/// </summary>
[JsonPropertyName("multiSpeakerVoiceConfig")]
public MultiSpeakerVoiceConfig? MultiSpeakerVoiceConfig { get; set; }

/// <summary>
/// Optional. Language code (in BCP 47 format, e.g. "en-US") for speech synthesis.
/// Valid values are shown at the above URI.
/// </summary>
[JsonPropertyName("languageCode")]
public string? LanguageCode { get; set; }
}