Skip to content

Commit

Permalink
Bedrock Blazor sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
guitarrapc committed Mar 18, 2024
1 parent 10c3884 commit 85a2a3e
Show file tree
Hide file tree
Showing 16 changed files with 494 additions and 1 deletion.
9 changes: 8 additions & 1 deletion Claudia.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Claudia.FunctionGenerator.T
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockConsoleApp", "sandbox\BedrockConsoleApp\BedrockConsoleApp.csproj", "{79C84272-E0AB-4918-9454-B0AEA9CBE40A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Claudia.Bedrock", "src\Claudia.Bedrock\Claudia.Bedrock.csproj", "{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Claudia.Bedrock", "src\Claudia.Bedrock\Claudia.Bedrock.csproj", "{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockBlazorApp1", "sandbox\BedrockBlazorApp1\BedrockBlazorApp1.csproj", "{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -63,6 +65,10 @@ Global
{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA}.Release|Any CPU.Build.0 = Release|Any CPU
{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -76,6 +82,7 @@ Global
{89A58A08-F553-4CEA-A2A8-783009501E05} = {1B4BD6F6-8528-4409-BA55-085DA5486D36}
{79C84272-E0AB-4918-9454-B0AEA9CBE40A} = {E61BFC87-2B96-4699-9B69-EE4B008AE0A0}
{9EC270A6-6E6F-44CF-8A4C-975A2A7344AA} = {B54A8855-F8F0-4015-80AA-86974E65AC2D}
{81ED7CB8-1357-4D6E-A54F-4BB07955EFD5} = {E61BFC87-2B96-4699-9B69-EE4B008AE0A0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B7CEBA02-BB0C-4102-AE58-DFD114C3192A}
Expand Down
21 changes: 21 additions & 0 deletions sandbox/BedrockBlazorApp1/BedrockBlazorApp1.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<UserSecretsId>ce2f09c8-e783-4af2-b9f1-8226c422040c</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.BedrockRuntime" Version="3.7.301.47" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.300.59" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Claudia.Bedrock\Claudia.Bedrock.csproj" />
<ProjectReference Include="..\..\src\Claudia\Claudia.csproj" />
</ItemGroup>

</Project>
34 changes: 34 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BedrockBlazorApp1.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />

@*Using latest tailwind?*@
<script src="https://cdn.tailwindcss.com/3.0.18"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
clifford: '#da373d',
}
}
}
}
</script>
<script src="https://cdn.tailwindcss.com/[email protected],[email protected],[email protected],[email protected]"></script>
<HeadOutlet />
</head>

<body class="bg-gray-100 h-screen flex flex-col">
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>

</html>
11 changes: 11 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@inherits LayoutComponentBase

<main>
@Body
</main>

<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
96 changes: 96 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/Layout/MainLayout.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}

#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
36 changes: 36 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/Pages/Error.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics

<PageTitle>Error</PageTitle>

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

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

<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more 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>

@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }

private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}
95 changes: 95 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/Pages/Home.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
@page "/"
@using Claudia
@rendermode InteractiveServer

<PageTitle>Blazor Claude</PageTitle>

<div class="flex flex-col relative h-full w-full overflow-auto transition-width">

<div class="flex-0 text-base font-bold mt-4 text-center">Blazor Claude</div>

<div class="flex-1 text-sm p-4">
<div class="p-4 h-full border bg-white rounded-md overflow-y-auto">
@foreach (var item in chatMessages)
{
@if (item.Role == Roles.User)
{
<div class="mb-2">
<span class="font-bold text-blue-500">User:</span> @((MarkupString)item.Content[0].Text!.Replace("\n", "<br />"))
</div>
}
else
{
<div class="mb-2">
<span class="font-bold text-green-500">Assistant:</span> @((MarkupString)item.Content[0].Text!.Replace("\n", "<br />"))
</div>
}
}
</div>
</div>

<div class="flex-0 bg-white p-2 border-t-2">
<div class="flex w-full mb-2">
<div class="flex-0 mr-2 relative">
<div class="block text-sm font-medium leading-6 text-gray-900">Temperature</div>
<input onmouseover="" class="range_slider w-full h-1 mb-6 bg-gray-200 rounded-lg appearance-none cursor-pointer range-sm dark:bg-gray-700" type="range" min="0.0" max="1.0" step=0.1 value=@temperature>
<span class="range_bubble">@temperature</span>
</div>
<div class="flex-1">
<div class="block text-sm font-medium leading-6 text-gray-900">System</div>
<textarea type="text" class="block w-full rounded-md border-0 py-1.5 text-sm leading-6 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600"
@bind="systemInput" />
</div>
</div>
<div class="w-full">
<form class="flex" @onsubmit=SendClick>
<input type="text" id="chat-input" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 text-sm leading-6" placeholder=" Enter Message..." autocomplete="off" @bind="textInput">
<button class="ml-2 mt-0 w-auto inline-flex items-center justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" disabled="@running">Send</button>
</form>
</div>
</div>
</div>


<style>
button:disabled {
background-color: rgb(179 179 179);
}
.range_bubble {
background-color: #333;
color: #fff;
position: absolute;
bottom: 0px;
left: 0px;
padding: 2px 6px;
border-radius: 3px;
z-index: 10;
display: none;
}
</style>

<script>
var rangeInput = document.querySelector(".range_slider");
var rangeBubble = document.querySelector(".range_bubble");
rangeInput.addEventListener("input", () => {
setBubble(rangeInput, rangeBubble);
});
rangeInput.addEventListener("mouseover", () => {
setBubble(rangeInput, rangeBubble);
});
rangeInput.addEventListener("mouseleave", () => {
rangeBubble.style.display = "none";
});
function setBubble(range, bubble) {
var val = range.value;
var min = range.min ? range.min : 0;
var max = range.max ? range.max : 100;
var newVal = Number(((val - min) * 100) / (max - min));
bubble.innerHTML = val;
bubble.style.left = `calc(${newVal}% + (${-5 - newVal * 0.15}px))`;
rangeBubble.style.display = "inline-block";
}
</script>
67 changes: 67 additions & 0 deletions sandbox/BedrockBlazorApp1/Components/Pages/Home.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Amazon.BedrockRuntime;
using Claudia;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using System.Text.Json;

namespace BedrockBlazorApp1.Components.Pages;

public partial class Home
{
[Inject]
public AmazonBedrockRuntimeClient BedrockClient { get; init; }
private BedrockAnthropicClient anthropic;

Check warning on line 13 in sandbox/BedrockBlazorApp1/Components/Pages/Home.razor.cs

View workflow job for this annotation

GitHub Actions / build-dotnet

Non-nullable field 'anthropic' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

double temperature = 1.0;
string textInput = "";
string systemInput = SystemPrompts.Claude3;
List<Message> chatMessages = new();

bool running = false;

protected override void OnInitialized()
{
anthropic = BedrockClient.UseAnthropic("anthropic.claude-3-haiku-20240307-v1:0");
base.OnInitialized();
}

async Task SendClick()
{
if (running) return;
if (string.IsNullOrWhiteSpace(textInput)) return;

running = true;
try
{
chatMessages.Add(new() { Role = Roles.User, Content = textInput });

var stream = anthropic.Messages.CreateStreamAsync(new()
{
Model = "bedrock-2023-05-31",
MaxTokens = 1024,
Temperature = temperature,
System = string.IsNullOrWhiteSpace(systemInput) ? null : systemInput,
Messages = chatMessages.ToArray()
});

var currentMessage = new Message { Role = Roles.Assistant, Content = "" };
chatMessages.Add(currentMessage);

textInput = ""; // clear input.
StateHasChanged();

await foreach (var messageStreamEvent in stream)
{
if (messageStreamEvent is ContentBlockDelta content)
{
currentMessage.Content[0].Text += content.Delta.Text;
StateHasChanged();
}
}
}
finally
{
running = false;
}
}
}
Loading

0 comments on commit 85a2a3e

Please sign in to comment.