Skip to content

Commit

Permalink
Fixed formatting
Browse files Browse the repository at this point in the history
Signed-off-by: joshuajpiluden@gmail.com <joshuajpiluden@Gmail.com>
  • Loading branch information
jjosh102 committed Oct 24, 2024
1 parent 124ddac commit aa00a20
Show file tree
Hide file tree
Showing 44 changed files with 676 additions and 740 deletions.
66 changes: 29 additions & 37 deletions src/Open.Blazor.Core/Features/Chat/Chat.razor
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
@using Microsoft.SemanticKernel
@using Microsoft.SemanticKernel.ChatCompletion
@using Microsoft.SemanticKernel.Connectors.OpenAI
@using System.Text
@using Open.Blazor.Core.Features.Components
@using Open.Blazor.Core.Features.Shared.Models
@using Open.Blazor.Core.Features.Shared.Models
@inject IJSRuntime JSRuntime
@if (_discourse is not null && _activeOllamaModels is not null)
{
<div class="settings">

<FluentCard>
<FluentLabel Typo="Typography.Header"> Chat Settings </FluentLabel>
<FluentDivider Style="margin-top:10px;margin-bottom:10px;" />
<FluentDivider Style="margin-top:10px;margin-bottom:10px;"/>
<FluentSelect TOption="OllamaModel"
Label="Model"
Items="@_activeOllamaModels.Models"
Expand All @@ -20,8 +15,8 @@
Style="margin:5px"
OptionText="@(p => p.Name)"
SelectedOption="_selectedModel"
SelectedOptionChanged="HandleSelectedOptionChanged" />
<FluentSlider Id="temp-control" Label="@($"Temperature: {_temperature}")" @bind-Value="_temperature" Min="0" Max="2" Step=".1" Style="margin:5px" />
SelectedOptionChanged="HandleSelectedOptionChanged"/>
<FluentSlider Id="temp-control" Label="@($"Temperature: {_temperature}")" @bind-Value="_temperature" Min="0" Max="2" Step=".1" Style="margin:5px"/>
<FluentTooltip Anchor="temp-control"
Delay="300"
Position="TooltipPosition.Start">
Expand All @@ -30,44 +25,44 @@
</FluentTooltip>
@if (UseSemanticKernel)
{
<FluentSlider Id="max-token-control" Label="@($"Max Tokens: {_maxTokens}")" @bind-Value="_maxTokens" Min="0" Max="4000" Step="10" Style="margin:5px" />
<FluentSlider Id="max-token-control" Label="@($"Max Tokens: {_maxTokens}")" @bind-Value="_maxTokens" Min="0" Max="4000" Step="10" Style="margin:5px"/>
<FluentTooltip Anchor="max-token-control"
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: Limits the length of the response. </p>
<p>How it works: It sets a maximum number of words or parts of words the model can generate in its response. </p>
</FluentTooltip>
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: Limits the length of the response. </p>
<p>How it works: It sets a maximum number of words or parts of words the model can generate in its response. </p>
</FluentTooltip>
}
<FluentSlider Id="topp-control" Label="@($"Top P: {_topP}")" @bind-Value="_topP" Min="0" Max="2" Step=".1" Style="margin:5px" />
<FluentSlider Id="topp-control" Label="@($"Top P: {_topP}")" @bind-Value="_topP" Min="0" Max="2" Step=".1" Style="margin:5px"/>
<FluentTooltip Anchor="topp-control"
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: A method to control the randomness of the model's responses, often referred to as "nucleus sampling". </p>
<p>How it works: It looks at the top percentage of possibilities for the next word. If set to 1.0, it considers all possibilities (most random); if set to a lower value, it only considers the most likely options. </p>
<p>What it is: A method to control the randomness of the model's responses, often referred to as "nucleus sampling". </p>
<p>How it works: It looks at the top percentage of possibilities for the next word. If set to 1.0, it considers all possibilities (most random); if set to a lower value, it only considers the most likely options. </p>
</FluentTooltip>
<FluentSlider Id="presence-penalty-control" Label="@($"Presence Penalty: {_presencePenalty}")" @bind-Value="_presencePenalty" Min="0" Max="2" Step=".1" Style="margin:5px" />
<FluentSlider Id="presence-penalty-control" Label="@($"Presence Penalty: {_presencePenalty}")" @bind-Value="_presencePenalty" Min="0" Max="2" Step=".1" Style="margin:5px"/>
<FluentTooltip Anchor="presence-penalty-control"
Delay="300"
Position="TooltipPosition.Start">
<p> What it is: A way to encourage the model to talk about new topics. </p>
<p>How it works: It reduces the likelihood of the model repeating the same words, promoting more varied responses. </p>
<p>How it works: It reduces the likelihood of the model repeating the same words, promoting more varied responses. </p>
</FluentTooltip>
<FluentSlider Id="frequency-penalty-control" Label="@($"Frequency Penalty: {_frequencyPenalty}")" @bind-Value="_frequencyPenalty" Min="0" Max="2" Step=".1" Style="margin:5px" />
<FluentSlider Id="frequency-penalty-control" Label="@($"Frequency Penalty: {_frequencyPenalty}")" @bind-Value="_frequencyPenalty" Min="0" Max="2" Step=".1" Style="margin:5px"/>
<FluentTooltip Anchor="frequency-penalty-control"
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: Similar to the presence penalty but focuses on how often words are used. </p>
<p>What it is: Similar to the presence penalty but focuses on how often words are used. </p>
<p>How it works: It discourages the model from using words too frequently, making the output more diverse. </p>
</FluentTooltip>
@if (UseSemanticKernel)
{
<FluentTextArea Id="system-prompt-control" Label="System Prompt" @bind-Value="_chatSystemPrompt" Cols="150"></FluentTextArea>
<FluentTooltip Anchor="system-prompt-control"
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: Information about the person using the model. </p>
<p>How it works: It might personalize the responses based on the user's identity or preferences. </p>
</FluentTooltip>
Delay="300"
Position="TooltipPosition.Start">
<p>What it is: Information about the person using the model. </p>
<p>How it works: It might personalize the responses based on the user's identity or preferences. </p>
</FluentTooltip>
}


Expand All @@ -78,7 +73,7 @@

@foreach (var message in _discourse.ChatMessages)
{
<ChatContent Message="message" ToastService="ToastService" JsRuntime="JsRuntime" />
<ChatContent Message="message" ToastService="ToastService" JsRuntime="JsRuntime"/>
}

</div>
Expand All @@ -87,13 +82,12 @@
@if (!_isListening)
{
<FluentButton Id="speech-button" IconStart="@(new Icons.Filled.Size16.Record())" Style="margin-right:5px"
Appearance="Appearance.Stealth" OnClick="StartListening" />
Appearance="Appearance.Stealth" OnClick="StartListening"/>
}
else
{
<FluentButton Id="speech-button" IconStart="@(new Icons.Filled.Size16.RecordStop())" Style="margin-right:5px" Color="Color.Error"
Appearance="Appearance.Accent" OnClick="StopListening" />

<FluentButton Id="speech-button" IconStart="@(new Icons.Filled.Size16.RecordStop())" Style="margin-right:5px" Color="Color.Error"
Appearance="Appearance.Accent" OnClick="StopListening"/>
}

<FluentTooltip Anchor="speech-button"
Expand All @@ -107,16 +101,14 @@
@if (!_isChatOngoing)
{
<FluentButton IconStart="@(new Icons.Filled.Size16.Send())" Style="margin-left:5px"
Appearance="Appearance.Stealth" OnClick="SendMessage" />
Appearance="Appearance.Stealth" OnClick="SendMessage"/>
}
else
{
<FluentButton IconStart="@(new Icons.Filled.Size16.Stop())" Style="margin-left:5px"
Appearance="Appearance.Stealth" OnClick="StopChat" />
Appearance="Appearance.Stealth" OnClick="StopChat"/>
}



</div>
}

}
115 changes: 51 additions & 64 deletions src/Open.Blazor.Core/Features/Chat/Chat.razor.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,65 @@
using Microsoft.AspNetCore.Components;
using System.Text;
using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components;
using Microsoft.JSInterop;
using Microsoft.SemanticKernel;
using Open.Blazor.Core.Features.Shared;
using Open.Blazor.Core.Features.Shared.Models;
using System.Text;
using Toolbelt.Blazor.SpeechRecognition;

namespace Open.Blazor.Core.Features.Chat;

public partial class Chat : ComponentBase, IDisposable
{

//todo support history
private Kernel _kernel = default!;
private Ollama? _activeOllamaModels = default!;
private CancellationTokenSource _cancellationTokenSource = default!;
private string? _chatSystemPrompt;
private Discourse _discourse = new();
private string _userMessage = string.Empty;
private double _frequencyPenalty;
private bool _isChatOngoing = false;
private bool _isListening = false;
private bool _isOllamaUp = false;
private Ollama? _activeOllamaModels = default!;
private bool _isSpeechAvailable = false;

//todo support history
private Kernel _kernel = default!;
private int _maxTokens = 2000;
private double _presencePenalty;

//Speech recognition
private SpeechRecognitionResult[] _results = Array.Empty<SpeechRecognitionResult>();
private OllamaModel _selectedModel = default!;
private CancellationTokenSource _cancellationTokenSource = default!;

private IList<string> _stopSequences = default!;

//chat settings
private double _temperature = 1;
private double _topP = 1;
private double _presencePenalty;
private double _frequencyPenalty;
private int _maxTokens = 2000;
private IList<string> _stopSequences = default!;
private string? _chatSystemPrompt;
private string _userMessage = string.Empty;

//Speech recognition
private SpeechRecognitionResult[] _results = Array.Empty<SpeechRecognitionResult>();
private bool _isSpeechAvailable = false;
private bool _isListening = false;

[Parameter] public bool UseSemanticKernel { get; set; }

[Parameter]
public bool UseSemanticKernel { get; set; }

[Inject] private ChatService ChatService { get; set; } = default!;

[Inject]
ChatService ChatService { get; set; } = default!;
[Inject] private OllamaService OllamaService { get; set; } = default!;

[Inject]
OllamaService OllamaService { get; set; } = default!;
[Inject] public required IToastService ToastService { get; set; }

[Inject]
public required IToastService ToastService { get; set; }
[Inject] public required IJSRuntime JsRuntime { get; set; }

[Inject]
public required IJSRuntime JsRuntime { get; set; }

[Inject] public required SpeechRecognition SpeechRecognition { get; set; }

[Inject]
public required SpeechRecognition SpeechRecognition { get; set; }
public void Dispose()
{
_cancellationTokenSource?.Dispose();
SpeechRecognition.Result -= OnSpeechRecognized!;
}

protected override async Task OnInitializedAsync()
{

SpeechRecognition.Lang = "en-US";
SpeechRecognition.InterimResults = false;
SpeechRecognition.Continuous = true;
Expand All @@ -81,21 +82,17 @@ protected override async Task OnInitializedAsync()
}

var defaultModel = _activeOllamaModels.Models.First();
if (UseSemanticKernel)
{
_kernel = ChatService.CreateKernel(defaultModel.Name);
}
if (UseSemanticKernel) _kernel = ChatService.CreateKernel(defaultModel.Name);

_selectedModel = defaultModel;
_cancellationTokenSource = new();

_cancellationTokenSource = new CancellationTokenSource();
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
this._isSpeechAvailable = await this.SpeechRecognition.IsAvailableAsync();
_isSpeechAvailable = await SpeechRecognition.IsAvailableAsync();
StateHasChanged();
}

Expand All @@ -117,16 +114,15 @@ private async Task SendMessage()

await StopListening();

ChatSettings settings = ChatSettings.New(_temperature, _topP, _presencePenalty, _frequencyPenalty, _maxTokens, default, _chatSystemPrompt);
var settings = ChatSettings.New(_temperature, _topP, _presencePenalty, _frequencyPenalty, _maxTokens,
default, _chatSystemPrompt);

if (UseSemanticKernel)
{
await ChatService.StreamChatMessageContentAsync(_kernel, _discourse, OnStreamCompletion, settings, _cancellationTokenSource.Token);
}
await ChatService.StreamChatMessageContentAsync(_kernel, _discourse, OnStreamCompletion, settings,
_cancellationTokenSource.Token);
else
{
await ChatService.StreamChatMessageContentAsync(_discourse, OnStreamCompletion, settings, _cancellationTokenSource.Token);
}
await ChatService.StreamChatMessageContentAsync(_discourse, OnStreamCompletion, settings,
_cancellationTokenSource.Token);

_discourse.ChatMessages.Last().IsDoneStreaming = true;
}
Expand Down Expand Up @@ -159,21 +155,22 @@ private void ResetCancellationTokenSource()
}
}

private void ShowError(string errorMessage) =>
ToastService.ShowError(errorMessage);
private void ShowError(string errorMessage)
{
ToastService.ShowError(errorMessage);
}


private void HandleSelectedOptionChanged(OllamaModel selectedModelChanged)
{
_selectedModel = selectedModelChanged;
if (UseSemanticKernel)
{
_kernel = ChatService.CreateKernel(_selectedModel.Name);
}
if (UseSemanticKernel) _kernel = ChatService.CreateKernel(_selectedModel.Name);
}

private async Task StopChat() =>
private async Task StopChat()
{
await _cancellationTokenSource.CancelAsync();
}

private async Task ScrollToBottom()
{
Expand All @@ -183,17 +180,12 @@ private async Task ScrollToBottom()

private void OnSpeechRecognized(object? sender, SpeechRecognitionEventArgs args)
{
if (args.Results == null || args.Results.Length <= args.ResultIndex)
{
return;
}
if (args.Results == null || args.Results.Length <= args.ResultIndex) return;

var transcript = new StringBuilder(_userMessage);
foreach (var result in args.Results.Skip(args.ResultIndex))
{
if (result.IsFinal)
transcript.Append(result.Items![0].Transcript);
}

_userMessage = transcript.ToString();

Expand All @@ -208,6 +200,7 @@ private bool EnsureDeviceIsAvailable()
ShowError("Device not available");
return false;
}

return true;
}

Expand Down Expand Up @@ -236,10 +229,4 @@ private async Task StopListening()
ToastService.ShowWarning("Stopped Listening");
}
}

public void Dispose()
{
_cancellationTokenSource?.Dispose();
SpeechRecognition.Result -= OnSpeechRecognized!;
}
}
}
8 changes: 4 additions & 4 deletions src/Open.Blazor.Core/Features/Chat/Chat.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

.settings {
display: block;
margin-right:60px;
position: fixed;
margin-right: 60px;
position: fixed;
right: 0;
top: 60px;
width:300px;
width: 300px;
}

@media (max-width:1400px) {
@media (max-width: 1400px) {
.settings {
display: none;
}
Expand Down
Loading

0 comments on commit aa00a20

Please sign in to comment.