diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationOptions.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationOptions.cs
index 3931173acfc..bf95b5d5aed 100644
--- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationOptions.cs
+++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationOptions.cs
@@ -59,12 +59,16 @@ public class ImageGenerationOptions
///
public ImageGenerationResponseFormat? ResponseFormat { get; set; }
+ /// Gets or sets any additional properties associated with the options.
+ public AdditionalPropertiesDictionary? AdditionalProperties { get; set; }
+
/// Produces a clone of the current instance.
/// A clone of the current instance.
public virtual ImageGenerationOptions Clone()
{
ImageGenerationOptions options = new()
{
+ AdditionalProperties = AdditionalProperties?.Clone(),
Count = Count,
MediaType = MediaType,
ImageSize = ImageSize,
diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationResponse.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationResponse.cs
index 40011821293..53c33b22978 100644
--- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationResponse.cs
+++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Image/ImageGenerationResponse.cs
@@ -51,4 +51,7 @@ public IList Contents
get => _contents ??= [];
set => _contents = value;
}
+
+ /// Gets or sets usage details for the image generation response.
+ public UsageDetails? Usage { get; set; }
}
diff --git a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIImageGenerator.cs b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIImageGenerator.cs
index b2ceb5cb317..9281167d917 100644
--- a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIImageGenerator.cs
+++ b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIImageGenerator.cs
@@ -163,9 +163,28 @@ private static ImageGenerationResponse ToImageGenerationResponse(GeneratedImageC
}
}
+ UsageDetails? ud = null;
+ if (generatedImages.Usage is { } usage)
+ {
+ ud = new()
+ {
+ InputTokenCount = usage.InputTokenCount,
+ OutputTokenCount = usage.OutputTokenCount,
+ TotalTokenCount = usage.TotalTokenCount,
+ };
+
+ if (usage.InputTokenDetails is { } inputDetails)
+ {
+ ud.AdditionalCounts ??= [];
+ ud.AdditionalCounts.Add($"{nameof(usage.InputTokenDetails)}.{nameof(inputDetails.ImageTokenCount)}", inputDetails.ImageTokenCount);
+ ud.AdditionalCounts.Add($"{nameof(usage.InputTokenDetails)}.{nameof(inputDetails.TextTokenCount)}", inputDetails.TextTokenCount);
+ }
+ }
+
return new ImageGenerationResponse(contents)
{
- RawRepresentation = generatedImages
+ RawRepresentation = generatedImages,
+ Usage = ud,
};
}
diff --git a/src/Libraries/Microsoft.Extensions.AI/CHANGELOG.md b/src/Libraries/Microsoft.Extensions.AI/CHANGELOG.md
index 1a4e630ca0a..71aa3927034 100644
--- a/src/Libraries/Microsoft.Extensions.AI/CHANGELOG.md
+++ b/src/Libraries/Microsoft.Extensions.AI/CHANGELOG.md
@@ -3,6 +3,7 @@
## NOT YET RELEASED
- Updated the EnableSensitiveData properties on OpenTelemetryChatClient/EmbeddingGenerator to respect a OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT environment variable.
+- Added OpenTelemetryImageGenerator to provide OpenTelemetry instrumentation for IImageGenerator implementations.
## 9.9.0
diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
index d06ec3d3b5e..41cbc3a140f 100644
--- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
@@ -217,7 +217,7 @@ public override async IAsyncEnumerable GetStreamingResponseA
}
}
- private static string SerializeChatMessages(IEnumerable messages, ChatFinishReason? chatFinishReason = null)
+ internal static string SerializeChatMessages(IEnumerable messages, ChatFinishReason? chatFinishReason = null)
{
List