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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
namespace Microsoft.Extensions.AI;

/// <summary>Represents a chat completion client.</summary>
/// <remarks>
/// <para>
/// Unless otherwise specified, all members of <see cref="IChatClient"/> are thread-safe for concurrent use.
/// It is expected that all implementations of <see cref="IChatClient"/> support being used by multiple requests concurrently.
/// </para>
/// <para>
/// However, implementations of <see cref="IChatClient"/> may mutate the arguments supplied to <see cref="CompleteAsync"/> and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"May" seems a bit weak given that mutating the list is the standard mechanism for updating the chat history.

Suggested change
/// However, implementations of <see cref="IChatClient"/> may mutate the arguments supplied to <see cref="CompleteAsync"/> and
/// However, implementations of <see cref="IChatClient"/> do mutate the arguments supplied to <see cref="CompleteAsync"/> and

Copy link
Member Author

@stephentoub stephentoub Oct 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me that suggests that all implementations do, which isn't the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// However, implementations of <see cref="IChatClient"/> may mutate the arguments supplied to <see cref="CompleteAsync"/> and
/// However, implementations of <see cref="IChatClient"/> are permitted to mutate the arguments supplied to <see cref="CompleteAsync"/> and

/// <see cref="CompleteStreamingAsync"/>, such as by adding additional messages to the messages list or configuring the options
/// instance. Thus, consumers of the interface either should avoid using shared instances of these arguments for concurrent
/// invocations or should otherwise ensure by construction that no <see cref="IChatClient"/> instances are used which might employ
/// such mutation. For example, the WithChatOptions method be provided with a callback that could mutate the supplied options
/// argument, and that should be avoided if using a singleton options instance.
/// </para>
/// </remarks>
public interface IChatClient : IDisposable
{
/// <summary>Sends chat messages to the model and returns the response messages.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ namespace Microsoft.Extensions.AI;
/// <summary>Represents a generator of embeddings.</summary>
/// <typeparam name="TInput">The type from which embeddings will be generated.</typeparam>
/// <typeparam name="TEmbedding">The type of embeddings to generate.</typeparam>
/// <remarks>
/// <para>
/// Unless otherwise specified, all members of <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> are thread-safe for concurrent use.
/// It is expected that all implementations of <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> support being used by multiple requests concurrently.
/// </para>
/// <para>
/// However, implementations of <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> may mutate the arguments supplied to
/// <see cref="GenerateAsync"/>, such as by adding additional values to the values list or configuring the options
/// instance. Thus, consumers of the interface either should avoid using shared instances of these arguments for concurrent
/// invocations or should otherwise ensure by construction that no <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> instances
/// are used which might employ such mutation.
/// </para>
/// </remarks>
public interface IEmbeddingGenerator<TInput, TEmbedding> : IDisposable
where TEmbedding : Embedding
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Microsoft.Extensions.AI;

/// <summary>A delegating chat client that updates or replaces the <see cref="ChatOptions"/> used by the remainder of the pipeline.</summary>
/// <remarks>
/// <para>
/// The configuration callback is invoked with the caller-supplied <see cref="ChatOptions"/> instance. To override the caller-supplied options
/// with a new instance, the callback may simply return that new instance, for example <c>_ => new ChatOptions() { MaxTokens = 1000 }</c>. To provide
/// a new instance only if the caller-supplied instance is `null`, the callback may conditionally return a new instance, for example
Expand All @@ -28,6 +29,12 @@ namespace Microsoft.Extensions.AI;
/// return newOptions;
/// }
/// </c>
/// </para>
/// <para>
/// The provided implementation of <see cref="IChatClient"/> is thread-safe for concurrent use so long as the employed configuration
/// callback is also thread-safe for concurrent requests. If callers employ a shared options instance, care should be taken in the
/// configuration callback, as multiple calls to it may end up running in parallel with the same options instance.
/// </para>
/// </remarks>
public sealed class ConfigureOptionsChatClient : DelegatingChatClient
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace Microsoft.Extensions.AI;
/// <summary>
/// A delegating chat client that caches the results of completion calls, storing them as JSON in an <see cref="IDistributedCache"/>.
/// </summary>
/// <remarks>
/// The provided implementation of <see cref="IChatClient"/> is thread-safe for concurrent use so long as the employed
/// <see cref="IDistributedCache"/> is similarly thread-safe for concurrent use.
/// </remarks>
public class DistributedCachingChatClient : CachingChatClient
{
private readonly IDistributedCache _storage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,22 @@ namespace Microsoft.Extensions.AI;
/// Include this in a chat pipeline to resolve function calls automatically.
/// </summary>
/// <remarks>
/// <para>
/// When this client receives a <see cref="FunctionCallContent"/> in a chat completion, it responds
/// by calling the corresponding <see cref="AIFunction"/> defined in <see cref="ChatOptions"/>,
/// producing a <see cref="FunctionResultContent"/>.
/// </para>
/// <para>
/// The provided implementation of <see cref="IChatClient"/> is thread-safe for concurrent use so long as the
/// <see cref="AIFunction"/> instances employed as part of the supplied <see cref="ChatOptions"/> are also safe.
/// The <see cref="ConcurrentInvocation"/> property may be used to control whether multiple function invocation
/// requests as part of the same request are invocable concurrently, but even with that set to <see langword="false"/>
/// (the default), multiple concurrent requests to this same instance and using the same tools could result in those
/// tools being used concurrently (one per request). For example, a function that accesses the HttpContext of a specific
/// ASP.NET web request should only be used as part of a single <see cref="ChatOptions"/> at a time, and only with
/// <see cref="ConcurrentInvocation"/> set to <see langword="false"/>, in case the inner client decided to issue multiple
/// invocation requests to that same function.
/// </para>
/// </remarks>
public class FunctionInvokingChatClient : DelegatingChatClient
{
Expand Down Expand Up @@ -49,6 +62,10 @@ public FunctionInvokingChatClient(IChatClient innerClient)
/// to continue attempting function calls until <see cref="MaximumIterationsPerRequest"/> is reached.
/// </para>
/// <para>
/// Changing the value of this property while the client is in use may result in inconsistencies
/// as to whether errors are retried during an in-flight request.
/// </para>
/// <para>
/// The default value is <see langword="false"/>.
/// </para>
/// </remarks>
Expand All @@ -73,6 +90,10 @@ public FunctionInvokingChatClient(IChatClient innerClient)
/// result in disclosing the raw exception information to external users, which may be a security
/// concern depending on the application scenario.
/// </para>
/// <para>
/// Changing the value of this property while the client is in use may result in inconsistencies
/// as to whether detailed errors are provided during an in-flight request.
/// </para>
/// </remarks>
public bool DetailedErrors { get; set; }

Expand All @@ -95,6 +116,7 @@ public FunctionInvokingChatClient(IChatClient innerClient)
/// Gets or sets a value indicating whether to keep intermediate messages in the chat history.
/// </summary>
/// <remarks>
/// <para>
/// When the inner <see cref="IChatClient"/> returns <see cref="FunctionCallContent"/> to the
/// <see cref="FunctionInvokingChatClient"/>, the <see cref="FunctionInvokingChatClient"/> adds
/// those messages to the list of messages, along with <see cref="FunctionResultContent"/> instances
Expand All @@ -104,6 +126,11 @@ public FunctionInvokingChatClient(IChatClient innerClient)
/// messages will persist in the <see cref="IList{ChatMessage}"/> list provided to <see cref="CompleteAsync"/>
/// and <see cref="CompleteStreamingAsync"/> by the caller. Set <see cref="KeepFunctionCallingMessages"/>
/// to <see langword="false"/> to remove those messages prior to completing the operation.
/// </para>
/// <para>
/// Changing the value of this property while the client is in use may result in inconsistencies
/// as to whether function calling messages are kept during an in-flight request.
/// </para>
/// </remarks>
public bool KeepFunctionCallingMessages { get; set; } = true;

Expand All @@ -120,6 +147,10 @@ public FunctionInvokingChatClient(IChatClient innerClient)
/// must be at least one, as it includes the initial request.
/// </para>
/// <para>
/// Changing the value of this property while the client is in use may result in inconsistencies
/// as to how many iterations are allowed for an in-flight request.
/// </para>
/// <para>
/// The default value is <see langword="null"/>.
/// </para>
/// </remarks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
namespace Microsoft.Extensions.AI;

/// <summary>A delegating chat client that logs chat operations to an <see cref="ILogger"/>.</summary>
/// <para>
/// The provided implementation of <see cref="IChatClient"/> is thread-safe for concurrent use so long as the
/// <see cref="ILogger"/> employed is also thread-safe for concurrent use.
/// </para>
public partial class LoggingChatClient : DelegatingChatClient
{
/// <summary>An <see cref="ILogger"/> instance used for all logging.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace Microsoft.Extensions.AI;
/// </summary>
/// <typeparam name="TInput">The type from which embeddings will be generated.</typeparam>
/// <typeparam name="TEmbedding">The type of embeddings to generate.</typeparam>
/// <remarks>
/// The provided implementation of <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> is thread-safe for concurrent
/// use so long as the employed <see cref="IDistributedCache"/> is similarly thread-safe for concurrent use.
/// </remarks>
public class DistributedCachingEmbeddingGenerator<TInput, TEmbedding> : CachingEmbeddingGenerator<TInput, TEmbedding>
where TEmbedding : Embedding
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace Microsoft.Extensions.AI;
/// <summary>A delegating embedding generator that logs embedding generation operations to an <see cref="ILogger"/>.</summary>
/// <typeparam name="TInput">Specifies the type of the input passed to the generator.</typeparam>
/// <typeparam name="TEmbedding">Specifies the type of the embedding instance produced by the generator.</typeparam>
/// <para>
/// The provided implementation of <see cref="IEmbeddingGenerator{TInput, TEmbedding}"/> is thread-safe for concurrent use
/// so long as the <see cref="ILogger"/> employed is also thread-safe for concurrent use.
/// </para>
public partial class LoggingEmbeddingGenerator<TInput, TEmbedding> : DelegatingEmbeddingGenerator<TInput, TEmbedding>
where TEmbedding : Embedding
{
Expand Down
Loading