Skip to content

Commit

Permalink
Fix AddChatGptEntityFrameworkIntegration extension; Release 2.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
rodion-m committed Apr 19, 2023
1 parent 8bbeea6 commit 6d7d243
Show file tree
Hide file tree
Showing 38 changed files with 1,570 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public static IServiceCollection AddChatGptIntegrationCore(
services.AddHttpClient();

services.AddSingleton<ITimeProvider, TimeProviderUtc>();
services.AddSingleton<ChatGPTFactory>();
services.AddScoped<ChatGPTFactory>();

return services;
}
Expand Down
2 changes: 1 addition & 1 deletion OpenAI.ChatGpt.AspNetCore/OpenAI.ChatGpt.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PackageId>OpenAI.ChatGPT.AspNetCore</PackageId>
<PackageProjectUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</PackageProjectUrl>
<Product>OpenAI ChatGPT integration for .NET with DI</Product>
<Version>2.2.1</Version>
<Version>2.2.2</Version>
<Description>OpenAI Chat Completions API (ChatGPT) integration with easy DI supporting (Microsoft.Extensions.DependencyInjection). It allows you to use the API in your .NET applications. Also, the client supports streaming responses (like ChatGPT) via async streams.</Description>
<RepositoryUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</RepositoryUrl>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageId>OpenAI.ChatGPT.EntityFrameworkCore</PackageId>
<PackageProjectUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</PackageProjectUrl>
<Product>OpenAI ChatGPT integration for .NET with EF Core storage</Product>
<Version>2.2.1</Version>
<Version>2.2.2</Version>
<Description>OpenAI Chat Completions API (ChatGPT) integration with DI and EF Core supporting. It allows you to use the API in your .NET applications. Also, the client supports streaming responses (like ChatGPT) via async streams.</Description>
<RepositoryUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</RepositoryUrl>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
Expand Down
2 changes: 1 addition & 1 deletion OpenAI.ChatGpt/OpenAI.ChatGpt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageId>OpenAI.ChatGPT</PackageId>
<PackageProjectUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</PackageProjectUrl>
<Product>OpenAI ChatGPT integration for .NET</Product>
<Version>2.2.1</Version>
<Version>2.2.2</Version>
<Description>.NET integration for ChatGPT with streaming responses supporting (like ChatGPT) via async streams.</Description>
<RepositoryUrl>https://github.com/rodion-m/ChatGPT_API_dotnet</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
7 changes: 7 additions & 0 deletions OpenAI_DotNet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{926D63B6
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAI.ChatGpt.IntegrationTests", "tests\OpenAI.ChatGpt.IntegrationTests\OpenAI.ChatGpt.IntegrationTests.csproj", "{983A565C-5AE2-4F76-8B7B-7C5C051072C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatGpt.BlazorExample", "samples\ChatGpt.BlazorExample\ChatGpt.BlazorExample.csproj", "{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -61,6 +63,10 @@ Global
{983A565C-5AE2-4F76-8B7B-7C5C051072C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{983A565C-5AE2-4F76-8B7B-7C5C051072C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{983A565C-5AE2-4F76-8B7B-7C5C051072C7}.Release|Any CPU.Build.0 = Release|Any CPU
{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -70,5 +76,6 @@ Global
{8C2E3643-95B1-44E8-A0BD-66576DCF7E3B} = {80DB142C-5A1B-431C-BD85-19C83C6FC0A3}
{7A50F277-75AA-4C4D-B0C9-08FE77A1A9E4} = {926D63B6-9F6A-45A1-B5B7-5F36352C23AB}
{983A565C-5AE2-4F76-8B7B-7C5C051072C7} = {926D63B6-9F6A-45A1-B5B7-5F36352C23AB}
{88213D5C-AADC-4F03-ACA3-7ADDCCE87DF4} = {80DB142C-5A1B-431C-BD85-19C83C6FC0A3}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions samples/ChatGpt.BlazorExample/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
15 changes: 15 additions & 0 deletions samples/ChatGpt.BlazorExample/ChatGpt.BlazorExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>e883db38-8c66-433b-a1cf-301b5b3b2171</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
<PackageReference Include="OpenAI.ChatGPT.EntityFrameworkCore" Version="2.2.0" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions samples/ChatGpt.BlazorExample/Pages/Counter.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()
{
currentCount++;
}
}
42 changes: 42 additions & 0 deletions samples/ChatGpt.BlazorExample/Pages/Error.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@page
@model ChatGpt.BlazorExample.Pages.ErrorModel

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head>

<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>

</html>
27 changes: 27 additions & 0 deletions samples/ChatGpt.BlazorExample/Pages/Error.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;

namespace ChatGpt.BlazorExample.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

private readonly ILogger<ErrorModel> _logger;

public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}

public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
213 changes: 213 additions & 0 deletions samples/ChatGpt.BlazorExample/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
@page "/"
@using OpenAI.ChatGpt.AspNetCore
@using OpenAI.ChatGpt
@using OpenAI.ChatGpt.Models
@using OpenAI.ChatGpt.Models.ChatCompletion
@inject IJSRuntime JsRuntime
@inject ChatGPTFactory ChatGPTFactory

<PageTitle>Index</PageTitle>
@if (_messages is null)
{
<h3>Loading messages...</h3>
return;
}
<style>
textarea {
border: 1px dashed #888;
border-radius: 5px;
width: 80%;
overflow: auto;
background: #f7f7f7
}
/* improved CSS for speech bubbles */
.assistant, .user {
position: relative;
font-family: arial;
font-size: 1.1em;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.assistant:after, .user:after {
content: '';
border: 20px solid transparent;
position: absolute;
margin-top: -30px;
}
.user {
background: #03a9f4;
color: #fff;
margin-left: 20%;
margin-right: 100px;
top: 30%;
text-align: right;
}
.assistant {
background: #4CAF50;
color: #fff;
margin-left: 100px;
margin-right: 20%;
}
.user:after {
border-left-color: #03a9f4;
border-right: 0;
right: -20px;
}
.assistant:after {
border-right-color: #4CAF50;
border-left: 0;
left: -20px;
}
.msg {
font-size: medium;
}
</style>
<h1>ChatGPT</h1>
<p style="font-size:small"><b>Total Tokens:</b> @_totalTokens</p>
<div id="chatcontainer" style="height:550px; width:80%; overflow: scroll;">
@foreach (var item in _messages)
{
<div>
@if (item.role == item.content)
{
<div style="float: right; margin-right: 20px; margin-top: 10px">
<b>Human</b>
</div>
<div class="@item.role.ToLower()">
<div class="msg">
@item.content
<br /><br />
</div>
</div>
}
else
{
<div style="float: left; margin-left: 20px; margin-top: 10px">
<b>ChatGPT&nbsp;&nbsp;</b>
</div>
<div class="@item.role.ToLower()">
<div class="msg">
@if (item.content != null)
{
@((MarkupString)item.content)
}
<br /><br />
</div>
</div>
}
</div>
}
</div>
@if (!_processing)
{
<textarea rows="3" cols="60" @bind="_prompt"></textarea>
<br />
<button class="btn btn-primary"
@onclick="CallChatGpt">
Call ChatGPT
</button>
<span>&nbsp;</span>
<button class="btn btn-info"
@onclick="RestartChatGpt">
Restart
</button>
}
else
{
<br>
<h4>Processing...</h4>
}
<br /><p style="color:red">@_errorMessage</p>
@code {
List<(string role, string content)> _messages = new();
string _prompt = "Write a 10 word description of OpenAI ChatGPT";
string _errorMessage = "";
bool _processing = false;
int _totalTokens = 0;
private Chat _chat;

protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await CreateNewChat();
}

private async Task CreateNewChat()
{
if(_chat != null) await _chat.DisposeAsync();
var chatGpt = await ChatGPTFactory.Create("test-user-id");
_chat = await chatGpt.StartNewTopic("Test Topic", clearOnDisposal: true);

}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
try
{
await JsRuntime.InvokeAsync<string>("ScrollToBottom", "chatcontainer");
}
catch
{
// do nothing if this fails
}
}

async Task CallChatGpt()
{
try
{
// Set Processing to true to indicate that the method is processing
_processing = true;

// Call StateHasChanged to refresh the UI
StateHasChanged();

// Clear any previous error messages
_errorMessage = "";
var response = await _chat.GetNextMessageResponse(_prompt);

// Create a new MessageSave object with the user's prompt and other
// details and add it to the messages list
_messages.Add((ChatCompletionRoles.User, _prompt));
_messages.Add((ChatCompletionRoles.Assistant, response));

//TotalTokens = _chat.LastResponse.Usage.TotalTokens;
}
catch (Exception ex)
{
// Set ErrorMessage to the exception message if an error occurs
_errorMessage = ex.Message;
}
finally
{
// Clear the prompt variable
_prompt = "";

// Set Processing to false to indicate
// that the method is done processing
_processing = false;

// Call StateHasChanged to refresh the UI
StateHasChanged();
}
}

async Task RestartChatGpt()
{
_prompt = "Write a 10 word description of OpenAI ChatGPT";
await CreateNewChat();
_messages = new();
_totalTokens = 0;
_errorMessage = "";
StateHasChanged();
}
}
Loading

0 comments on commit 6d7d243

Please sign in to comment.