Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita0688e0

Browse files
authored
Address some M.E.AI API feedback (#5860)
- Remove DataContent.ContainsData. While ContainsData could be used to avoid lazily-instantiating a `ReadOnlyMemory<byte>` from a data URI, in all cases examined ContainsData was being used to guard accessing Data, in which case Data.HasValue is sufficient.- Make ToolMode optional. We'd previously said that an implementation could use null to imply None if it wanted, but with this being optional we'd want null to be the same as auto, so I added in an explicit null options. That matches as well with what various other client libs do.- Remove IChatClient/IEmbeddingGenerator.Metadata. GetService can be used instead, reducing what an implementer must implement and what's exposed to a consumer.- Add Complete{Streaming}Async for a single message. We have such accelerators in other places but not here, and it provides a natural grow-up from string to ChatMessage to `IList<ChatMessage>`.- Change UsageDetails.XxTokenCount properties from int? to long?. The AdditionalCounts is already based on longs, and in theory the token counts could exceed int, especially in a situation where UsageData is being used to sum many other call data.- Rename GenerateEmbeddingVectorAsync's TEmbedding to TEmbeddingElement. Everywhere else TEmbedding is used where it represents an Embedding, but here it represents a numerical element in an embedding vector.- Remove setters on FunctionCall/ResultContent for required ctor parameters. Having those setters goes against .NET design guidelines.- Remove FunctionResultContent.Name. It's unnecessary and is actually causing us to do more work in places.
1 parent66bc675 commita0688e0

File tree

56 files changed

+460
-339
lines changed

Some content is hidden

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

56 files changed

+460
-339
lines changed

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatClientExtensions.cs‎

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,25 @@ public static Task<ChatCompletion> CompleteAsync(
4242
_=Throw.IfNull(client);
4343
_=Throw.IfNull(chatMessage);
4444

45-
returnclient.CompleteAsync([newChatMessage(ChatRole.User,chatMessage)],options,cancellationToken);
45+
returnclient.CompleteAsync(newChatMessage(ChatRole.User,chatMessage),options,cancellationToken);
46+
}
47+
48+
/// <summary>Sends a chat message to the model and returns the response messages.</summary>
49+
/// <param name="client">The chat client.</param>
50+
/// <param name="chatMessage">The chat message to send.</param>
51+
/// <param name="options">The chat options to configure the request.</param>
52+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
53+
/// <returns>The response messages generated by the client.</returns>
54+
publicstaticTask<ChatCompletion>CompleteAsync(
55+
thisIChatClientclient,
56+
ChatMessagechatMessage,
57+
ChatOptions?options=null,
58+
CancellationTokencancellationToken=default)
59+
{
60+
_=Throw.IfNull(client);
61+
_=Throw.IfNull(chatMessage);
62+
63+
returnclient.CompleteAsync([chatMessage],options,cancellationToken);
4664
}
4765

4866
/// <summary>Sends a user chat text message to the model and streams the response messages.</summary>
@@ -60,6 +78,24 @@ public static IAsyncEnumerable<StreamingChatCompletionUpdate> CompleteStreamingA
6078
_=Throw.IfNull(client);
6179
_=Throw.IfNull(chatMessage);
6280

63-
returnclient.CompleteStreamingAsync([newChatMessage(ChatRole.User,chatMessage)],options,cancellationToken);
81+
returnclient.CompleteStreamingAsync(newChatMessage(ChatRole.User,chatMessage),options,cancellationToken);
82+
}
83+
84+
/// <summary>Sends a chat message to the model and streams the response messages.</summary>
85+
/// <param name="client">The chat client.</param>
86+
/// <param name="chatMessage">The chat message to send.</param>
87+
/// <param name="options">The chat options to configure the request.</param>
88+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
89+
/// <returns>The response messages generated by the client.</returns>
90+
publicstaticIAsyncEnumerable<StreamingChatCompletionUpdate>CompleteStreamingAsync(
91+
thisIChatClientclient,
92+
ChatMessagechatMessage,
93+
ChatOptions?options=null,
94+
CancellationTokencancellationToken=default)
95+
{
96+
_=Throw.IfNull(client);
97+
_=Throw.IfNull(chatMessage);
98+
99+
returnclient.CompleteStreamingAsync([chatMessage],options,cancellationToken);
64100
}
65101
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public class ChatOptions
5151
publicIList<string>?StopSequences{get;set;}
5252

5353
/// <summary>Gets or sets the tool mode for the chat request.</summary>
54-
publicChatToolModeToolMode{get;set;}=ChatToolMode.Auto;
54+
/// <remarks>The default value is <see langword="null"/>, which is treated the same as <see cref="ChatToolMode.Auto"/>.</remarks>
55+
publicChatToolMode?ToolMode{get;set;}
5556

5657
/// <summary>Gets or sets the list of tools to include with a chat request.</summary>
5758
[JsonIgnore]

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatToolMode.cs‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ namespace Microsoft.Extensions.AI;
99
/// Describes how tools should be selected by a <see cref="IChatClient"/>.
1010
/// </summary>
1111
/// <remarks>
12-
/// The predefined values <see cref="Auto" /> and <see cref="RequireAny"/> are provided.
12+
/// The predefined values <see cref="Auto" />, <see cref="None"/>, and <see cref="RequireAny"/> are provided.
1313
/// To nominate a specific function, use <see cref="RequireSpecific(string)"/>.
1414
/// </remarks>
1515
[JsonPolymorphic(TypeDiscriminatorPropertyName="$type")]
16+
[JsonDerivedType(typeof(NoneChatToolMode),typeDiscriminator:"none")]
1617
[JsonDerivedType(typeof(AutoChatToolMode),typeDiscriminator:"auto")]
1718
[JsonDerivedType(typeof(RequiredChatToolMode),typeDiscriminator:"required")]
1819
#pragma warning disableCA1052// Static holder types should be Static or NotInheritable
@@ -32,7 +33,19 @@ private protected ChatToolMode()
3233
/// <see cref="ChatOptions.Tools"/> can contain zero or more <see cref="AITool"/>
3334
/// instances, and the <see cref="IChatClient"/> is free to invoke zero or more of them.
3435
/// </remarks>
35-
publicstaticAutoChatToolModeAuto{get;}=newAutoChatToolMode();
36+
publicstaticAutoChatToolModeAuto{get;}=new();
37+
38+
/// <summary>
39+
/// Gets a predefined <see cref="ChatToolMode"/> indicating that tool usage is unsupported.
40+
/// </summary>
41+
/// <remarks>
42+
/// <see cref="ChatOptions.Tools"/> can contain zero or more <see cref="AITool"/>
43+
/// instances, but the <see cref="IChatClient"/> should not request the invocation of
44+
/// any of them. This can be used when the <see cref="IChatClient"/> should know about
45+
/// tools in order to provide information about them or plan out their usage, but should
46+
/// not request the invocation of any of them.
47+
/// </remarks>
48+
publicstaticNoneChatToolModeNone{get;}=new();
3649

3750
/// <summary>
3851
/// Gets a predefined <see cref="ChatToolMode"/> indicating that tool usage is required,

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/DelegatingChatClient.cs‎

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ public void Dispose()
3737
/// <summary>Gets the inner <see cref="IChatClient" />.</summary>
3838
protectedIChatClientInnerClient{get;}
3939

40-
/// <summary>Provides a mechanism for releasing unmanaged resources.</summary>
41-
/// <param name="disposing"><see langword="true"/> if being called from <see cref="Dispose()"/>; otherwise, <see langword="false"/>.</param>
42-
protectedvirtualvoidDispose(booldisposing)
43-
{
44-
if(disposing)
45-
{
46-
InnerClient.Dispose();
47-
}
48-
}
49-
50-
/// <inheritdoc />
51-
publicvirtualChatClientMetadataMetadata=>InnerClient.Metadata;
52-
5340
/// <inheritdoc />
5441
publicvirtualTask<ChatCompletion>CompleteAsync(IList<ChatMessage>chatMessages,ChatOptions?options=null,CancellationTokencancellationToken=default)
5542
{
@@ -72,4 +59,14 @@ public virtual IAsyncEnumerable<StreamingChatCompletionUpdate> CompleteStreaming
7259
serviceKeyisnull&&serviceType.IsInstanceOfType(this)?this:
7360
InnerClient.GetService(serviceType,serviceKey);
7461
}
62+
63+
/// <summary>Provides a mechanism for releasing unmanaged resources.</summary>
64+
/// <param name="disposing"><see langword="true"/> if being called from <see cref="Dispose()"/>; otherwise, <see langword="false"/>.</param>
65+
protectedvirtualvoidDispose(booldisposing)
66+
{
67+
if(disposing)
68+
{
69+
InnerClient.Dispose();
70+
}
71+
}
7572
}

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/IChatClient.cs‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ IAsyncEnumerable<StreamingChatCompletionUpdate> CompleteStreamingAsync(
5353
ChatOptions?options=null,
5454
CancellationTokencancellationToken=default);
5555

56-
/// <summary>Gets metadata that describes the <see cref="IChatClient"/>.</summary>
57-
ChatClientMetadataMetadata{get;}
58-
5956
/// <summary>Asks the <see cref="IChatClient"/> for an object of the specified type <paramref name="serviceType"/>.</summary>
6057
/// <param name="serviceType">The type of object being requested.</param>
6158
/// <param name="serviceKey">An optional key that can be used to help identify the target service.</param>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
usingSystem.Diagnostics;
5+
6+
namespaceMicrosoft.Extensions.AI;
7+
8+
/// <summary>
9+
/// Indicates that an <see cref="IChatClient"/> should not request the invocation of any tools.
10+
/// </summary>
11+
/// <remarks>
12+
/// Use <see cref="ChatToolMode.None"/> to get an instance of <see cref="NoneChatToolMode"/>.
13+
/// </remarks>
14+
[DebuggerDisplay("None")]
15+
publicsealedclassNoneChatToolMode:ChatToolMode
16+
{
17+
/// <summary>Initializes a new instance of the <see cref="NoneChatToolMode"/> class.</summary>
18+
/// <remarks>Use <see cref="ChatToolMode.None"/> to get an instance of <see cref="NoneChatToolMode"/>.</remarks>
19+
publicNoneChatToolMode()
20+
{
21+
}// must exist in support of polymorphic deserialization of a ChatToolMode
22+
23+
/// <inheritdoc/>
24+
publicoverrideboolEquals(object?obj)=>objisNoneChatToolMode;
25+
26+
/// <inheritdoc/>
27+
publicoverrideintGetHashCode()=>typeof(NoneChatToolMode).GetHashCode();
28+
}

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/DataContent.cs‎

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,22 +172,13 @@ public string Uri
172172
[JsonPropertyOrder(1)]
173173
publicstring?MediaType{get;privateset;}
174174

175-
/// <summary>
176-
/// Gets a value indicating whether the content contains data rather than only being a reference to data.
177-
/// </summary>
178-
/// <remarks>
179-
/// If the instance is constructed from a <see cref="ReadOnlyMemory{Byte}"/> or from a data URI, this property returns <see langword="true"/>,
180-
/// as the instance actually contains all of the data it represents. If, however, the instance was constructed from another form of URI, one
181-
/// that simply references where the data can be found but doesn't actually contain the data, this property returns <see langword="false"/>.
182-
/// </remarks>
183-
[MemberNotNullWhen(true,nameof(Data))]
184-
[JsonIgnore]
185-
publicboolContainsData=>_dataUriis notnull||_datais notnull;
186-
187175
/// <summary>Gets the data represented by this instance.</summary>
188176
/// <remarks>
189-
/// If <see cref="ContainsData"/> is <see langword="true" />, this property returns the represented data.
190-
/// If <see cref="ContainsData"/> is <see langword="false" />, this property returns <see langword="null" />.
177+
/// If the instance was constructed from a <see cref="ReadOnlyMemory{Byte}"/>, this property returns that data.
178+
/// If the instance was constructed from a data URI, this property the data contained within the data URI.
179+
/// If, however, the instance was constructed from another form of URI, one that simply references where the
180+
/// data can be found but doesn't actually contain the data, this property returns <see langword="null"/>;
181+
/// no attempt is made to retrieve the data from that URI.
191182
/// </remarks>
192183
[JsonIgnore]
193184
publicReadOnlyMemory<byte>?Data

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionCallContent.cs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ public sealed class FunctionCallContent : AIContent
2525
[JsonConstructor]
2626
publicFunctionCallContent(stringcallId,stringname,IDictionary<string,object?>?arguments=null)
2727
{
28+
CallId=Throw.IfNull(callId);
2829
Name=Throw.IfNull(name);
29-
CallId=callId;
3030
Arguments=arguments;
3131
}
3232

3333
/// <summary>
34-
/// Getsor setsthe function call ID.
34+
/// Gets the function call ID.
3535
/// </summary>
36-
publicstringCallId{get;set;}
36+
publicstringCallId{get;}
3737

3838
/// <summary>
39-
/// Getsor setsthe name of the function requested.
39+
/// Gets the name of the function requested.
4040
/// </summary>
41-
publicstringName{get;set;}
41+
publicstringName{get;}
4242

4343
/// <summary>
4444
/// Gets or sets the arguments requested to be provided to the function.

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionResultContent.cs‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,26 @@ public sealed class FunctionResultContent : AIContent
1919
/// Initializes a new instance of the <see cref="FunctionResultContent"/> class.
2020
/// </summary>
2121
/// <param name="callId">The function call ID for which this is the result.</param>
22-
/// <param name="name">The function name that produced the result.</param>
2322
/// <param name="result">
2423
/// <see langword="null"/> if the function returned <see langword="null"/> or was void-returning
2524
/// and thus had no result, or if the function call failed. Typically, however, to provide meaningfully representative
2625
/// information to an AI service, a human-readable representation of those conditions should be supplied.
2726
/// </param>
2827
[JsonConstructor]
29-
publicFunctionResultContent(stringcallId,stringname,object?result)
28+
publicFunctionResultContent(stringcallId,object?result)
3029
{
3130
CallId=Throw.IfNull(callId);
32-
Name=Throw.IfNull(name);
3331
Result=result;
3432
}
3533

3634
/// <summary>
37-
/// Getsor setsthe ID of the function call for which this is the result.
35+
/// Gets the ID of the function call for which this is the result.
3836
/// </summary>
3937
/// <remarks>
4038
/// If this is the result for a <see cref="FunctionCallContent"/>, this property should contain the same
4139
/// <see cref="FunctionCallContent.CallId"/> value.
4240
/// </remarks>
43-
publicstringCallId{get;set;}
44-
45-
/// <summary>
46-
/// Gets or sets the name of the function that was called.
47-
/// </summary>
48-
publicstringName{get;set;}
41+
publicstringCallId{get;}
4942

5043
/// <summary>
5144
/// Gets or sets the result of the function call, or a generic error message if the function call failed.

‎src/Libraries/Microsoft.Extensions.AI.Abstractions/Embeddings/DelegatingEmbeddingGenerator.cs‎

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,6 @@ public void Dispose()
4040
GC.SuppressFinalize(this);
4141
}
4242

43-
/// <summary>Provides a mechanism for releasing unmanaged resources.</summary>
44-
/// <param name="disposing"><see langword="true"/> if being called from <see cref="Dispose()"/>; otherwise, <see langword="false"/>.</param>
45-
protectedvirtualvoidDispose(booldisposing)
46-
{
47-
if(disposing)
48-
{
49-
InnerGenerator.Dispose();
50-
}
51-
}
52-
53-
/// <inheritdoc />
54-
publicvirtualEmbeddingGeneratorMetadataMetadata=>
55-
InnerGenerator.Metadata;
56-
5743
/// <inheritdoc />
5844
publicvirtualTask<GeneratedEmbeddings<TEmbedding>>GenerateAsync(IEnumerable<TInput>values,EmbeddingGenerationOptions?options=null,CancellationTokencancellationToken=default)=>
5945
InnerGenerator.GenerateAsync(values,options,cancellationToken);
@@ -68,4 +54,14 @@ public virtual Task<GeneratedEmbeddings<TEmbedding>> GenerateAsync(IEnumerable<T
6854
serviceKeyisnull&&serviceType.IsInstanceOfType(this)?this:
6955
InnerGenerator.GetService(serviceType,serviceKey);
7056
}
57+
58+
/// <summary>Provides a mechanism for releasing unmanaged resources.</summary>
59+
/// <param name="disposing"><see langword="true"/> if being called from <see cref="Dispose()"/>; otherwise, <see langword="false"/>.</param>
60+
protectedvirtualvoidDispose(booldisposing)
61+
{
62+
if(disposing)
63+
{
64+
InnerGenerator.Dispose();
65+
}
66+
}
7167
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp