Skip to content

Commit 85529e4

Browse files
authored
[Playground] Add chat window component (#316)
1 parent 4edf7a8 commit 85529e4

File tree

9 files changed

+398
-69
lines changed

9 files changed

+398
-69
lines changed

src/AzureOpenAIProxy.ApiApp/Models/AdminResourceDetails.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ public class AdminResourceDetails
6060
}
6161

6262
/// <summary>
63-
/// /// This defines the type of the resource.
63+
/// This defines the type of the resource.
64+
/// </summary>
6465
[JsonConverter(typeof(EnumMemberConverter<ResourceType>))]
6566
public enum ResourceType
6667
{

src/AzureOpenAIProxy.PlaygroundApp/Components/Pages/Home.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
Welcome to your new app.
99

10-
<ChatWindowComponent @rendermode="InteractiveServer"/>
10+
<OldChatWindowComponent @rendermode="InteractiveServer"/>

src/AzureOpenAIProxy.PlaygroundApp/Components/Pages/Playground.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<ConfigTabComponent @rendermode="InteractiveServer"/>
1212
</FluentGridItem>
1313

14-
<FluentGridItem Class="chat-grid" xs="12" sm="12" md="8" lg="8" xl="8" xxl="8">
15-
Chat Window
14+
<FluentGridItem Class="chat-grid" xs="12" sm="12" md="8" lg="8" xl="8" xxl="8" Style="height: 900px;">
15+
<ChatWindowComponent Id="chat-window" @rendermode="InteractiveServer" />
1616
</FluentGridItem>
1717
</FluentGrid>
1818
</FluentLayout>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@using AzureOpenAIProxy.PlaygroundApp.Models
2+
3+
<FluentStack Id="@Id" Style="width: 100%;" Orientation="Orientation.Vertical" VerticalAlignment="VerticalAlignment.Top">
4+
@if (this.Messages != null && this.Messages.Any())
5+
{
6+
foreach (var message in this.Messages)
7+
{
8+
<FluentStack id="@($"message-{this.Messages.IndexOf(message).ToString("00")}")" Style="width: 100%;" Orientation="Orientation.Horizontal" HorizontalAlignment="@(message.Role == MessageRole.Assistant ? HorizontalAlignment.Start : HorizontalAlignment.End)">
9+
<FluentCard Style="width: 70%;" MinimalStyle="true">
10+
<p>@message.Message</p>
11+
</FluentCard>
12+
</FluentStack>
13+
}
14+
}
15+
</FluentStack>
16+
17+
@code {
18+
[Parameter]
19+
public string? Id { get; set; }
20+
21+
[Parameter]
22+
public List<ChatMessage>? Messages { get; set; }
23+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<FluentStack Id="@Id" Style="width: 100%;" Orientation="Orientation.Vertical" VerticalAlignment="VerticalAlignment.Bottom">
2+
<FluentTextArea Id="prompt" Style="width: 100%;" Rows="6" Placeholder="Type user query here. (Shift + Enter for new line)" @bind-Value="prompt" @onchange="UpdatePrompt"></FluentTextArea>
3+
<FluentStack Style="width: 100%;" Orientation="Orientation.Horizontal" HorizontalAlignment="HorizontalAlignment.Start">
4+
<FluentStack Style="width: 50%;" Orientation="Orientation.Horizontal" HorizontalAlignment="HorizontalAlignment.Start">
5+
<FluentButton Id="button-clear" IconStart="@(new Icons.Regular.Size20.Broom())" OnClick="ClearChat">Clear</FluentButton>
6+
</FluentStack>
7+
<FluentStack Style="width: 50%;" Orientation="Orientation.Horizontal" HorizontalAlignment="HorizontalAlignment.End">
8+
<FluentButton Id="button-send" IconStart="@(new Icons.Regular.Size20.Send())" OnClick="CompleteChat">Send</FluentButton>
9+
</FluentStack>
10+
</FluentStack>
11+
</FluentStack>
12+
13+
@code {
14+
private string? prompt;
15+
16+
[Parameter]
17+
public string? Id { get; set; }
18+
19+
[Parameter]
20+
public EventCallback<string?> OnPromptSent { get; set; }
21+
22+
[Parameter]
23+
public EventCallback OnChatCleared { get; set; }
24+
25+
private async Task UpdatePrompt(ChangeEventArgs e)
26+
{
27+
this.prompt = e.Value!.ToString();
28+
29+
await Task.CompletedTask;
30+
}
31+
32+
private async Task CompleteChat()
33+
{
34+
if (string.IsNullOrWhiteSpace(this.prompt) == true)
35+
{
36+
return;
37+
}
38+
39+
await this.OnPromptSent.InvokeAsync(this.prompt);
40+
this.prompt = string.Empty;
41+
}
42+
43+
private async Task ClearChat()
44+
{
45+
await this.OnChatCleared.InvokeAsync();
46+
}
47+
}
Lines changed: 21 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,34 @@
1-
@using AzureOpenAIProxy.PlaygroundApp.Clients
2-
@inject IOpenAIApiClient Api
1+
@using AzureOpenAIProxy.PlaygroundApp.Models
32

4-
<div class="container">
5-
<h3>Chat Window</h3>
6-
7-
<div class="row">
8-
<div class="col-md-6">
9-
<textarea class="form-control" readonly>@userPrompt</textarea>
10-
</div>
11-
<div class="col-md-6">
12-
<textarea class="form-control" readonly>@assistantMessage</textarea>
13-
</div>
14-
</div>
15-
16-
<div class="row mt-3">
17-
<div class="col-md-6">
18-
<textarea class="form-control" @bind="@userInput"></textarea>
19-
</div>
20-
<div class="col-md-6">
21-
<button class="btn btn-primary" @onclick="SendAsync">Send</button>
22-
<button class="btn btn-secondary" @onclick="ClearAsync">Clear</button>
23-
</div>
24-
</div>
25-
</div>
3+
<FluentStack Id="@Id" Style="width: 100%; height: 100%;" Orientation="Orientation.Vertical" VerticalAlignment="VerticalAlignment.Bottom">
4+
<ChatHistoryComponent Id="chat-history" Messages="messages" />
5+
<ChatPromptComponent Id="chat-prompt" OnPromptSent="SendPrompt" OnChatCleared="ClearMessage" />
6+
</FluentStack>
267

278
@code {
28-
private string? endpoint = "https://localhost:7001/";
29-
private string? apiKey = "abcdef";
30-
private string? deploymentName = "model-gpt35turbo16k-0613";
31-
private int? maxTokens = 4096;
32-
private float? temperature = 0.7f;
33-
private string? systemPrompt = "You are an AI assistant that helps people find information.";
34-
private string? userPrompt;
35-
private string? assistantMessage;
36-
private string? userInput;
9+
private List<ChatMessage>? messages;
3710

38-
private async Task SendAsync()
11+
[Parameter]
12+
public string? Id { get; set; }
13+
14+
protected override async Task OnInitializedAsync()
3915
{
40-
userPrompt = userInput;
16+
this.messages = [];
17+
18+
await Task.CompletedTask;
19+
}
4120

42-
try
43-
{
44-
var options = new OpenAIApiClientOptions()
45-
{
46-
Endpoint = endpoint,
47-
ApiKey = apiKey,
48-
DeploymentName = deploymentName,
49-
MaxTokens = maxTokens,
50-
Temperature = temperature,
51-
SystemPrompt = systemPrompt,
52-
UserPrompt = userInput,
53-
};
54-
var result = await Api.CompleteChatAsync(options);
55-
assistantMessage = result;
21+
private async Task SendPrompt(string prompt)
22+
{
23+
this.messages!.Add(new ChatMessage() { Role = MessageRole.User, Message = prompt });
5624

57-
}
58-
catch (Exception ex)
59-
{
60-
assistantMessage = ex.Message;
61-
}
25+
await Task.CompletedTask;
6226
}
6327

64-
private async Task ClearAsync()
28+
private async Task ClearMessage()
6529
{
66-
userPrompt = string.Empty;
67-
assistantMessage = string.Empty;
68-
userInput = string.Empty;
30+
this.messages!.Clear();
6931

7032
await Task.CompletedTask;
7133
}
72-
}
34+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@using AzureOpenAIProxy.PlaygroundApp.Clients
2+
@inject IOpenAIApiClient Api
3+
4+
<div class="container">
5+
<h3>Chat Window</h3>
6+
7+
<div class="row">
8+
<div class="col-md-6">
9+
<textarea class="form-control" readonly>@userPrompt</textarea>
10+
</div>
11+
<div class="col-md-6">
12+
<textarea class="form-control" readonly>@assistantMessage</textarea>
13+
</div>
14+
</div>
15+
16+
<div class="row mt-3">
17+
<div class="col-md-6">
18+
<textarea class="form-control" @bind="@userInput"></textarea>
19+
</div>
20+
<div class="col-md-6">
21+
<button class="btn btn-primary" @onclick="SendAsync">Send</button>
22+
<button class="btn btn-secondary" @onclick="ClearAsync">Clear</button>
23+
</div>
24+
</div>
25+
</div>
26+
27+
@code {
28+
private string? endpoint = "https://localhost:7001/";
29+
private string? apiKey = "abcdef";
30+
private string? deploymentName = "model-gpt35turbo16k-0613";
31+
private int? maxTokens = 4096;
32+
private float? temperature = 0.7f;
33+
private string? systemPrompt = "You are an AI assistant that helps people find information.";
34+
private string? userPrompt;
35+
private string? assistantMessage;
36+
private string? userInput;
37+
38+
private async Task SendAsync()
39+
{
40+
userPrompt = userInput;
41+
42+
try
43+
{
44+
var options = new OpenAIApiClientOptions()
45+
{
46+
Endpoint = endpoint,
47+
ApiKey = apiKey,
48+
DeploymentName = deploymentName,
49+
MaxTokens = maxTokens,
50+
Temperature = temperature,
51+
SystemPrompt = systemPrompt,
52+
UserPrompt = userInput,
53+
};
54+
var result = await Api.CompleteChatAsync(options);
55+
assistantMessage = result;
56+
57+
}
58+
catch (Exception ex)
59+
{
60+
assistantMessage = ex.Message;
61+
}
62+
}
63+
64+
private async Task ClearAsync()
65+
{
66+
userPrompt = string.Empty;
67+
assistantMessage = string.Empty;
68+
userInput = string.Empty;
69+
70+
await Task.CompletedTask;
71+
}
72+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
namespace AzureOpenAIProxy.PlaygroundApp.Models;
2+
3+
/// <summary>
4+
/// This represents the entity for chat message.
5+
/// </summary>
6+
public class ChatMessage
7+
{
8+
/// <summary>
9+
/// Gets or sets the message role.
10+
/// </summary>
11+
public MessageRole? Role { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets the message.
15+
/// </summary>
16+
public string? Message { get; set; }
17+
}
18+
19+
/// <summary>
20+
/// This defines the role of the message.
21+
/// </summary>
22+
public enum MessageRole
23+
{
24+
/// <summary>
25+
/// Indicates the role is not defined.
26+
/// </summary>
27+
Undefined,
28+
29+
/// <summary>
30+
/// Indicates the user role.
31+
/// </summary>
32+
User,
33+
34+
/// <summary>
35+
/// Indicates the assistant role.
36+
/// </summary>
37+
Assistant
38+
}

0 commit comments

Comments
 (0)