Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
Expand Up @@ -26,6 +26,8 @@ namespace Microsoft.Extensions.AI;
[JsonDerivedType(typeof(ToolApprovalResponseContent), typeDiscriminator: "toolApprovalResponse")]
[JsonDerivedType(typeof(McpServerToolCallContent), typeDiscriminator: "mcpServerToolCall")]
[JsonDerivedType(typeof(McpServerToolResultContent), typeDiscriminator: "mcpServerToolResult")]
[JsonDerivedType(typeof(ImageGenerationToolCallContent), typeDiscriminator: "imageGenerationToolCall")]
[JsonDerivedType(typeof(ImageGenerationToolResultContent), typeDiscriminator: "imageGenerationToolResult")]

// These should be added in once they're no longer [Experimental]. If they're included while still
// experimental, any JsonSerializerContext that includes AIContent will incur errors about using
Expand All @@ -34,8 +36,6 @@ namespace Microsoft.Extensions.AI;
// as well as the [JsonSerializable] attributes for them on the JsonContext should be removed.
// [JsonDerivedType(typeof(CodeInterpreterToolCallContent), typeDiscriminator: "codeInterpreterToolCall")]
// [JsonDerivedType(typeof(CodeInterpreterToolResultContent), typeDiscriminator: "codeInterpreterToolResult")]
// [JsonDerivedType(typeof(ImageGenerationToolCallContent), typeDiscriminator: "imageGenerationToolCall")]
// [JsonDerivedType(typeof(ImageGenerationToolResultContent), typeDiscriminator: "imageGenerationToolResult")]
// [JsonDerivedType(typeof(WebSearchToolCallContent), typeDiscriminator: "webSearchToolCall")]
// [JsonDerivedType(typeof(WebSearchToolResultContent), typeDiscriminator: "webSearchToolResult")]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using Microsoft.Shared.DiagnosticIds;

namespace Microsoft.Extensions.AI;

/// <summary>
/// Represents the invocation of an image generation tool call by a hosted service.
/// </summary>
[Experimental(DiagnosticIds.Experiments.AIImageGeneration, UrlFormat = DiagnosticIds.UrlFormat)]
public sealed class ImageGenerationToolCallContent : ToolCallContent
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Shared.DiagnosticIds;

namespace Microsoft.Extensions.AI;

Expand All @@ -14,7 +12,6 @@ namespace Microsoft.Extensions.AI;
/// This content type represents when a hosted AI service invokes an image generation tool.
/// It is informational only and represents the call itself, not the result.
/// </remarks>
[Experimental(DiagnosticIds.Experiments.AIImageGeneration, UrlFormat = DiagnosticIds.UrlFormat)]
public sealed class ImageGenerationToolResultContent : ToolResultContent
Comment thread
jozkee marked this conversation as resolved.
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.Extensions.AI;
/// </summary>
[JsonDerivedType(typeof(FunctionCallContent), "functionCall")]
[JsonDerivedType(typeof(McpServerToolCallContent), "mcpServerToolCall")]
[JsonDerivedType(typeof(ImageGenerationToolCallContent), "imageGenerationToolCall")]

// Same as in AIContent.
// These should be added in once they're no longer [Experimental]. If they're included while still
Expand All @@ -20,7 +21,6 @@ namespace Microsoft.Extensions.AI;
// these lines should be uncommented and the corresponding lines in AIJsonUtilities.CreateDefaultOptions
// as well as the [JsonSerializable] attributes for them on the JsonContext should be removed.
// [JsonDerivedType(typeof(CodeInterpreterToolCallContent), "codeInterpreterToolCall")]
// [JsonDerivedType(typeof(ImageGenerationToolCallContent), "imageGenerationToolCall")]
// [JsonDerivedType(typeof(WebSearchToolCallContent), "webSearchToolCall")]
public class ToolCallContent : AIContent
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.Extensions.AI;
/// </summary>
[JsonDerivedType(typeof(FunctionResultContent), "functionResult")]
[JsonDerivedType(typeof(McpServerToolResultContent), "mcpServerToolResult")]
[JsonDerivedType(typeof(ImageGenerationToolResultContent), "imageGenerationToolResult")]

// Same as in AIContent.
// These should be added in once they're no longer [Experimental]. If they're included while still
Expand All @@ -20,7 +21,6 @@ namespace Microsoft.Extensions.AI;
// these lines should be uncommented and the corresponding lines in AIJsonUtilities.CreateDefaultOptions
// as well as the [JsonSerializable] attributes for them on the JsonContext should be removed.
// [JsonDerivedType(typeof(CodeInterpreterToolResultContent), "codeInterpreterToolResult")]
// [JsonDerivedType(typeof(ImageGenerationToolResultContent), "imageGenerationToolResult")]
// [JsonDerivedType(typeof(WebSearchToolResultContent), "webSearchToolResult")]
public class ToolResultContent : AIContent
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Text.Json.Serialization;
using Microsoft.Shared.DiagnosticIds;

namespace Microsoft.Extensions.AI;

/// <summary>Represents the options for an image generation request.</summary>
[Experimental(DiagnosticIds.Experiments.AIImageGeneration, UrlFormat = DiagnosticIds.UrlFormat)]
public class ImageGenerationOptions
{
/// <summary>Initializes a new instance of the <see cref="ImageGenerationOptions"/> class.</summary>
Expand Down Expand Up @@ -101,7 +98,6 @@ protected ImageGenerationOptions(ImageGenerationOptions? other)
/// <remarks>
/// Not all implementations support all response formats and this value might be ignored by the implementation if not supported.
/// </remarks>
[Experimental(DiagnosticIds.Experiments.AIImageGeneration, UrlFormat = DiagnosticIds.UrlFormat)]
public enum ImageGenerationResponseFormat
{
/// <summary>
Expand All @@ -114,8 +110,4 @@ public enum ImageGenerationResponseFormat
/// </summary>
Data,

/// <summary>
/// The generated image is returned as a hosted resource identifier, which can be used to retrieve the image later.
/// </summary>
Hosted,
Comment thread
jozkee marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"Name": "Microsoft.Extensions.AI.Abstractions, Version=10.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
{
"Name": "Microsoft.Extensions.AI.Abstractions, Version=10.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"Types": [
{
"Type": "sealed class Microsoft.Extensions.AI.AdditionalPropertiesDictionary : Microsoft.Extensions.AI.AdditionalPropertiesDictionary<object?>",
Expand Down Expand Up @@ -2521,29 +2521,29 @@
},
{
"Type": "class Microsoft.Extensions.AI.HostedImageGenerationTool : Microsoft.Extensions.AI.AITool",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.AI.HostedImageGenerationTool.HostedImageGenerationTool();",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "Microsoft.Extensions.AI.HostedImageGenerationTool.HostedImageGenerationTool(System.Collections.Generic.IReadOnlyDictionary<string, object?>? additionalProperties);",
"Stage": "Experimental"
"Stage": "Stable"
}
],
"Properties": [
{
"Member": "override System.Collections.Generic.IReadOnlyDictionary<string, object?> Microsoft.Extensions.AI.HostedImageGenerationTool.AdditionalProperties { get; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override string Microsoft.Extensions.AI.HostedImageGenerationTool.Name { get; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "Microsoft.Extensions.AI.ImageGenerationOptions? Microsoft.Extensions.AI.HostedImageGenerationTool.Options { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
}
]
},
Expand Down Expand Up @@ -2821,53 +2821,53 @@
},
{
"Type": "class Microsoft.Extensions.AI.ImageGenerationOptions",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.AI.ImageGenerationOptions.ImageGenerationOptions();",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "Microsoft.Extensions.AI.ImageGenerationOptions.ImageGenerationOptions(Microsoft.Extensions.AI.ImageGenerationOptions? other);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "virtual Microsoft.Extensions.AI.ImageGenerationOptions Microsoft.Extensions.AI.ImageGenerationOptions.Clone();",
"Stage": "Experimental"
"Stage": "Stable"
}
],
"Properties": [
{
"Member": "Microsoft.Extensions.AI.AdditionalPropertiesDictionary? Microsoft.Extensions.AI.ImageGenerationOptions.AdditionalProperties { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "int? Microsoft.Extensions.AI.ImageGenerationOptions.Count { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "System.Drawing.Size? Microsoft.Extensions.AI.ImageGenerationOptions.ImageSize { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "string? Microsoft.Extensions.AI.ImageGenerationOptions.MediaType { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "string? Microsoft.Extensions.AI.ImageGenerationOptions.ModelId { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "System.Func<Microsoft.Extensions.AI.IImageGenerator, object?>? Microsoft.Extensions.AI.ImageGenerationOptions.RawRepresentationFactory { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "Microsoft.Extensions.AI.ImageGenerationResponseFormat? Microsoft.Extensions.AI.ImageGenerationOptions.ResponseFormat { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "int? Microsoft.Extensions.AI.ImageGenerationOptions.StreamingCount { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
}
]
},
Expand Down Expand Up @@ -2929,54 +2929,49 @@
},
{
"Type": "enum Microsoft.Extensions.AI.ImageGenerationResponseFormat",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.AI.ImageGenerationResponseFormat.ImageGenerationResponseFormat();",
"Stage": "Experimental"
"Stage": "Stable"
}
],
"Fields": [
{
"Member": "const Microsoft.Extensions.AI.ImageGenerationResponseFormat Microsoft.Extensions.AI.ImageGenerationResponseFormat.Data",
"Stage": "Experimental",
"Stage": "Stable",
"Value": "1"
},
{
"Member": "const Microsoft.Extensions.AI.ImageGenerationResponseFormat Microsoft.Extensions.AI.ImageGenerationResponseFormat.Hosted",
"Stage": "Experimental",
"Value": "2"
},
{
"Member": "const Microsoft.Extensions.AI.ImageGenerationResponseFormat Microsoft.Extensions.AI.ImageGenerationResponseFormat.Uri",
"Stage": "Experimental",
"Stage": "Stable",
"Value": "0"
}
]
},
{
"Type": "sealed class Microsoft.Extensions.AI.ImageGenerationToolCallContent : Microsoft.Extensions.AI.ToolCallContent",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.AI.ImageGenerationToolCallContent.ImageGenerationToolCallContent(string callId);",
"Stage": "Experimental"
"Stage": "Stable"
}
]
},
{
"Type": "sealed class Microsoft.Extensions.AI.ImageGenerationToolResultContent : Microsoft.Extensions.AI.ToolResultContent",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.AI.ImageGenerationToolResultContent.ImageGenerationToolResultContent(string callId);",
"Stage": "Experimental"
"Stage": "Stable"
}
],
"Properties": [
{
"Member": "System.Collections.Generic.IList<Microsoft.Extensions.AI.AIContent>? Microsoft.Extensions.AI.ImageGenerationToolResultContent.Outputs { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
}
]
},
Expand Down Expand Up @@ -4811,4 +4806,4 @@
]
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Shared.DiagnosticIds;

namespace Microsoft.Extensions.AI;

Expand All @@ -12,7 +10,6 @@ namespace Microsoft.Extensions.AI;
/// This tool does not itself implement image generation. It is a marker that can be used to inform a service
/// that the service is allowed to perform image generation if the service is capable of doing so.
/// </remarks>
[Experimental(DiagnosticIds.Experiments.AIImageGeneration, UrlFormat = DiagnosticIds.UrlFormat)]
public class HostedImageGenerationTool : AITool
{
Comment thread
jozkee marked this conversation as resolved.
/// <summary>Any additional properties associated with the tool.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ private static JsonSerializerOptions CreateDefaultOptions()
// Once they're no longer [Experimental] and added as [JsonDerivedType] on AIContent, these lines should be removed.
AddAIContentTypeChain(options, typeof(CodeInterpreterToolCallContent), typeDiscriminatorId: "codeInterpreterToolCall", checkBuiltIn: false);
AddAIContentTypeChain(options, typeof(CodeInterpreterToolResultContent), typeDiscriminatorId: "codeInterpreterToolResult", checkBuiltIn: false);
AddAIContentTypeChain(options, typeof(ImageGenerationToolCallContent), typeDiscriminatorId: "imageGenerationToolCall", checkBuiltIn: false);
AddAIContentTypeChain(options, typeof(ImageGenerationToolResultContent), typeDiscriminatorId: "imageGenerationToolResult", checkBuiltIn: false);
AddAIContentTypeChain(options, typeof(WebSearchToolCallContent), typeDiscriminatorId: "webSearchToolCall", checkBuiltIn: false);
AddAIContentTypeChain(options, typeof(WebSearchToolResultContent), typeDiscriminatorId: "webSearchToolResult", checkBuiltIn: false);

Expand Down Expand Up @@ -123,8 +121,6 @@ private static JsonSerializerOptions CreateDefaultOptions()
// and are included via [JsonDerivedType] on AIContent.
[JsonSerializable(typeof(CodeInterpreterToolCallContent))]
[JsonSerializable(typeof(CodeInterpreterToolResultContent))]
[JsonSerializable(typeof(ImageGenerationToolCallContent))]
[JsonSerializable(typeof(ImageGenerationToolResultContent))]
[JsonSerializable(typeof(WebSearchToolCallContent))]
[JsonSerializable(typeof(WebSearchToolResultContent))]
[JsonSerializable(typeof(ResponseContinuationToken))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,6 @@ private OpenAI.Images.ImageGenerationOptions ToOpenAIImageGenerationOptions(Imag
{
ImageGenerationResponseFormat.Uri => GeneratedImageFormat.Uri,
ImageGenerationResponseFormat.Data => GeneratedImageFormat.Bytes,

// ImageGenerationResponseFormat.Hosted not supported by ImageGenerator, however other OpenAI API support file IDs.
_ => (GeneratedImageFormat?)null
};

Expand Down Expand Up @@ -214,8 +212,6 @@ private ImageEditOptions ToOpenAIImageEditOptions(ImageGenerationOptions? option
{
ImageGenerationResponseFormat.Uri => GeneratedImageFormat.Uri,
ImageGenerationResponseFormat.Data => GeneratedImageFormat.Bytes,

// ImageGenerationResponseFormat.Hosted not supported by ImageGenerator, however other OpenAI API support file IDs.
_ => (GeneratedImageFormat?)null
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public void Clone_CreatesIndependentCopy()
[Theory]
[InlineData(ImageGenerationResponseFormat.Uri)]
[InlineData(ImageGenerationResponseFormat.Data)]
[InlineData(ImageGenerationResponseFormat.Hosted)]

public void ImageGenerationResponseFormat_Values_AreValid(ImageGenerationResponseFormat responseFormat)
{
Assert.True(Enum.IsDefined(typeof(ImageGenerationResponseFormat), responseFormat));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Microsoft.Extensions.AI</RootNamespace>
<Description>Stabilization tests for ImageGeneration content types (no MEAI001 suppression).</Description>
</PropertyGroup>

<PropertyGroup>
<!-- No MEAI001 suppression: verifies stabilized types don't expose experimental APIs to consumers -->
<NoWarn>$(NoWarn);CA1063;CA1861;CA2201;VSTHRD003;S104</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>

<PropertyGroup>
<InjectIsExternalInitOnLegacy>true</InjectIsExternalInitOnLegacy>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Microsoft.Extensions.AI.Abstractions.Tests\Contents\ImageGenerationToolCallContentTests.cs" Link="Contents\ImageGenerationToolCallContentTests.cs" />
<Compile Include="..\Microsoft.Extensions.AI.Abstractions.Tests\Contents\ImageGenerationToolResultContentTests.cs" Link="Contents\ImageGenerationToolResultContentTests.cs" />
<Compile Include="..\Microsoft.Extensions.AI.Abstractions.Tests\Tools\HostedImageGenerationToolTests.cs" Link="Tools\HostedImageGenerationToolTests.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.AI.Abstractions\Microsoft.Extensions.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.AI\Microsoft.Extensions.AI.csproj" />
Comment thread
jozkee marked this conversation as resolved.
Outdated
</ItemGroup>
</Project>
Loading