-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from edgett/rag
New features: Upload docs. Chat with docs. Persist settings to local storage. Code improvements.
- Loading branch information
Showing
69 changed files
with
2,801 additions
and
745 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using PalmHill.BlazorChat.ApiClient.WebApiInterface; | ||
using Refit; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace PalmHill.BlazorChat.ApiClient | ||
{ | ||
public class BlazorChatApi | ||
{ | ||
public BlazorChatApi(HttpClient httpClient) | ||
{ | ||
HttpClient = httpClient; | ||
Attachment = RestService.For<IAttachment>(httpClient); | ||
Chat = RestService.For<IChat>(httpClient); | ||
} | ||
|
||
public HttpClient HttpClient { get; } | ||
public IAttachment Attachment { get; } | ||
public IChat Chat { get; } | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
PalmHill.BlazorChat.ApiClient/PalmHill.BlazorChat.ApiClient.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Refit" Version="7.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\PalmHill.BlazorChat\Shared\PalmHill.BlazorChat.Shared.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# PalmHill.BlazorChat.ApiClient | ||
|
||
This project is a .NET 8.0 library that provides an API client for the PalmHill Blazor Chat application. It uses the Refit library for HTTP communication. | ||
|
||
## Dependencies | ||
- .NET 8.0 | ||
- Refit 7.0.0 | ||
|
||
## Project References | ||
- PalmHill.BlazorChat.Shared | ||
|
||
## API Interface | ||
The API client provides an interface to interact with the chat API. The interface is defined in the `IChat` interface. | ||
|
||
### Methods | ||
- `Chat(InferenceRequest conversation)`: This method sends a chat message to the server and returns the server's response as a string. The chat message is encapsulated in an `InferenceRequest` object. | ||
- `Ask(InferenceRequest chatConversation)`: This method sends a chat message to the server and returns the server's response as a `ChatMessage` object. The chat message is encapsulated in an `InferenceRequest` object. | ||
- `CancelChat(Guid conversationId)`: This method sends a request to the server to cancel a chat conversation. The ID of the conversation to be cancelled is passed as a parameter. | ||
|
||
### BlazorChatApi.cs | ||
The `BlazorChatApi.cs` file contains the `BlazorChatApi` class, which is the main entry point for using the API client. It provides a convenient way to access the interface and its methods. | ||
|
||
The `BlazorChatApi` class has a constructor that takes a `HttpClient` object. This `HttpClient` object is used by the Refit library to make HTTP requests. | ||
|
||
The `BlazorChatApi` implments the interfaces by using Refit. | ||
|
||
## Usage | ||
To use this library, add a reference to it in your project and create an instance of the `IChat` interface using Refit's `RestService` class. Then, you can call the methods defined in the `IChat` interface. | ||
|
||
```csharp | ||
var httpClient = new HttpClient { BaseAddress = new Uri("https://api.example.com") }; | ||
var blazorChatApi = new BlazorChatApi(httpClient); | ||
var response = await blazorChatApi.Chat.Chat(new InferenceRequest { /* ... */ }); | ||
``` | ||
|
||
Note: This library is not yet available on NuGet. |
22 changes: 22 additions & 0 deletions
22
PalmHill.BlazorChat.ApiClient/WebApiInterface/IAttachment.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using PalmHill.BlazorChat.Shared.Models; | ||
using Refit; | ||
|
||
|
||
namespace PalmHill.BlazorChat.ApiClient.WebApiInterface | ||
{ | ||
public interface IAttachment | ||
{ | ||
[Get("/api/Attachment/list/{conversationId}")] | ||
Task<IEnumerable<AttachmentInfo>> GetAttachments(string conversationId); | ||
|
||
[Get("/api/Attachment/{attachmentId}")] | ||
Task<ApiResponse<AttachmentInfo>> GetAttachmentById(string attachmentId); | ||
|
||
[Multipart] | ||
[Post("/api/Attachment/{conversationId}/{attachmentId}")] | ||
Task<ApiResponse<AttachmentInfo>> AddAttachment(Guid conversationId, Guid attachmentId, [AliasAs("file")] StreamPart file); | ||
|
||
[Delete("/api/Attachment/{attachmentId}")] | ||
Task<ApiResponse<bool>> DeleteAttachment(Guid attachmentId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using Refit; | ||
using PalmHill.BlazorChat.Shared.Models; | ||
|
||
|
||
namespace PalmHill.BlazorChat.ApiClient.WebApiInterface | ||
{ | ||
public interface IChat | ||
{ | ||
[Post("/api/chat")] | ||
Task<ApiResponse<string>> Chat(InferenceRequest conversation); | ||
|
||
[Post("/api/chat/docs")] | ||
Task<ApiResponse<ChatMessage>> Ask(InferenceRequest chatConversation); | ||
|
||
[Delete("/api/chat/cancel/{conversationId}")] | ||
public Task<ApiResponse<bool>> CancelChat(Guid conversationId); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
PalmHill.BlazorChat/Client/Components/Attachment/AttachmentItemDisplay.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
@using PalmHill.BlazorChat.ApiClient | ||
@using PalmHill.BlazorChat.Shared.Models | ||
@inject BlazorChatApi BlazorChatApi | ||
|
||
@if (Attachment != null) | ||
{ | ||
<FluentPresenceBadge Style="width:100%;" Status="_presenceStatus" StatusTitle="@_presenceLabel"> | ||
<FluentCard Style="width:100%; padding:3px 3px" > | ||
<div> | ||
@Attachment.Name | ||
</div> | ||
<FluentButton IconStart="@(new Icons.Regular.Size16.Delete())" | ||
Loading="@_deleteInProgress" | ||
OnClick="@_deleteAttachment" | ||
Title="Delete"> | ||
</FluentButton> | ||
</FluentCard> | ||
</FluentPresenceBadge> | ||
} | ||
|
||
|
||
@code { | ||
/// <summary> | ||
/// The <see cref="AttachmentInfo"/> to display | ||
/// </summary> | ||
[Parameter] | ||
public AttachmentInfo? Attachment { get; set; } | ||
|
||
/// <summary> | ||
/// The <see cref="EventCallback"/> to invoke when the attachment is deleted. | ||
/// The event handler will remove the attachment from the list. | ||
/// </summary> | ||
[Parameter] | ||
public EventCallback<AttachmentInfo> OnFileDeleted { get; set; } | ||
|
||
private bool _deleteInProgress = false; | ||
|
||
/// <summary> | ||
/// Deletes the attachment by calling the api. | ||
/// </summary> | ||
/// <returns></returns> | ||
private async Task _deleteAttachment() | ||
{ | ||
if(Attachment == null) | ||
{ | ||
return; | ||
} | ||
|
||
_deleteInProgress = true; | ||
try | ||
{ | ||
var apiResponse = await BlazorChatApi.Attachment.DeleteAttachment(Attachment.Id); | ||
|
||
if (!apiResponse.IsSuccessStatusCode ) | ||
{ | ||
throw new Exception($"Failed to delete attachment. {apiResponse.StatusCode} {apiResponse.ReasonPhrase}"); | ||
} | ||
|
||
if (!apiResponse.Content) | ||
{ | ||
throw new Exception($"Failed to delete attachment. {apiResponse.StatusCode} {apiResponse.ReasonPhrase}"); | ||
} | ||
|
||
if (apiResponse.IsSuccessStatusCode) | ||
{ //Only invoke when the delete was successful. | ||
//The event handler will remove the attachment from the list. | ||
await OnFileDeleted.InvokeAsync(Attachment); | ||
} | ||
|
||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"{ex}"); | ||
} | ||
_deleteInProgress = false; | ||
} | ||
|
||
/// <summary> | ||
/// The <see cref="PresenceStatus"/> to display on the attachment. | ||
/// </summary> | ||
private PresenceStatus _presenceStatus | ||
{ | ||
get | ||
{ | ||
if (Attachment == null) | ||
{ | ||
return PresenceStatus.Busy; | ||
|
||
} | ||
|
||
var presenceStatus = Attachment.Status switch | ||
{ | ||
AttachmentStatus.Pending => PresenceStatus.Away, | ||
AttachmentStatus.Uploaded => PresenceStatus.Available, | ||
AttachmentStatus.Failed => PresenceStatus.Busy, | ||
_ => PresenceStatus.Busy | ||
}; | ||
|
||
return presenceStatus; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// The tooltip text to display for the attachment. | ||
/// </summary> | ||
private string _presenceLabel | ||
{ | ||
get | ||
{ | ||
if (Attachment == null) | ||
{ | ||
return ""; | ||
|
||
} | ||
|
||
var presenceStatus = Attachment.Status switch | ||
{ | ||
AttachmentStatus.Pending => "Pending", | ||
AttachmentStatus.Uploaded => "Ready", | ||
AttachmentStatus.Failed => "Failed", | ||
_ => "Failed" | ||
}; | ||
|
||
return presenceStatus; | ||
} | ||
} | ||
|
||
|
||
} |
22 changes: 22 additions & 0 deletions
22
PalmHill.BlazorChat/Client/Components/Attachment/AttachmentList.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@if (Controller!.UploadedFiles.Any()) | ||
{ | ||
<div style="padding:3px 3px;"> | ||
@foreach (var file in Controller.UploadedFiles) | ||
{ | ||
<AttachmentItemDisplay OnFileDeleted="_fileDeletedHandler" Attachment="file"></AttachmentItemDisplay> | ||
} | ||
</div> | ||
} | ||
@code { | ||
[Parameter] | ||
public ChatService? Controller { get; set; } | ||
|
||
/// <summary> | ||
/// Removes the deleted attachment from the <see cref="Controller"/>'s UploadedFiles list. | ||
/// </summary> | ||
/// <param name="deletedAttachment">The deleted <see cref="AttachmentInfo"></param> | ||
private void _fileDeletedHandler(AttachmentInfo deletedAttachment) | ||
{ | ||
Controller!.UploadedFiles.Remove(deletedAttachment); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
PalmHill.BlazorChat/Client/Components/Attachment/AttachmentManager.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
@using Microsoft.AspNetCore.Components.Forms | ||
@using Refit | ||
@inject BlazorChatApi BlazorChatApi; | ||
<InfoPanel IsOpen="Controller!.AttachmentsVisible" Title="Attachments"> | ||
<FluentSwitch | ||
|
||
@bind-Value="Controller!.AttachmentsEnabled" | ||
Label="Enable"></FluentSwitch> | ||
|
||
<FileInput Controller="Controller" OnInputFileChange="_uploadFiles"> | ||
</FileInput> | ||
|
||
<AttachmentList Controller="Controller"> | ||
</AttachmentList> | ||
</InfoPanel> | ||
|
||
@code { | ||
|
||
[Parameter] | ||
public ChatService? Controller { get; set; } | ||
|
||
/// <summary> | ||
/// Uploads files to the server when the user selects them. | ||
/// Adds to the <see cref="Controller"/>'s UploadedFiles list. | ||
/// </summary> | ||
/// <param name="e">The selected files.</param> | ||
private async Task _uploadFiles(InputFileChangeEventArgs e) | ||
{ | ||
|
||
var files = e.GetMultipleFiles(); | ||
var uploadedCount = 0; | ||
var uploadTasks = new List<Task>(); | ||
|
||
foreach (var file in files) | ||
{ | ||
var attachmentInfo = new AttachmentInfo(); | ||
attachmentInfo.ConversationId = Controller?.WebSocketChatConnection?.ConversationId; | ||
attachmentInfo.Name = file.Name; | ||
attachmentInfo.Size = file.Size; | ||
attachmentInfo.ContentType = file.ContentType; | ||
attachmentInfo.Status = AttachmentStatus.Pending; | ||
|
||
Controller!.UploadedFiles.Add(attachmentInfo); | ||
|
||
var uploadTask = new Task(async () => | ||
{ | ||
if (attachmentInfo?.ConversationId is null) | ||
{ | ||
attachmentInfo!.Status = AttachmentStatus.Failed; | ||
return; | ||
} | ||
|
||
var stream = file.OpenReadStream(10000000); | ||
var streamPart = new StreamPart(stream, file.Name, file.ContentType); | ||
var apiResponse = await BlazorChatApi.Attachment.AddAttachment(attachmentInfo.ConversationId.Value, attachmentInfo.Id, streamPart); | ||
uploadedCount++; | ||
|
||
if (!apiResponse.IsSuccessStatusCode) | ||
{ | ||
attachmentInfo.Status = AttachmentStatus.Failed; | ||
} | ||
}); | ||
|
||
uploadTasks.Add(uploadTask); | ||
} | ||
|
||
foreach (var uploadTask in uploadTasks) | ||
{ | ||
uploadTask.Start(); | ||
await uploadTask; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.