Skip to content

Commit ff891d4

Browse files
committed
Merge branch 'main' into feature_chatagent_streaming
2 parents bb565eb + 76e9db4 commit ff891d4

15 files changed

+40
-35
lines changed

dotnet/samples/GettingStartedWithAgents/Step7_Logging.cs

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public async Task UseLoggerFactoryWithAgentGroupChatAsync()
4646
Instructions = ReviewerInstructions,
4747
Name = ReviewerName,
4848
Kernel = this.CreateKernelWithChatCompletion(),
49+
LoggerFactory = this.LoggerFactory,
4950
};
5051

5152
ChatCompletionAgent agentWriter =
@@ -54,6 +55,7 @@ public async Task UseLoggerFactoryWithAgentGroupChatAsync()
5455
Instructions = CopyWriterInstructions,
5556
Name = CopyWriterName,
5657
Kernel = this.CreateKernelWithChatCompletion(),
58+
LoggerFactory = this.LoggerFactory,
5759
};
5860

5961
// Create a chat for agent interaction.

dotnet/src/Agents/Abstractions/Agent.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading;
55
using System.Threading.Tasks;
66
using Microsoft.Extensions.Logging;
7+
using Microsoft.Extensions.Logging.Abstractions;
78

89
namespace Microsoft.SemanticKernel.Agents;
910

@@ -36,6 +37,16 @@ public abstract class Agent
3637
/// </summary>
3738
public string? Name { get; init; }
3839

40+
/// <summary>
41+
/// A <see cref="ILoggerFactory"/> for this <see cref="Agent"/>.
42+
/// </summary>
43+
public ILoggerFactory LoggerFactory { get; init; } = NullLoggerFactory.Instance;
44+
45+
/// <summary>
46+
/// The <see cref="ILogger"/> associated with this <see cref="Agent"/>.
47+
/// </summary>
48+
protected ILogger Logger => this._logger ??= this.LoggerFactory.CreateLogger(this.GetType());
49+
3950
/// <summary>
4051
/// Set of keys to establish channel affinity. Minimum expected key-set:
4152
/// <example>
@@ -53,12 +64,13 @@ public abstract class Agent
5364
/// <summary>
5465
/// Produce the an <see cref="AgentChannel"/> appropriate for the agent type.
5566
/// </summary>
56-
/// <param name="logger">An agent specific logger.</param>
5767
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
5868
/// <returns>An <see cref="AgentChannel"/> appropriate for the agent type.</returns>
5969
/// <remarks>
6070
/// Every agent conversation, or <see cref="AgentChat"/>, will establish one or more <see cref="AgentChannel"/>
6171
/// objects according to the specific <see cref="Agent"/> type.
6272
/// </remarks>
63-
protected internal abstract Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken);
73+
protected internal abstract Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken);
74+
75+
private ILogger? _logger;
6476
}

dotnet/src/Agents/Abstractions/AgentChat.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,7 @@ async Task<AgentChannel> GetOrCreateChannelAsync()
256256
{
257257
this.Logger.LogDebug("[{MethodName}] Creating channel for {AgentType}: {AgentId}", nameof(InvokeAgentAsync), agent.GetType(), agent.Id);
258258

259-
// Creating an agent-typed logger for CreateChannelAsync
260-
channel = await agent.CreateChannelAsync(this.LoggerFactory.CreateLogger(agent.GetType()), cancellationToken).ConfigureAwait(false);
261-
// Creating an channel-typed logger for the channel
262-
channel.Logger = this.LoggerFactory.CreateLogger(channel.GetType());
259+
channel = await agent.CreateChannelAsync(cancellationToken).ConfigureAwait(false);
263260

264261
this._agentChannels.Add(channelKey, channel);
265262

dotnet/src/Agents/Abstractions/AggregatorAgent.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ protected internal override IEnumerable<string> GetChannelKeys()
4444
}
4545

4646
/// <inheritdoc/>
47-
protected internal override Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken)
47+
protected internal override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
4848
{
49-
logger.LogDebug("[{MethodName}] Creating channel {ChannelType}", nameof(CreateChannelAsync), nameof(AggregatorChannel));
49+
this.Logger.LogDebug("[{MethodName}] Creating channel {ChannelType}", nameof(CreateChannelAsync), nameof(AggregatorChannel));
5050

5151
AgentChat chat = chatProvider.Invoke();
5252
AggregatorChannel channel = new(chat);
5353

54-
logger.LogInformation("[{MethodName}] Created channel {ChannelType} ({ChannelMode}) with: {AgentChatType}", nameof(CreateChannelAsync), nameof(AggregatorChannel), this.Mode, chat.GetType());
54+
this.Logger.LogInformation("[{MethodName}] Created channel {ChannelType} ({ChannelMode}) with: {AgentChatType}", nameof(CreateChannelAsync), nameof(AggregatorChannel), this.Mode, chat.GetType());
5555

5656
return Task.FromResult<AgentChannel>(channel);
5757
}

dotnet/src/Agents/Abstractions/ChatHistoryChannel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ protected internal sealed override async IAsyncEnumerable<ChatMessageContent> In
2525
throw new KernelException($"Invalid channel binding for agent: {agent.Id} ({agent.GetType().FullName})");
2626
}
2727

28-
await foreach (var message in historyHandler.InvokeAsync(this._history, this.Logger, cancellationToken).ConfigureAwait(false))
28+
await foreach (var message in historyHandler.InvokeAsync(this._history, cancellationToken).ConfigureAwait(false))
2929
{
3030
this._history.Add(message);
3131

dotnet/src/Agents/Abstractions/ChatHistoryKernelAgent.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@ protected internal sealed override IEnumerable<string> GetChannelKeys()
1818
}
1919

2020
/// <inheritdoc/>
21-
protected internal sealed override Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken)
21+
protected internal sealed override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
2222
{
23-
return Task.FromResult<AgentChannel>(new ChatHistoryChannel());
23+
ChatHistoryChannel channel =
24+
new()
25+
{
26+
Logger = this.LoggerFactory.CreateLogger<ChatHistoryChannel>()
27+
};
28+
29+
return Task.FromResult<AgentChannel>(channel);
2430
}
2531

2632
/// <inheritdoc/>
2733
public abstract IAsyncEnumerable<ChatMessageContent> InvokeAsync(
2834
IReadOnlyList<ChatMessageContent> history,
29-
ILogger logger,
3035
CancellationToken cancellationToken = default);
3136

3237
/// <inheritdoc/>

dotnet/src/Agents/Abstractions/IChatHistoryHandler.cs

-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
using System.Collections.Generic;
33
using System.Threading;
4-
using Microsoft.Extensions.Logging;
54

65
namespace Microsoft.SemanticKernel.Agents;
76

@@ -14,12 +13,10 @@ public interface IChatHistoryHandler
1413
/// Entry point for calling into an agent from a <see cref="ChatHistoryChannel"/>.
1514
/// </summary>
1615
/// <param name="history">The chat history at the point the channel is created.</param>
17-
/// <param name="logger">The logger associated with the <see cref="ChatHistoryChannel"/></param>
1816
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
1917
/// <returns>Asynchronous enumeration of messages.</returns>
2018
IAsyncEnumerable<ChatMessageContent> InvokeAsync(
2119
IReadOnlyList<ChatMessageContent> history,
22-
ILogger logger,
2320
CancellationToken cancellationToken = default);
2421

2522
/// <summary>

dotnet/src/Agents/Core/ChatCompletionAgent.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public sealed class ChatCompletionAgent : ChatHistoryKernelAgent
2525
/// <inheritdoc/>
2626
public override async IAsyncEnumerable<ChatMessageContent> InvokeAsync(
2727
IReadOnlyList<ChatMessageContent> history,
28-
ILogger logger,
2928
[EnumeratorCancellation] CancellationToken cancellationToken = default)
3029
{
3130
IChatCompletionService chatCompletionService = this.Kernel.GetRequiredService<IChatCompletionService>();
@@ -34,7 +33,7 @@ public override async IAsyncEnumerable<ChatMessageContent> InvokeAsync(
3433

3534
int messageCount = chat.Count;
3635

37-
logger.LogDebug("[{MethodName}] Invoking {ServiceType}.", nameof(InvokeAsync), chatCompletionService.GetType());
36+
this.Logger.LogDebug("[{MethodName}] Invoking {ServiceType}.", nameof(InvokeAsync), chatCompletionService.GetType());
3837

3938
IReadOnlyList<ChatMessageContent> messages =
4039
await chatCompletionService.GetChatMessageContentsAsync(
@@ -43,9 +42,9 @@ await chatCompletionService.GetChatMessageContentsAsync(
4342
this.Kernel,
4443
cancellationToken).ConfigureAwait(false);
4544

46-
if (logger.IsEnabled(LogLevel.Information)) // Avoid boxing if not enabled
45+
if (this.Logger.IsEnabled(LogLevel.Information)) // Avoid boxing if not enabled
4746
{
48-
logger.LogInformation("[{MethodName}] Invoked {ServiceType} with message count: {MessageCount}.", nameof(InvokeAsync), chatCompletionService.GetType(), messages.Count);
47+
this.Logger.LogInformation("[{MethodName}] Invoked {ServiceType} with message count: {MessageCount}.", nameof(InvokeAsync), chatCompletionService.GetType(), messages.Count);
4948
}
5049

5150
// Capture mutated messages related function calling / tools

dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ protected override IEnumerable<string> GetChannelKeys()
204204
}
205205

206206
/// <inheritdoc/>
207-
protected override async Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken)
207+
protected override async Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
208208
{
209-
logger.LogDebug("[{MethodName}] Creating assistant thread", nameof(CreateChannelAsync));
209+
this.Logger.LogDebug("[{MethodName}] Creating assistant thread", nameof(CreateChannelAsync));
210210

211211
AssistantThread thread = await this._client.CreateThreadAsync(cancellationToken).ConfigureAwait(false);
212212

213-
logger.LogInformation("[{MethodName}] Created assistant thread: {ThreadId}", nameof(CreateChannelAsync), thread.Id);
213+
this.Logger.LogInformation("[{MethodName}] Created assistant thread: {ThreadId}", nameof(CreateChannelAsync), thread.Id);
214214

215215
return new OpenAIAssistantChannel(this._client, thread.Id, this._config.Polling);
216216
}

dotnet/src/Agents/UnitTests/AgentChannelTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Runtime.CompilerServices;
66
using System.Threading;
77
using System.Threading.Tasks;
8-
using Microsoft.Extensions.Logging;
98
using Microsoft.SemanticKernel;
109
using Microsoft.SemanticKernel.Agents;
1110
using Xunit;
@@ -68,7 +67,7 @@ private sealed class NextAgent : TestAgent;
6867

6968
private class TestAgent : KernelAgent
7069
{
71-
protected internal override Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken)
70+
protected internal override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
7271
{
7372
throw new NotImplementedException();
7473
}

dotnet/src/Agents/UnitTests/AgentChatTests.cs

-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Runtime.CompilerServices;
55
using System.Threading;
66
using System.Threading.Tasks;
7-
using Microsoft.Extensions.Logging;
87
using Microsoft.SemanticKernel;
98
using Microsoft.SemanticKernel.Agents;
109
using Microsoft.SemanticKernel.ChatCompletion;
@@ -137,7 +136,6 @@ private sealed class TestAgent : ChatHistoryKernelAgent
137136

138137
public override async IAsyncEnumerable<ChatMessageContent> InvokeAsync(
139138
IReadOnlyList<ChatMessageContent> history,
140-
ILogger logger,
141139
[EnumeratorCancellation] CancellationToken cancellationToken = default)
142140
{
143141
await Task.Delay(0, cancellationToken);

dotnet/src/Agents/UnitTests/AggregatorAgentTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Linq;
44
using System.Threading;
55
using System.Threading.Tasks;
6-
using Microsoft.Extensions.Logging;
76
using Microsoft.SemanticKernel;
87
using Microsoft.SemanticKernel.Agents;
98
using Microsoft.SemanticKernel.ChatCompletion;
@@ -88,7 +87,7 @@ private static Mock<ChatHistoryKernelAgent> CreateMockAgent()
8887
Mock<ChatHistoryKernelAgent> agent = new();
8988

9089
ChatMessageContent[] messages = [new ChatMessageContent(AuthorRole.Assistant, "test agent")];
91-
agent.Setup(a => a.InvokeAsync(It.IsAny<IReadOnlyList<ChatMessageContent>>(), It.IsAny<ILogger>(), It.IsAny<CancellationToken>())).Returns(() => messages.ToAsyncEnumerable());
90+
agent.Setup(a => a.InvokeAsync(It.IsAny<IReadOnlyList<ChatMessageContent>>(), It.IsAny<CancellationToken>())).Returns(() => messages.ToAsyncEnumerable());
9291

9392
return agent;
9493
}

dotnet/src/Agents/UnitTests/ChatHistoryChannelTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Linq;
55
using System.Threading;
66
using System.Threading.Tasks;
7-
using Microsoft.Extensions.Logging;
87
using Microsoft.SemanticKernel;
98
using Microsoft.SemanticKernel.Agents;
109
using Xunit;
@@ -30,7 +29,7 @@ public async Task VerifyAgentWithoutIChatHistoryHandlerAsync()
3029

3130
private sealed class TestAgent : KernelAgent
3231
{
33-
protected internal override Task<AgentChannel> CreateChannelAsync(ILogger logger, CancellationToken cancellationToken)
32+
protected internal override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
3433
{
3534
throw new NotImplementedException();
3635
}

dotnet/src/Agents/UnitTests/Core/AgentGroupChatTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Linq;
55
using System.Threading;
66
using System.Threading.Tasks;
7-
using Microsoft.Extensions.Logging;
87
using Microsoft.SemanticKernel;
98
using Microsoft.SemanticKernel.Agents;
109
using Microsoft.SemanticKernel.Agents.Chat;
@@ -199,7 +198,7 @@ private static Mock<ChatHistoryKernelAgent> CreateMockAgent()
199198
Mock<ChatHistoryKernelAgent> agent = new();
200199

201200
ChatMessageContent[] messages = [new ChatMessageContent(AuthorRole.Assistant, "test")];
202-
agent.Setup(a => a.InvokeAsync(It.IsAny<IReadOnlyList<ChatMessageContent>>(), It.IsAny<ILogger>(), It.IsAny<CancellationToken>())).Returns(() => messages.ToAsyncEnumerable());
201+
agent.Setup(a => a.InvokeAsync(It.IsAny<IReadOnlyList<ChatMessageContent>>(), It.IsAny<CancellationToken>())).Returns(() => messages.ToAsyncEnumerable());
203202

204203
return agent;
205204
}

dotnet/src/Agents/UnitTests/Core/ChatCompletionAgentTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Threading;
44
using System.Threading.Tasks;
55
using Microsoft.Extensions.DependencyInjection;
6-
using Microsoft.Extensions.Logging.Abstractions;
76
using Microsoft.SemanticKernel;
87
using Microsoft.SemanticKernel.Agents;
98
using Microsoft.SemanticKernel.ChatCompletion;
@@ -60,7 +59,7 @@ public async Task VerifyChatCompletionAgentInvocationAsync()
6059
ExecutionSettings = new(),
6160
};
6261

63-
var result = await agent.InvokeAsync([], NullLogger.Instance).ToArrayAsync();
62+
var result = await agent.InvokeAsync([]).ToArrayAsync();
6463

6564
Assert.Single(result);
6665

0 commit comments

Comments
 (0)