Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
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
19 changes: 13 additions & 6 deletions dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ internal async Task NotifyProvidersOfNewMessagesAsync(
ChatOptions? chatOptions,
CancellationToken cancellationToken)
{
ChatHistoryProvider? chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions);
ChatHistoryProvider? chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions, session);

if (chatHistoryProvider is not null)
{
Expand Down Expand Up @@ -508,7 +508,7 @@ internal async Task NotifyProvidersOfFailureAsync(
ChatOptions? chatOptions,
CancellationToken cancellationToken)
{
ChatHistoryProvider? chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions);
ChatHistoryProvider? chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions, session);

if (chatHistoryProvider is not null)
{
Expand Down Expand Up @@ -974,14 +974,15 @@ private void WarnOnMissingPerServiceCallChatHistoryPersistingChatClient()
}
}

private ChatHistoryProvider? ResolveChatHistoryProvider(ChatOptions? chatOptions)
private ChatHistoryProvider? ResolveChatHistoryProvider(ChatOptions? chatOptions, ChatClientAgentSession? session = null)
{
ChatHistoryProvider? provider = chatOptions?.ConversationId is null ? this.ChatHistoryProvider : null;
string? conversationId = !string.IsNullOrWhiteSpace(chatOptions?.ConversationId) ? chatOptions.ConversationId : session?.ConversationId;
ChatHistoryProvider? provider = IsServiceManagedConversationId(conversationId) ? null : this.ChatHistoryProvider;

// If someone provided an override ChatHistoryProvider via AdditionalProperties, we should use that instead.
if (chatOptions?.AdditionalProperties?.TryGetValue(out ChatHistoryProvider? overrideProvider) is true)
{
if (this._agentOptions?.ThrowOnChatHistoryProviderConflict is true && string.IsNullOrWhiteSpace(chatOptions?.ConversationId) is false)
if (this._agentOptions?.ThrowOnChatHistoryProviderConflict is true && IsServiceManagedConversationId(conversationId))
{
throw new InvalidOperationException(
$"Only {nameof(ChatClientAgentSession.ConversationId)} or {nameof(this.ChatHistoryProvider)} may be used, but not both. The current {nameof(ChatClientAgentSession)} has a {nameof(ChatClientAgentSession.ConversationId)} indicating server-side chat history management, but an override {nameof(this.ChatHistoryProvider)} was provided via {nameof(AgentRunOptions.AdditionalProperties)}.");
Comment on lines +985 to 988
Expand All @@ -1006,6 +1007,12 @@ private void WarnOnMissingPerServiceCallChatHistoryPersistingChatClient()
return provider;
}

private static bool IsServiceManagedConversationId(string? conversationId)
{
return !string.IsNullOrWhiteSpace(conversationId)
&& conversationId != PerServiceCallChatHistoryPersistingChatClient.LocalHistoryConversationId;
}

/// <summary>
/// Loads chat history from the resolved <see cref="ChatHistoryProvider"/> and prepends it to the given messages.
/// </summary>
Expand All @@ -1019,7 +1026,7 @@ internal async Task<IEnumerable<ChatMessage>> LoadChatHistoryAsync(
ChatOptions? chatOptions,
CancellationToken cancellationToken)
{
var chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions);
var chatHistoryProvider = this.ResolveChatHistoryProvider(chatOptions, session);
if (chatHistoryProvider is null)
{
return messages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,11 @@ public async Task RunAsync_Throws_WhenThrowEnabledRegardlessOfClearSettingAsync(
}

/// <summary>
/// Verify that RunAsync does not throw when no ChatHistoryProvider is configured on options,
/// even if the service returns a conversation id (default InMemoryChatHistoryProvider is used but not from options).
/// Verify that RunAsync does not persist the default InMemoryChatHistoryProvider when
/// the service returns a conversation id.
/// </summary>
[Fact]
public async Task RunAsync_DoesNotThrow_WhenNoChatHistoryProviderInOptionsAndConversationIdReturnedAsync()
public async Task RunAsync_DoesNotPersistDefaultChatHistoryProvider_WhenConversationIdReturnedByChatClientAsync()
{
// Arrange
Mock<IChatClient> mockService = new();
Expand All @@ -407,8 +407,10 @@ public async Task RunAsync_DoesNotThrow_WhenNoChatHistoryProviderInOptionsAndCon
ChatClientAgentSession? session = await agent.CreateSessionAsync() as ChatClientAgentSession;
await agent.RunAsync([new(ChatRole.User, "test")], session);

// Assert - no exception, session gets the conversation id
// Assert
Assert.Equal("ConvId", session!.ConversationId);
var inMemoryProvider = Assert.IsType<InMemoryChatHistoryProvider>(agent.ChatHistoryProvider);
Assert.Empty(inMemoryProvider.GetMessages(session));
}

#endregion
Expand Down