Skip to content

Commit e80caff

Browse files
jeffhandleypeterwaldShyam Namboodiripadjozkeeartl93
authored
Staging the MEAI 9.4.3 Release (#6353)
* Merged PR 49569: Cherry pick Evaluation changes for 9.4.3 release * Update package-lock.json for Evaluations * Reset package-lock.json to same as main branch * Merged PR 49585: [9.4.3] [cherry pick] A couple of minor fixes A couple of minor fixes 1. Adds back tool tip for metrics which are useful in cases where the metric name is long and does not fit entirely in the card 2. Makes the size of the selection buttons on the left of cards consistent with the size of status icons on the right to make the alignment cleaner 3. Implement IEquatable for UrlCacheKey (per Copilot's suggestion) 4. Throw ArgumentException when the number of messages passed to ContentSafetyChatClient does not match expectations (also per Copilot's suggestion) * Add test for optional parameters being required with RequireAllProperties (#6265) * Add test for optional parameters being required with RequireAllProperties * Test both requireAllProperties values * Use AssertDeepEquals that logs the difference to other tests * Adding reference to an unsupported built-in tool on OpenAI Chat API no longer throws (#6276) * Update M.E.AI changelogs (#6269) * Augment UseDistributedCache XML docs (#6256) * Augment AIFunctionFactory.Create XML docs (#6255) * Rename EmbeddingGeneratorExtensions.GenerateEmbedding extension methods (#6295) To align with the the base method on IEmbeddingGenerator * Augment FunctionInvokingChatClient's span with token counts (#6296) * Rename ChatThreadId to ConversationId (#6300) * In OpenAI responses client, use response ID as ChatThreadId * Rename ChatThreadId -> ConversationId * Related renames * Restore deleted members as obsolete (#6304) * Restore EmbeddingGeneratorExtensions members as obsolete * Restore ChatThreadId as obsolete * Restore ChatResponse.ChatThreadId and ChatResponseUpdate.ChatThreadId as obsolete. * Remove the tests for obsolete members * Remove the Embeddings tests for obsolete members * Support [FromKeyedServices] in AIFunctionFactory (#6310) * Utilize IServiceProviderIsService in AIFunctionFactory (#6317) Add AIFunctionFactoryOptions.Services, and use it when examining function parameters to determine whether they should be resolved by default from DI. * Remove AsChatClient/AsEmbeddingGenerator that were obsoleted in 9.4.0-preview.1.25207.5 (#6327) * Add ChatOptions.AllowMultipleToolCalls (#6326) * Add ChatOptions.AllowMultipleToolCalls * Use it in OpenAI adapter * Disable default required property schema generation and OpenAI strict mode. (#6285) * Disable default required property schema generation and OpenAI strict mode. * Default strictness to OpenAI client defaults. * Fix a few failing tests. * Undo a number of additional changes made by #6064 * Revert change to structured output defaults. * Incorporate more test fixes. * Address feedback. * Tweak strict mode signature, fix failing tests. * Roll back schemaIsStrict flag from ChatResponseFormat. * Merged PR 49624: [9.4.3] [cherry-pick] Update readmes (#6345) Includes name of new metric that was added to Quality package. Also updates some doc comments. * Bump version to 9.4.3 * Merged PR 49636: [9.4.3] [cherry-pick] Skip messages that have no text when rendering conversations as part of evaluation prompts (#6349) * Add test for optional parameters being required with RequireAllProperties (#6265) * Add test for optional parameters being required with RequireAllProperties * Test both requireAllProperties values * Use AssertDeepEquals that logs the difference to other tests * Adding reference to an unsupported built-in tool on OpenAI Chat API no longer throws (#6276) * Update M.E.AI changelogs (#6269) * Augment UseDistributedCache XML docs (#6256) * Augment AIFunctionFactory.Create XML docs (#6255) * Rename EmbeddingGeneratorExtensions.GenerateEmbedding extension methods (#6295) To align with the the base method on IEmbeddingGenerator * Augment FunctionInvokingChatClient's span with token counts (#6296) * Rename ChatThreadId to ConversationId (#6300) * In OpenAI responses client, use response ID as ChatThreadId * Rename ChatThreadId -> ConversationId * Related renames * Restore deleted members as obsolete (#6304) * Restore EmbeddingGeneratorExtensions members as obsolete * Restore ChatThreadId as obsolete * Restore ChatResponse.ChatThreadId and ChatResponseUpdate.ChatThreadId as obsolete. * Remove the tests for obsolete members * Remove the Embeddings tests for obsolete members * Support [FromKeyedServices] in AIFunctionFactory (#6310) * Utilize IServiceProviderIsService in AIFunctionFactory (#6317) Add AIFunctionFactoryOptions.Services, and use it when examining function parameters to determine whether they should be resolved by default from DI. * Remove AsChatClient/AsEmbeddingGenerator that were obsoleted in 9.4.0-preview.1.25207.5 (#6327) * Add ChatOptions.AllowMultipleToolCalls (#6326) * Add ChatOptions.AllowMultipleToolCalls * Use it in OpenAI adapter * Disable default required property schema generation and OpenAI strict mode. (#6285) * Disable default required property schema generation and OpenAI strict mode. * Default strictness to OpenAI client defaults. * Fix a few failing tests. * Undo a number of additional changes made by #6064 * Revert change to structured output defaults. * Incorporate more test fixes. * Address feedback. * Tweak strict mode signature, fix failing tests. * Roll back schemaIsStrict flag from ChatResponseFormat. * Bump version to 9.4.3 * Merged PR 49636: [9.4.3] [cherry-pick] Skip messages that have no text when rendering conversations as part of evaluation prompts (#6349) * Update chat template dependencies, fix OpenAI/Aspire config, and address build warnings (#6280) * Update chat template dependencies * Update test snapshots * Update Aspire version * Revert Aspire + update CommunityToolkit.Aspire * Open README in VS after project creation * Add Known Issue to Aspire README for Qdrant * Update survey template URL * Set the Project Template package version to -preview.2 * Update template baseline * Update template pinned versions * Do not append template args to snapshot names * Fix vector store index in the README. Add an AzureAISearch template test. * Add a note to the Aspire README for trusting the development certificate * Use AddOpenAIClient for OpenAI and AddAzureOpenAIClient for Azure OpenAI * Remove duplicated using System.ClientModel * Update Aspire README to specify the exception thrown for the known issue * Augment the Aspire README for more Docker notes for Ollama and Qdrant * Fix Microsoft.Extensions.Http.Resilience warnings with separate pinned versions * Update test baseline for: Rename EmbeddingGeneratorExtensions.GenerateEmbedding extension methods (#6295) * Add --managed-identity to the template developer README * Apply the Ollama timeout recommendation in the template code * Call http.RemoveAllResilienceHandlers before adding the handler * Update template test baseline --------- Co-authored-by: Jeff Handley <[email protected]> Co-authored-by: David Cantu <[email protected]> * Expose AIContent constructor (#6346) * Add PDF support to OpenAI AsIChatClient (#6344) * Add PDF support to OpenAI AsIChatClient * Add missing reference * Make CreateJsonSchema tolerate JSO inputs that don't have a resolver set. (#6348) * Update MEAI.Templates to use the just-built version of the libraries * Enhance Function Invocation Extensibility for Microsoft.Extensions.AI (#6325) --------- Co-authored-by: Peter Waldschmidt <[email protected]> Co-authored-by: Peter Waldschmidt <[email protected]> Co-authored-by: Shyam Namboodiripad <[email protected]> Co-authored-by: David Cantú <[email protected]> Co-authored-by: Art Leonard <[email protected]> Co-authored-by: Stephen Toub <[email protected]> Co-authored-by: Shay Rojansky <[email protected]> Co-authored-by: Steve Sanderson <[email protected]> Co-authored-by: Eirik Tsarpalis <[email protected]> Co-authored-by: Mackinnon Buck <[email protected]> Co-authored-by: Roger Barreto <[email protected]>
1 parent c9aa5d3 commit e80caff

File tree

184 files changed

+7975
-3443
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+7975
-3443
lines changed

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup Label="Version settings">
33
<MajorVersion>9</MajorVersion>
44
<MinorVersion>4</MinorVersion>
5-
<PatchVersion>2</PatchVersion>
5+
<PatchVersion>3</PatchVersion>
66
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
77
<PreReleaseVersionIteration>1</PreReleaseVersionIteration>
88
<VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix>

eng/packages/TestOnly.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<PackageVersion Include="Moq.AutoMock" Version="3.1.0" />
1919
<PackageVersion Include="Moq" Version="4.18.4" />
2020
<PackageVersion Include="OpenTelemetry.Exporter.InMemory" Version="1.9.0" />
21+
<PackageVersion Include="PdfPig" Version="0.1.10-alpha-20250203-fdb88" />
2122
<PackageVersion Include="Polly.Testing" Version="8.4.2" />
2223
<PackageVersion Include="StrongNamer" Version="0.2.5" />
2324
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerVersion)" />

src/Libraries/Microsoft.Extensions.AI.Abstractions/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Release History
22

3+
## 9.4.0-preview.1.25207.5
4+
5+
- Added `ErrorContent` and `TextReasoningContent`.
6+
- Added `MessageId` to `ChatMessage` and `ChatResponseUpdate`.
7+
- Added `AIFunctionArguments`, changing `AIFunction.InvokeAsync` to accept one and to return a `ValueTask`.
8+
- Updated `AIJsonUtilities`'s schema generation to not use `default` when `RequireAllProperties` is set to `true`.
9+
- Added `ISpeechToTextClient` and supporting types.
10+
- Fixed several issues related to Native AOT support.
11+
312
## 9.3.0-preview.1.25161.3
413

514
- Changed `IChatClient.GetResponseAsync` and `IChatClient.GetStreamingResponseAsync` to accept an `IEnumerable<ChatMessage>` rather than an `IList<ChatMessage>`. It is no longer mutated by implementations.

src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatOptions.cs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,18 @@ namespace Microsoft.Extensions.AI;
99
/// <summary>Represents the options for a chat request.</summary>
1010
public class ChatOptions
1111
{
12-
/// <summary>Gets or sets an optional identifier used to associate a request with an existing chat thread.</summary>
13-
public string? ChatThreadId { get; set; }
12+
/// <summary>Gets or sets an optional identifier used to associate a request with an existing conversation.</summary>
13+
/// <remarks>This property is obsolete. Use <see cref="ConversationId"/> instead.</remarks>
14+
[System.Obsolete("Use ConversationId instead.")]
15+
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
16+
public string? ChatThreadId
17+
{
18+
get => ConversationId;
19+
set => ConversationId = value;
20+
}
21+
22+
/// <summary>Gets or sets an optional identifier used to associate a request with an existing conversation.</summary>
23+
public string? ConversationId { get; set; }
1424

1525
/// <summary>Gets or sets the temperature for generating chat responses.</summary>
1626
/// <remarks>
@@ -83,6 +93,23 @@ public class ChatOptions
8393
/// </remarks>
8494
public IList<string>? StopSequences { get; set; }
8595

96+
/// <summary>
97+
/// Gets or sets a flag to indicate whether a single response is allowed to include multiple tool calls.
98+
/// If <see langword="false"/>, the <see cref="IChatClient"/> is asked to return a maximum of one tool call per request.
99+
/// If <see langword="true"/>, there is no limit.
100+
/// If <see langword="null"/>, the provider may select its own default.
101+
/// </summary>
102+
/// <remarks>
103+
/// <para>
104+
/// When used with function calling middleware, this does not affect the ability to perform multiple function calls in sequence.
105+
/// It only affects the number of function calls within a single iteration of the function calling loop.
106+
/// </para>
107+
/// <para>
108+
/// The underlying provider is not guaranteed to support or honor this flag. For example it may choose to ignore it and return multiple tool calls regardless.
109+
/// </para>
110+
/// </remarks>
111+
public bool? AllowMultipleToolCalls { get; set; }
112+
86113
/// <summary>Gets or sets the tool mode for the chat request.</summary>
87114
/// <remarks>The default value is <see langword="null"/>, which is treated the same as <see cref="ChatToolMode.Auto"/>.</remarks>
88115
public ChatToolMode? ToolMode { get; set; }
@@ -105,7 +132,7 @@ public virtual ChatOptions Clone()
105132
{
106133
ChatOptions options = new()
107134
{
108-
ChatThreadId = ChatThreadId,
135+
ConversationId = ConversationId,
109136
Temperature = Temperature,
110137
MaxOutputTokens = MaxOutputTokens,
111138
TopP = TopP,
@@ -115,6 +142,7 @@ public virtual ChatOptions Clone()
115142
Seed = Seed,
116143
ResponseFormat = ResponseFormat,
117144
ModelId = ModelId,
145+
AllowMultipleToolCalls = AllowMultipleToolCalls,
118146
ToolMode = ToolMode,
119147
AdditionalProperties = AdditionalProperties?.Clone(),
120148
};

src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatResponse.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,36 @@ public IList<ChatMessage> Messages
6363
/// <summary>Gets or sets the ID of the chat response.</summary>
6464
public string? ResponseId { get; set; }
6565

66-
/// <summary>Gets or sets the chat thread ID associated with this chat response.</summary>
66+
/// <summary>Gets or sets an identifier for the state of the conversation.</summary>
6767
/// <remarks>
68-
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a chat thread, such that
68+
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a conversation, such that
6969
/// the input messages supplied to <see cref="IChatClient.GetResponseAsync"/> need only be the additional messages beyond
7070
/// what's already stored. If this property is non-<see langword="null"/>, it represents an identifier for that state,
71-
/// and it should be used in a subsequent <see cref="ChatOptions.ChatThreadId"/> instead of supplying the same messages
72-
/// (and this <see cref="ChatResponse"/>'s message) as part of the <c>messages</c> parameter.
71+
/// and it should be used in a subsequent <see cref="ChatOptions.ConversationId"/> instead of supplying the same messages
72+
/// (and this <see cref="ChatResponse"/>'s message) as part of the <c>messages</c> parameter. Note that the value may
73+
/// or may not differ on every response, depending on whether the underlying provider uses a fixed ID for each conversation
74+
/// or updates it for each message.
7375
/// </remarks>
74-
public string? ChatThreadId { get; set; }
76+
/// <remarks>This method is obsolete. Use <see cref="ConversationId"/> instead.</remarks>
77+
[Obsolete("Use ConversationId instead.")]
78+
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
79+
public string? ChatThreadId
80+
{
81+
get => ConversationId;
82+
set => ConversationId = value;
83+
}
84+
85+
/// <summary>Gets or sets an identifier for the state of the conversation.</summary>
86+
/// <remarks>
87+
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a conversation, such that
88+
/// the input messages supplied to <see cref="IChatClient.GetResponseAsync"/> need only be the additional messages beyond
89+
/// what's already stored. If this property is non-<see langword="null"/>, it represents an identifier for that state,
90+
/// and it should be used in a subsequent <see cref="ChatOptions.ConversationId"/> instead of supplying the same messages
91+
/// (and this <see cref="ChatResponse"/>'s message) as part of the <c>messages</c> parameter. Note that the value may
92+
/// or may not differ on every response, depending on whether the underlying provider uses a fixed ID for each conversation
93+
/// or updates it for each message.
94+
/// </remarks>
95+
public string? ConversationId { get; set; }
7596

7697
/// <summary>Gets or sets the model ID used in the creation of the chat response.</summary>
7798
public string? ModelId { get; set; }
@@ -127,7 +148,7 @@ public ChatResponseUpdate[] ToChatResponseUpdates()
127148
ChatMessage message = _messages![i];
128149
updates[i] = new ChatResponseUpdate
129150
{
130-
ChatThreadId = ChatThreadId,
151+
ConversationId = ConversationId,
131152

132153
AdditionalProperties = message.AdditionalProperties,
133154
AuthorName = message.AuthorName,

src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatResponseExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,9 @@ private static void ProcessUpdate(ChatResponseUpdate update, ChatResponse respon
320320
response.ResponseId = update.ResponseId;
321321
}
322322

323-
if (update.ChatThreadId is not null)
323+
if (update.ConversationId is not null)
324324
{
325-
response.ChatThreadId = update.ChatThreadId;
325+
response.ConversationId = update.ConversationId;
326326
}
327327

328328
if (update.CreatedAt is not null)

src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatResponseUpdate.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,34 @@ public IList<AIContent> Contents
116116
/// </remarks>
117117
public string? MessageId { get; set; }
118118

119-
/// <summary>Gets or sets the chat thread ID associated with the chat response of which this update is a part.</summary>
119+
/// <summary>Gets or sets an identifier for the state of the conversation of which this update is a part.</summary>
120120
/// <remarks>
121-
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a chat thread, such that
121+
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a conversation, such that
122122
/// the input messages supplied to <see cref="IChatClient.GetStreamingResponseAsync"/> need only be the additional messages beyond
123123
/// what's already stored. If this property is non-<see langword="null"/>, it represents an identifier for that state,
124-
/// and it should be used in a subsequent <see cref="ChatOptions.ChatThreadId"/> instead of supplying the same messages
125-
/// (and this streaming message) as part of the <c>messages</c> parameter.
124+
/// and it should be used in a subsequent <see cref="ChatOptions.ConversationId"/> instead of supplying the same messages
125+
/// (and this streaming message) as part of the <c>messages</c> parameter. Note that the value may or may not differ on every
126+
/// response, depending on whether the underlying provider uses a fixed ID for each conversation or updates it for each message.
126127
/// </remarks>
127-
public string? ChatThreadId { get; set; }
128+
/// <remarks>This method is obsolete. Use <see cref="ConversationId"/> instead.</remarks>
129+
[Obsolete("Use ConversationId instead.")]
130+
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
131+
public string? ChatThreadId
132+
{
133+
get => ConversationId;
134+
set => ConversationId = value;
135+
}
136+
137+
/// <summary>Gets or sets an identifier for the state of the conversation of which this update is a part.</summary>
138+
/// <remarks>
139+
/// Some <see cref="IChatClient"/> implementations are capable of storing the state for a conversation, such that
140+
/// the input messages supplied to <see cref="IChatClient.GetStreamingResponseAsync"/> need only be the additional messages beyond
141+
/// what's already stored. If this property is non-<see langword="null"/>, it represents an identifier for that state,
142+
/// and it should be used in a subsequent <see cref="ChatOptions.ConversationId"/> instead of supplying the same messages
143+
/// (and this streaming message) as part of the <c>messages</c> parameter. Note that the value may or may not differ on every
144+
/// response, depending on whether the underlying provider uses a fixed ID for each conversation or updates it for each message.
145+
/// </remarks>
146+
public string? ConversationId { get; set; }
128147

129148
/// <summary>Gets or sets a timestamp for the response update.</summary>
130149
public DateTimeOffset? CreatedAt { get; set; }

src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/AIContent.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Microsoft.Extensions.AI;
77

8-
/// <summary>Provides a base class for all content used with AI services.</summary>
8+
/// <summary>Represents content used by AI services.</summary>
99
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")]
1010
[JsonDerivedType(typeof(DataContent), typeDiscriminator: "data")]
1111
[JsonDerivedType(typeof(ErrorContent), typeDiscriminator: "error")]
@@ -20,15 +20,15 @@ public class AIContent
2020
/// <summary>
2121
/// Initializes a new instance of the <see cref="AIContent"/> class.
2222
/// </summary>
23-
protected AIContent()
23+
public AIContent()
2424
{
2525
}
2626

2727
/// <summary>Gets or sets the raw representation of the content from an underlying implementation.</summary>
2828
/// <remarks>
2929
/// If an <see cref="AIContent"/> is created to represent some underlying object from another object
3030
/// model, this property can be used to store that original object. This can be useful for debugging or
31-
/// for enabling a consumer to access the underlying object model if needed.
31+
/// for enabling a consumer to access the underlying object model, if needed.
3232
/// </remarks>
3333
[JsonIgnore]
3434
public object? RawRepresentation { get; set; }

src/Libraries/Microsoft.Extensions.AI.Abstractions/Embeddings/EmbeddingGeneratorExtensions.cs

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,45 @@ public static TService GetRequiredService<TService>(
9999
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
100100
/// <exception cref="InvalidOperationException">The generator did not produce exactly one embedding.</exception>
101101
/// <remarks>
102-
/// This operation is equivalent to using <see cref="GenerateEmbeddingAsync"/> and returning the
102+
/// This operation is equivalent to using <see cref="GenerateAsync"/> and returning the
103103
/// resulting <see cref="Embedding{T}"/>'s <see cref="Embedding{T}.Vector"/> property.
104104
/// </remarks>
105+
/// <remarks>
106+
/// This method is obsolete. Use <see cref="GenerateVectorAsync{TInput, TEmbeddingElement}"/> instead.
107+
/// </remarks>
108+
[Obsolete("Use GenerateVectorAsync<TInput, TEmbeddingElement> instead.")]
109+
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
105110
public static async Task<ReadOnlyMemory<TEmbeddingElement>> GenerateEmbeddingVectorAsync<TInput, TEmbeddingElement>(
106111
this IEmbeddingGenerator<TInput, Embedding<TEmbeddingElement>> generator,
107112
TInput value,
108113
EmbeddingGenerationOptions? options = null,
109114
CancellationToken cancellationToken = default)
110115
{
111-
var embedding = await GenerateEmbeddingAsync(generator, value, options, cancellationToken).ConfigureAwait(false);
116+
return await GenerateVectorAsync(generator, value, options, cancellationToken).ConfigureAwait(false);
117+
}
118+
119+
/// <summary>Generates an embedding vector from the specified <paramref name="value"/>.</summary>
120+
/// <typeparam name="TInput">The type from which embeddings will be generated.</typeparam>
121+
/// <typeparam name="TEmbeddingElement">The numeric type of the embedding data.</typeparam>
122+
/// <param name="generator">The embedding generator.</param>
123+
/// <param name="value">A value from which an embedding will be generated.</param>
124+
/// <param name="options">The embedding generation options to configure the request.</param>
125+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
126+
/// <returns>The generated embedding for the specified <paramref name="value"/>.</returns>
127+
/// <exception cref="ArgumentNullException"><paramref name="generator"/> is <see langword="null"/>.</exception>
128+
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
129+
/// <exception cref="InvalidOperationException">The generator did not produce exactly one embedding.</exception>
130+
/// <remarks>
131+
/// This operation is equivalent to using <see cref="GenerateAsync"/> and returning the
132+
/// resulting <see cref="Embedding{T}"/>'s <see cref="Embedding{T}.Vector"/> property.
133+
/// </remarks>
134+
public static async Task<ReadOnlyMemory<TEmbeddingElement>> GenerateVectorAsync<TInput, TEmbeddingElement>(
135+
this IEmbeddingGenerator<TInput, Embedding<TEmbeddingElement>> generator,
136+
TInput value,
137+
EmbeddingGenerationOptions? options = null,
138+
CancellationToken cancellationToken = default)
139+
{
140+
var embedding = await GenerateAsync(generator, value, options, cancellationToken).ConfigureAwait(false);
112141
return embedding.Vector;
113142
}
114143

@@ -130,12 +159,45 @@ public static async Task<ReadOnlyMemory<TEmbeddingElement>> GenerateEmbeddingVec
130159
/// collection composed of the single <paramref name="value"/> and then returning the first embedding element from the
131160
/// resulting <see cref="GeneratedEmbeddings{TEmbedding}"/> collection.
132161
/// </remarks>
162+
/// <remarks>
163+
/// This method is obsolete. Use <see cref="GenerateAsync{TInput, TEmbedding}"/> instead.
164+
/// </remarks>
165+
[Obsolete("Use GenerateAsync<TInput, TEmbedding> instead.")]
166+
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
133167
public static async Task<TEmbedding> GenerateEmbeddingAsync<TInput, TEmbedding>(
134168
this IEmbeddingGenerator<TInput, TEmbedding> generator,
135169
TInput value,
136170
EmbeddingGenerationOptions? options = null,
137171
CancellationToken cancellationToken = default)
138172
where TEmbedding : Embedding
173+
{
174+
return await GenerateAsync(generator, value, options, cancellationToken).ConfigureAwait(false);
175+
}
176+
177+
/// <summary>Generates an embedding from the specified <paramref name="value"/>.</summary>
178+
/// <typeparam name="TInput">The type from which embeddings will be generated.</typeparam>
179+
/// <typeparam name="TEmbedding">The type of embedding to generate.</typeparam>
180+
/// <param name="generator">The embedding generator.</param>
181+
/// <param name="value">A value from which an embedding will be generated.</param>
182+
/// <param name="options">The embedding generation options to configure the request.</param>
183+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
184+
/// <returns>
185+
/// The generated embedding for the specified <paramref name="value"/>.
186+
/// </returns>
187+
/// <exception cref="ArgumentNullException"><paramref name="generator"/> is <see langword="null"/>.</exception>
188+
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
189+
/// <exception cref="InvalidOperationException">The generator did not produce exactly one embedding.</exception>
190+
/// <remarks>
191+
/// This operations is equivalent to using <see cref="IEmbeddingGenerator{TInput, TEmbedding}.GenerateAsync"/> with a
192+
/// collection composed of the single <paramref name="value"/> and then returning the first embedding element from the
193+
/// resulting <see cref="GeneratedEmbeddings{TEmbedding}"/> collection.
194+
/// </remarks>
195+
public static async Task<TEmbedding> GenerateAsync<TInput, TEmbedding>(
196+
this IEmbeddingGenerator<TInput, TEmbedding> generator,
197+
TInput value,
198+
EmbeddingGenerationOptions? options = null,
199+
CancellationToken cancellationToken = default)
200+
where TEmbedding : Embedding
139201
{
140202
_ = Throw.IfNull(generator);
141203
_ = Throw.IfNull(value);

0 commit comments

Comments
 (0)