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
10 changes: 10 additions & 0 deletions src/GenerativeAI.Microsoft/AdditionalPropertyKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ public static class AdditionalPropertiesKeys
/// Key used to indicate the thinking budget in tokens.
/// </summary>
public const string ThinkingBudget = "ThinkingBudget";

/// <summary>
/// Key used to specify response modalities (e.g., text, image).
/// </summary>
public const string ResponseModalities = "ResponseModalities";

/// <summary>
/// Key used to specify the aspect ratio for image generation.
/// </summary>
public const string ImageConfigAspectRatio = "AspectRatio";
}
22 changes: 21 additions & 1 deletion src/GenerativeAI.Microsoft/Extensions/MicrosoftExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,17 @@ private static JsonNode ToJsonNodeResponse(this object? response)
config.ThinkingConfig.IncludeThoughts = includeThoughts;
}

if (options.AdditionalProperties.TryGetValue(AdditionalPropertiesKeys.ResponseModalities, out List<Modality>? modalities))
{
config.ResponseModalities = modalities;
}

if (options.AdditionalProperties.TryGetValue(AdditionalPropertiesKeys.ImageConfigAspectRatio, out string? aspectRatio))
{
config.ImageConfig ??= new ImageConfig();
config.ImageConfig.AspectRatio = aspectRatio;
}

return config;
}

Expand Down Expand Up @@ -394,9 +405,18 @@ public static ChatResponseUpdate ToChatResponseUpdate(this GenerateContentRespon

if (response.Candidates != null)
{
var contents = response.Candidates.Select(s => s.Content).SelectMany(s => s?.Parts ?? new List<Part>()).ToList().ToAiContents(options);

// Add usage information as UsageContent so it gets aggregated by the framework
var usage = ParseContentResponseUsage(response);
if (usage != null)
{
contents.Add(new UsageContent(usage));
}

return new ChatResponseUpdate
{
Contents = response.Candidates.Select(s => s.Content).SelectMany(s => s?.Parts ?? new List<Part>()).ToList().ToAiContents(options),
Contents = contents,
AdditionalProperties = null,
FinishReason = response?.Candidates?.FirstOrDefault()?.FinishReason == FinishReason.OTHER
? ChatFinishReason.Stop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ public class GenerationConfig
/// </summary>
[JsonPropertyName("responseJsonSchema")]
public JsonNode? ResponseJsonSchema { get; set; }

/// <summary>
/// Optional. Image generation configuration for models that support image output.
/// </summary>
[JsonPropertyName("imageConfig")]
public ImageConfig? ImageConfig { get; set; }
}


Expand Down Expand Up @@ -321,4 +327,16 @@ public class ManualRoutingMode
/// </summary>
[JsonPropertyName("modelName")]
public string? ModelName { get; set; }
}

/// <summary>
/// Configuration for image generation in models that support image output (e.g., gemini-2.5-flash-image).
/// </summary>
public class ImageConfig
{
/// <summary>
/// Optional. The aspect ratio for generated images. Common values: "16:9", "9:16", "1:1", "4:3", "3:4".
/// </summary>
[JsonPropertyName("aspectRatio")]
public string? AspectRatio { get; set; }
}