Public Access
Handle settings logs agent failures
PR and Push Build/Test / build-and-test (push) Successful in 9m8s
PR and Push Build/Test / build-and-test (push) Successful in 9m8s
This commit is contained in:
@@ -126,12 +126,14 @@ public sealed class LiteLlmResponsesChatClientTests
|
||||
}
|
||||
""")
|
||||
});
|
||||
using var client = CreateClient(handler, reconnectionAttempts: 1);
|
||||
var retryCount = 0;
|
||||
using var client = CreateClient(handler, reconnectionAttempts: 1, retrying: () => retryCount++);
|
||||
|
||||
var response = await client.GetResponseAsync([new ChatMessage(ChatRole.User, "write summary")]);
|
||||
|
||||
Assert.Equal("Done.", response.Text);
|
||||
Assert.Equal(2, handler.RequestCount);
|
||||
Assert.Equal(1, retryCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -303,7 +305,8 @@ public sealed class LiteLlmResponsesChatClientTests
|
||||
private static LiteLlmResponsesChatClient CreateClient(
|
||||
HttpMessageHandler handler,
|
||||
int reconnectionAttempts,
|
||||
LiteLlmResponsesCompactionOptions? compactionOptions = null)
|
||||
LiteLlmResponsesCompactionOptions? compactionOptions = null,
|
||||
Action? retrying = null)
|
||||
{
|
||||
return new LiteLlmResponsesChatClient(
|
||||
new HttpClient(handler)
|
||||
@@ -316,7 +319,8 @@ public sealed class LiteLlmResponsesChatClientTests
|
||||
reasoningEffort: "none",
|
||||
reconnectionAttempts,
|
||||
TimeSpan.Zero,
|
||||
compactionOptions);
|
||||
compactionOptions,
|
||||
retrying: retrying);
|
||||
}
|
||||
|
||||
private sealed class SequencedHttpMessageHandler : HttpMessageHandler
|
||||
|
||||
@@ -853,6 +853,52 @@ public sealed class WorkflowRulesEditorTests
|
||||
Assert.Equal("Updated rules.", viewModel.Messages[1].Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ViewModelShowsAgentErrorWhenRequestTimesOut()
|
||||
{
|
||||
var viewModel = new WorkflowRulesEditorChatViewModel(
|
||||
new ThrowingRulesEditorPipeline(new TaskCanceledException("The request timed out.")))
|
||||
{
|
||||
Draft = "check logs"
|
||||
};
|
||||
|
||||
await viewModel.SendAsync();
|
||||
|
||||
Assert.False(viewModel.IsThinking);
|
||||
Assert.Equal("", viewModel.Draft);
|
||||
Assert.Equal(
|
||||
[
|
||||
new WorkflowRulesEditorChatMessage(WorkflowRulesEditorChatRole.User, "check logs"),
|
||||
new WorkflowRulesEditorChatMessage(
|
||||
WorkflowRulesEditorChatRole.Agent,
|
||||
"Settings and logs failed: The request timed out.")
|
||||
],
|
||||
viewModel.Messages.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ViewModelShowsReconnectStatusReportedByPipeline()
|
||||
{
|
||||
var pipeline = new StatusReportingRulesEditorPipeline("Updated rules.");
|
||||
var viewModel = new WorkflowRulesEditorChatViewModel(pipeline)
|
||||
{
|
||||
Draft = "check logs"
|
||||
};
|
||||
|
||||
var sendTask = viewModel.SendAsync();
|
||||
await pipeline.Reported.Task.WaitAsync(TimeSpan.FromSeconds(2));
|
||||
|
||||
Assert.True(viewModel.IsThinking);
|
||||
Assert.Equal("Reconnecting...", viewModel.ActivityMessage);
|
||||
|
||||
pipeline.Release.SetResult();
|
||||
await sendTask.WaitAsync(TimeSpan.FromSeconds(2));
|
||||
|
||||
Assert.False(viewModel.IsThinking);
|
||||
Assert.Equal("Thinking...", viewModel.ActivityMessage);
|
||||
Assert.Equal("Updated rules.", viewModel.Messages[1].Content);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 500, 0, true)]
|
||||
[InlineData(0, 500, 400, true)]
|
||||
@@ -1149,7 +1195,8 @@ public sealed class WorkflowRulesEditorTests
|
||||
public async Task<WorkflowRulesEditorChatResult> SendAsync(
|
||||
IReadOnlyList<WorkflowRulesEditorChatMessage> conversation,
|
||||
string userMessage,
|
||||
CancellationToken cancellationToken)
|
||||
CancellationToken cancellationToken,
|
||||
Action<string>? statusChanged = null)
|
||||
{
|
||||
Started.SetResult();
|
||||
await Release.Task.WaitAsync(cancellationToken);
|
||||
@@ -1162,6 +1209,56 @@ public sealed class WorkflowRulesEditorTests
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ThrowingRulesEditorPipeline : IWorkflowRulesEditorChatPipeline
|
||||
{
|
||||
private readonly Exception exception;
|
||||
|
||||
public ThrowingRulesEditorPipeline(Exception exception)
|
||||
{
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public Task<WorkflowRulesEditorChatResult> SendAsync(
|
||||
IReadOnlyList<WorkflowRulesEditorChatMessage> conversation,
|
||||
string userMessage,
|
||||
CancellationToken cancellationToken,
|
||||
Action<string>? statusChanged = null)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class StatusReportingRulesEditorPipeline : IWorkflowRulesEditorChatPipeline
|
||||
{
|
||||
private readonly string response;
|
||||
|
||||
public StatusReportingRulesEditorPipeline(string response)
|
||||
{
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public TaskCompletionSource Reported { get; } = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
public TaskCompletionSource Release { get; } = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
public async Task<WorkflowRulesEditorChatResult> SendAsync(
|
||||
IReadOnlyList<WorkflowRulesEditorChatMessage> conversation,
|
||||
string userMessage,
|
||||
CancellationToken cancellationToken,
|
||||
Action<string>? statusChanged = null)
|
||||
{
|
||||
statusChanged?.Invoke("Reconnecting...");
|
||||
Reported.SetResult();
|
||||
await Release.Task.WaitAsync(cancellationToken);
|
||||
return new WorkflowRulesEditorChatResult(
|
||||
response,
|
||||
conversation
|
||||
.Append(new WorkflowRulesEditorChatMessage(WorkflowRulesEditorChatRole.User, userMessage))
|
||||
.Append(new WorkflowRulesEditorChatMessage(WorkflowRulesEditorChatRole.Agent, response))
|
||||
.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class CapturingLogger : ILogger
|
||||
{
|
||||
public List<string> Messages { get; } = [];
|
||||
|
||||
Reference in New Issue
Block a user