Skip to content

Commit 81a2d78

Browse files
Update only streaming
1 parent b504360 commit 81a2d78

File tree

5 files changed

+101
-390
lines changed

5 files changed

+101
-390
lines changed

app/SharedWebComponents/Pages/Chat.razor

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@
8888
OnClick="@OnClearChat" Disabled=@(_isReceivingResponse || _questionAndAnswerMap is { Count: 0 }) />
8989
</MudTooltip>
9090
</MudItem>
91-
<MudItem xs="12" Class="pa-2">
92-
<MudCheckBox @bind-Checked="_useStreaming" Label="Use streaming mode" Color="Color.Secondary"
93-
Disabled="@_isReceivingResponse" />
94-
</MudItem>
9591
</MudGrid>
9692
</MudItem>
9793
</MudGrid>

app/SharedWebComponents/Pages/Chat.razor.cs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public sealed partial class Chat
99
private UserQuestion _currentQuestion;
1010
private string _lastReferenceQuestion = "";
1111
private bool _isReceivingResponse = false;
12-
private bool _useStreaming = false;
1312

1413
private readonly Dictionary<UserQuestion, ChatAppResponseOrError?> _questionAndAnswerMap = [];
1514

@@ -45,38 +44,35 @@ private async Task OnAskClickedAsync()
4544
{
4645
var history = _questionAndAnswerMap
4746
.Where(x => x.Value?.Choices is { Length: > 0 })
48-
.SelectMany(x => new ChatMessage[] { new ChatMessage("user", x.Key.Question), new ChatMessage("assistant", x.Value!.Choices[0].Message.Content) })
47+
.SelectMany(x => new ChatMessage[] {
48+
new ChatMessage("user", x.Key.Question),
49+
new ChatMessage("assistant", x.Value!.Choices[0].Message.Content)
50+
})
4951
.ToList();
5052

5153
history.Add(new ChatMessage("user", _userQuestion));
5254

5355
var request = new ChatRequest([.. history], Settings.Overrides);
5456

55-
if (_useStreaming)
57+
try
5658
{
57-
try
58-
{
59-
await foreach (var response in await ApiClient.PostStreamingRequestAsync(request, "api/chat/stream"))
60-
{
61-
_questionAndAnswerMap[_currentQuestion] = new ChatAppResponseOrError(
62-
response.Choices,
63-
null);
64-
65-
StateHasChanged();
66-
await Task.Delay(10);
67-
}
68-
}
69-
catch (Exception ex)
59+
var responseStream = await ApiClient.PostStreamingRequestAsync(request, "api/chat/stream");
60+
61+
await foreach (var response in responseStream)
7062
{
7163
_questionAndAnswerMap[_currentQuestion] = new ChatAppResponseOrError(
72-
Array.Empty<ResponseChoice>(),
73-
ex.Message);
64+
response.Choices,
65+
null);
66+
67+
StateHasChanged();
68+
await Task.Delay(1);
7469
}
7570
}
76-
else
71+
catch (Exception ex)
7772
{
78-
var result = await ApiClient.ChatConversationAsync(request);
79-
_questionAndAnswerMap[_currentQuestion] = result.Response;
73+
_questionAndAnswerMap[_currentQuestion] = new ChatAppResponseOrError(
74+
Array.Empty<ResponseChoice>(),
75+
ex.Message);
8076
}
8177

8278
if (_questionAndAnswerMap[_currentQuestion]?.Error is null)

app/SharedWebComponents/Services/ApiClient.cs

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -90,65 +90,29 @@ public async IAsyncEnumerable<DocumentResponse> GetDocumentsAsync(
9090
}
9191
}
9292

93-
public Task<AnswerResult<ChatRequest>> ChatConversationAsync(ChatRequest request) => PostRequestAsync(request, "api/chat");
94-
95-
private async Task<AnswerResult<TRequest>> PostRequestAsync<TRequest>(
96-
TRequest request, string apiRoute) where TRequest : ApproachRequest
97-
{
98-
var result = new AnswerResult<TRequest>(
99-
IsSuccessful: false,
100-
Response: null,
101-
Approach: request.Approach,
102-
Request: request);
103-
104-
var json = JsonSerializer.Serialize(
105-
request,
106-
SerializerOptions.Default);
107-
108-
using var body = new StringContent(
109-
json, Encoding.UTF8, "application/json");
110-
111-
var response = await httpClient.PostAsync(apiRoute, body);
112-
113-
if (response.IsSuccessStatusCode)
114-
{
115-
var answer = await response.Content.ReadFromJsonAsync<ChatAppResponseOrError>();
116-
return result with
117-
{
118-
IsSuccessful = answer is not null,
119-
Response = answer,
120-
};
121-
}
122-
else
123-
{
124-
var errorTitle = $"HTTP {(int)response.StatusCode} : {response.ReasonPhrase ?? "☹️ Unknown error..."}";
125-
var answer = new ChatAppResponseOrError(
126-
Array.Empty<ResponseChoice>(),
127-
errorTitle);
128-
129-
return result with
130-
{
131-
IsSuccessful = false,
132-
Response = answer
133-
};
134-
}
135-
}
136-
13793
public async Task<IAsyncEnumerable<ChatAppResponse>> PostStreamingRequestAsync<TRequest>(
13894
TRequest request, string apiRoute) where TRequest : ApproachRequest
13995
{
14096
var json = JsonSerializer.Serialize(
14197
request,
14298
SerializerOptions.Default);
14399

144-
using var body = new StringContent(
100+
using var content = new StringContent(
145101
json, Encoding.UTF8, "application/json");
146102

147-
var response = await httpClient.PostAsync(apiRoute, body);
103+
// Use both HttpCompletionOption and CancellationToken
104+
var response = await httpClient.PostAsync(
105+
apiRoute,
106+
content,
107+
CancellationToken.None);
148108

149109
if (response.IsSuccessStatusCode)
150110
{
151-
var nullableResponses = response.Content.ReadFromJsonAsAsyncEnumerable<ChatAppResponse>();
111+
var stream = await response.Content.ReadAsStreamAsync();
112+
var nullableResponses = JsonSerializer.DeserializeAsyncEnumerable<ChatAppResponse>(
113+
stream,
114+
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
115+
152116
return nullableResponses.Where(r => r != null)!;
153117
}
154118

app/backend/Extensions/WebApplicationExtensions.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal static WebApplication MapApi(this WebApplication app)
1212
api.MapPost("openai/chat", OnPostChatPromptAsync);
1313

1414
// Long-form chat w/ contextual history endpoint
15-
api.MapPost("chat", OnPostChatAsync);
15+
api.MapPost("chat/stream", OnPostChatStreamingAsync);
1616

1717
// Upload a document
1818
api.MapPost("documents", OnPostDocumentAsync);
@@ -25,9 +25,6 @@ internal static WebApplication MapApi(this WebApplication app)
2525

2626
api.MapGet("enableLogout", OnGetEnableLogout);
2727

28-
// Add streaming chat endpoint
29-
api.MapPost("chat/stream", OnPostChatStreamingAsync);
30-
3128
return app;
3229
}
3330

@@ -73,22 +70,6 @@ You will always reply with a Markdown formatted response.
7370
}
7471
}
7572

76-
private static async Task<IResult> OnPostChatAsync(
77-
ChatRequest request,
78-
ReadRetrieveReadChatService chatService,
79-
CancellationToken cancellationToken)
80-
{
81-
if (request is { History.Length: > 0 })
82-
{
83-
var response = await chatService.ReplyAsync(
84-
request.History, request.Overrides, cancellationToken);
85-
86-
return TypedResults.Ok(response);
87-
}
88-
89-
return Results.BadRequest();
90-
}
91-
9273
private static async IAsyncEnumerable<ChatAppResponse> OnPostChatStreamingAsync(
9374
ChatRequest request,
9475
ReadRetrieveReadChatService chatService,

0 commit comments

Comments
 (0)