Skip to content

Commit 67c547f

Browse files
committed
Improve JSON console logging at the client pipeline level
Rather than replacing the transport, use a better hook as a pipeline policy instead.
1 parent 795986d commit 67c547f

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

src/AI/Console/JsonConsoleLoggingExtensions.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static class JsonConsoleLoggingExtensions
1919
/// <typeparam name="TOptions">The options type to configure for HTTP logging.</typeparam>
2020
/// <param name="pipelineOptions">The options instance to configure.</param>
2121
/// <remarks>
22-
/// NOTE: this is the lowst-level logging after all chat pipeline processing has been done.
22+
/// NOTE: this is the lowest-level logging after all chat pipeline processing has been done.
2323
/// <para>
2424
/// If the options already provide a transport, it will be wrapped with the console
2525
/// logging transport to minimize the impact on existing configurations.
@@ -36,8 +36,7 @@ public static TOptions UseJsonConsoleLogging<TOptions>(this TOptions pipelineOpt
3636
if (consoleOptions.InteractiveOnly && !ConsoleExtensions.IsConsoleInteractive)
3737
return pipelineOptions;
3838

39-
pipelineOptions.Transport = new ConsoleLoggingPipelineTransport(pipelineOptions.Transport ?? HttpClientPipelineTransport.Shared, consoleOptions);
40-
39+
pipelineOptions.AddPolicy(new JsonConsoleLoggingPipelinePolicy(consoleOptions), PipelinePosition.BeforeTransport);
4140
return pipelineOptions;
4241
}
4342

@@ -62,16 +61,33 @@ public static ChatClientBuilder UseJsonConsoleLogging(this ChatClientBuilder bui
6261
return builder.Use(inner => new JsonConsoleLoggingChatClient(inner, consoleOptions));
6362
}
6463

65-
class ConsoleLoggingPipelineTransport(PipelineTransport inner, JsonConsoleOptions consoleOptions) : PipelineTransport
64+
class JsonConsoleLoggingPipelinePolicy(JsonConsoleOptions consoleOptions) : PipelinePolicy
6665
{
67-
public static PipelineTransport Default { get; } = new ConsoleLoggingPipelineTransport();
66+
public override void Process(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
67+
{
68+
message.BufferResponse = true;
69+
ProcessNext(message, pipeline, currentIndex);
70+
71+
if (message.Request.Content is not null)
72+
{
73+
using var memory = new MemoryStream();
74+
message.Request.Content.WriteTo(memory);
75+
memory.Position = 0;
76+
using var reader = new StreamReader(memory);
77+
var content = reader.ReadToEnd();
78+
AnsiConsole.Write(consoleOptions.CreatePanel(content));
79+
}
6880

69-
public ConsoleLoggingPipelineTransport() : this(HttpClientPipelineTransport.Shared, JsonConsoleOptions.Default) { }
81+
if (message.Response != null)
82+
{
83+
AnsiConsole.Write(consoleOptions.CreatePanel(message.Response.Content.ToString()));
84+
}
85+
}
7086

71-
protected override async ValueTask ProcessCoreAsync(PipelineMessage message)
87+
public override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
7288
{
7389
message.BufferResponse = true;
74-
await inner.ProcessAsync(message);
90+
await ProcessNextAsync(message, pipeline, currentIndex);
7591

7692
if (message.Request.Content is not null)
7793
{
@@ -88,9 +104,6 @@ protected override async ValueTask ProcessCoreAsync(PipelineMessage message)
88104
AnsiConsole.Write(consoleOptions.CreatePanel(message.Response.Content.ToString()));
89105
}
90106
}
91-
92-
protected override PipelineMessage CreateMessageCore() => inner.CreateMessage();
93-
protected override void ProcessCore(PipelineMessage message) => inner.Process(message);
94107
}
95108

96109
class JsonConsoleLoggingChatClient(IChatClient inner, JsonConsoleOptions consoleOptions) : DelegatingChatClient(inner)

0 commit comments

Comments
 (0)