Skip to content
Merged
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
35 changes: 24 additions & 11 deletions src/AI/Console/JsonConsoleLoggingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class JsonConsoleLoggingExtensions
/// <typeparam name="TOptions">The options type to configure for HTTP logging.</typeparam>
/// <param name="pipelineOptions">The options instance to configure.</param>
/// <remarks>
/// NOTE: this is the lowst-level logging after all chat pipeline processing has been done.
/// NOTE: this is the lowest-level logging after all chat pipeline processing has been done.
/// <para>
/// If the options already provide a transport, it will be wrapped with the console
/// logging transport to minimize the impact on existing configurations.
Expand All @@ -36,8 +36,7 @@ public static TOptions UseJsonConsoleLogging<TOptions>(this TOptions pipelineOpt
if (consoleOptions.InteractiveOnly && !ConsoleExtensions.IsConsoleInteractive)
return pipelineOptions;

pipelineOptions.Transport = new ConsoleLoggingPipelineTransport(pipelineOptions.Transport ?? HttpClientPipelineTransport.Shared, consoleOptions);

pipelineOptions.AddPolicy(new JsonConsoleLoggingPipelinePolicy(consoleOptions), PipelinePosition.BeforeTransport);
return pipelineOptions;
}

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

class ConsoleLoggingPipelineTransport(PipelineTransport inner, JsonConsoleOptions consoleOptions) : PipelineTransport
class JsonConsoleLoggingPipelinePolicy(JsonConsoleOptions consoleOptions) : PipelinePolicy
{
public static PipelineTransport Default { get; } = new ConsoleLoggingPipelineTransport();
public override void Process(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
message.BufferResponse = true;
ProcessNext(message, pipeline, currentIndex);

if (message.Request.Content is not null)
{
using var memory = new MemoryStream();
message.Request.Content.WriteTo(memory);
memory.Position = 0;
using var reader = new StreamReader(memory);
var content = reader.ReadToEnd();
AnsiConsole.Write(consoleOptions.CreatePanel(content));
}

public ConsoleLoggingPipelineTransport() : this(HttpClientPipelineTransport.Shared, JsonConsoleOptions.Default) { }
if (message.Response != null)
{
AnsiConsole.Write(consoleOptions.CreatePanel(message.Response.Content.ToString()));
}
}

protected override async ValueTask ProcessCoreAsync(PipelineMessage message)
public override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
message.BufferResponse = true;
await inner.ProcessAsync(message);
await ProcessNextAsync(message, pipeline, currentIndex);

if (message.Request.Content is not null)
{
Expand All @@ -88,9 +104,6 @@ protected override async ValueTask ProcessCoreAsync(PipelineMessage message)
AnsiConsole.Write(consoleOptions.CreatePanel(message.Response.Content.ToString()));
}
}

protected override PipelineMessage CreateMessageCore() => inner.CreateMessage();
protected override void ProcessCore(PipelineMessage message) => inner.Process(message);
}

class JsonConsoleLoggingChatClient(IChatClient inner, JsonConsoleOptions consoleOptions) : DelegatingChatClient(inner)
Expand Down
Loading