update
This commit is contained in:
parent
fbc820208a
commit
7626775d4b
10
GptBlazor/Constant.cs
Normal file
10
GptBlazor/Constant.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace GptBlazor;
|
||||||
|
|
||||||
|
public class Constant
|
||||||
|
{
|
||||||
|
public static string? ResourceName;
|
||||||
|
|
||||||
|
public static string? DeploymentId;
|
||||||
|
|
||||||
|
public static string? ApiKey;
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UserSecretsId>c76d0bd7-b6fa-4aaa-baeb-49ab35f36fc4</UserSecretsId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -12,6 +13,7 @@
|
|||||||
<PackageReference Include="Furion" Version="4.8.7.35" />
|
<PackageReference Include="Furion" Version="4.8.7.35" />
|
||||||
<PackageReference Include="Markdig" Version="0.31.0" />
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
<PackageReference Include="OpenAI" Version="1.7.2" />
|
<PackageReference Include="OpenAI" Version="1.7.2" />
|
||||||
|
<PackageReference Include="Toolbelt.Blazor.HotKeys2" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<div class="card-header d-flex justify-content-between align-items-center p-3">
|
<div class="card-header d-flex justify-content-between align-items-center p-3">
|
||||||
<h5 class="mb-0">Chat</h5>
|
<h5 class="mb-0">Chat</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body" style="overflow: auto; position: relative; height: calc(100vh - 196px)">
|
<div class="card-body" id="scroll" style="overflow: auto; position: relative; height: calc(100vh - 196px)">
|
||||||
|
|
||||||
@foreach (var message in _messages)
|
@foreach (var message in _messages)
|
||||||
{
|
{
|
||||||
@ -57,8 +57,8 @@
|
|||||||
<div class="card-footer text-muted d-flex justify-content-start align-items-center p-3">
|
<div class="card-footer text-muted d-flex justify-content-start align-items-center p-3">
|
||||||
<img src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava3-bg.webp"
|
<img src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava3-bg.webp"
|
||||||
alt="avatar 3" style="width: 40px; height: 100%;">
|
alt="avatar 3" style="width: 40px; height: 100%;">
|
||||||
<Textarea rows="4" @bind-Value="@_userInput"></Textarea>
|
<textarea @ref="Input" rows="4" @bind-value="@_userInput" @bind-value:event="onchange" class="form-control"></textarea>
|
||||||
<Button Icon="fas fa-paper-plane" OnClick="@SendMessage"></Button>
|
<Button @ref="SubmitButton" Icon="fas fa-paper-plane" Text="发送[Ctrl+Enter]" OnClick="@SendMessage" IsDisabled="_isThinking"></Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,35 +1,59 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using BootstrapBlazor.Components;
|
||||||
using Furion.LinqBuilder;
|
using Furion.LinqBuilder;
|
||||||
using GptBlazor.Entity;
|
|
||||||
using GptBlazor.Service;
|
using GptBlazor.Service;
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
using Toolbelt.Blazor.HotKeys2;
|
||||||
|
using Message = GptBlazor.Entity.Message;
|
||||||
|
|
||||||
namespace GptBlazor.Pages;
|
namespace GptBlazor.Pages;
|
||||||
|
|
||||||
public partial class Index
|
public partial class Index : IAsyncDisposable
|
||||||
{
|
{
|
||||||
private List<Message> _messages;
|
private List<Message> _messages;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
[NotNull]
|
||||||
|
private IJSRuntime? JsRuntime { get; set; }
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
[NotNull]
|
[NotNull]
|
||||||
private OpenAiService? OpenAiService { get; set; }
|
private OpenAiService? OpenAiService { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
[NotNull]
|
||||||
|
private HotKeys HotKeys { get; set; }
|
||||||
|
|
||||||
|
private ElementReference Input { get; set; }
|
||||||
|
|
||||||
|
private Button? SubmitButton { get; set; }
|
||||||
|
|
||||||
private string _userInput = string.Empty;
|
private string _userInput = string.Empty;
|
||||||
|
|
||||||
private string _response = string.Empty;
|
private string _response = string.Empty;
|
||||||
|
|
||||||
private bool _isThinking = false;
|
private bool _isThinking = false;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
private HotKeysContext HotKeysContext;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
await base.OnInitializedAsync();
|
base.OnInitialized();
|
||||||
_messages = new List<Message>();
|
_messages = new List<Message>();
|
||||||
|
this.HotKeysContext = this.HotKeys.CreateContext()
|
||||||
|
.Add(ModCode.Ctrl, Code.Enter, async () =>
|
||||||
|
{
|
||||||
|
await SubmitButton.FocusAsync();
|
||||||
|
await SendMessage();
|
||||||
|
}, exclude: Exclude.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendMessage()
|
private async Task SendMessage()
|
||||||
{
|
{
|
||||||
if (_userInput.IsNullOrEmpty())
|
//await JsRuntime.InvokeVoidAsync("focusInput", SubmitButton);
|
||||||
|
if (_userInput.IsNullOrEmpty() || _isThinking)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -44,10 +68,12 @@ public partial class Index
|
|||||||
});
|
});
|
||||||
_isThinking = true;
|
_isThinking = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
await JsRuntime.InvokeVoidAsync("scrollToBottom");
|
||||||
await foreach (var str in OpenAiService.StreamResponseEnumerableFromChatbotAsync(input))
|
await foreach (var str in OpenAiService.StreamResponseEnumerableFromChatbotAsync(input))
|
||||||
{
|
{
|
||||||
_response += str;
|
_response += str;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
await JsRuntime.InvokeVoidAsync("scrollToBottom");
|
||||||
}
|
}
|
||||||
|
|
||||||
_messages.Add(new Message
|
_messages.Add(new Message
|
||||||
@ -59,5 +85,12 @@ public partial class Index
|
|||||||
_isThinking = false;
|
_isThinking = false;
|
||||||
_response = string.Empty;
|
_response = string.Empty;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
await JsRuntime.InvokeVoidAsync("scrollToBottom");
|
||||||
|
await Input.FocusAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
await this.HotKeys.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,5 +34,6 @@
|
|||||||
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></script>
|
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></script>
|
||||||
<script src="_framework/blazor.server.js"></script>
|
<script src="_framework/blazor.server.js"></script>
|
||||||
<script src="js/prism.js"></script>
|
<script src="js/prism.js"></script>
|
||||||
|
<script src="js/site.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,6 +1,10 @@
|
|||||||
|
using GptBlazor;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using GptBlazor.Data;
|
using GptBlazor.Data;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using Toolbelt.Blazor.Extensions.DependencyInjection;
|
||||||
|
using App = Furion.App;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args).Inject();
|
var builder = WebApplication.CreateBuilder(args).Inject();
|
||||||
|
|
||||||
@ -9,6 +13,19 @@ builder.Services.AddRazorPages().AddInjectBase();
|
|||||||
builder.Services.AddServerSideBlazor();
|
builder.Services.AddServerSideBlazor();
|
||||||
builder.Services.AddSingleton<WeatherForecastService>();
|
builder.Services.AddSingleton<WeatherForecastService>();
|
||||||
builder.Services.AddBootstrapBlazor();
|
builder.Services.AddBootstrapBlazor();
|
||||||
|
builder.Services.AddHotKeys2();
|
||||||
|
|
||||||
|
var config = App.Configuration.GetSection("ChatGpt");
|
||||||
|
Constant.ResourceName = config["ResourceName"];
|
||||||
|
Constant.DeploymentId = config["DeploymentId"];
|
||||||
|
Constant.ApiKey = config["ApiKey"];
|
||||||
|
ChangeToken.OnChange(() => config.GetReloadToken(), () =>
|
||||||
|
{
|
||||||
|
Constant.ResourceName = config["ResourceName"];
|
||||||
|
Constant.DeploymentId = config["DeploymentId"];
|
||||||
|
Constant.ApiKey = config["ApiKey"];
|
||||||
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
@ -6,17 +6,12 @@ namespace GptBlazor.Service;
|
|||||||
|
|
||||||
public class OpenAiService : IScoped
|
public class OpenAiService : IScoped
|
||||||
{
|
{
|
||||||
private const string _resourceName = "jxgpt";
|
|
||||||
|
|
||||||
private const string _deploymentId = "gpt35test";
|
|
||||||
|
|
||||||
private const string _apiKey = "e97ae651d99945e2b3bb7e666442f5e9";
|
|
||||||
|
|
||||||
private readonly Conversation conversation;
|
private readonly Conversation conversation;
|
||||||
|
|
||||||
public OpenAiService()
|
public OpenAiService()
|
||||||
{
|
{
|
||||||
var api = OpenAIAPI.ForAzure(_resourceName, _deploymentId, _apiKey);
|
var api = OpenAIAPI.ForAzure(Constant.ResourceName, Constant.DeploymentId, Constant.ApiKey);
|
||||||
api.ApiVersion = "2023-03-15-preview";
|
api.ApiVersion = "2023-03-15-preview";
|
||||||
conversation = api.Chat.CreateConversation();
|
conversation = api.Chat.CreateConversation();
|
||||||
}
|
}
|
||||||
|
8
GptBlazor/wwwroot/js/site.js
Normal file
8
GptBlazor/wwwroot/js/site.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
function scrollToBottom() {
|
||||||
|
var element = document.getElementById("scroll");
|
||||||
|
element.scrollTop = element.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusInput(element) {
|
||||||
|
element.focus();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user