enhance webui graphics
This commit is contained in:
@@ -30,7 +30,7 @@ type Agent struct {
|
|||||||
currentReasoning string
|
currentReasoning string
|
||||||
currentState *action.StateResult
|
currentState *action.StateResult
|
||||||
nextAction Action
|
nextAction Action
|
||||||
currentConversation []openai.ChatCompletionMessage
|
currentConversation Messages
|
||||||
selfEvaluationInProgress bool
|
selfEvaluationInProgress bool
|
||||||
|
|
||||||
newConversations chan openai.ChatCompletionMessage
|
newConversations chan openai.ChatCompletionMessage
|
||||||
@@ -392,7 +392,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
job.Result.Finish(fmt.Errorf("error renderTemplate: %w", err))
|
job.Result.Finish(fmt.Errorf("error renderTemplate: %w", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !Messages(a.currentConversation).Exist(prompt) {
|
if !a.currentConversation.Exist(prompt) {
|
||||||
a.currentConversation = append([]openai.ChatCompletionMessage{
|
a.currentConversation = append([]openai.ChatCompletionMessage{
|
||||||
{
|
{
|
||||||
Role: "system",
|
Role: "system",
|
||||||
|
|||||||
@@ -3,5 +3,17 @@ package main
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func chatDiv(content string, color string) string {
|
func chatDiv(content string, color string) string {
|
||||||
return fmt.Sprintf(`<div class="p-2 my-2 rounded bg-%s-100">%s</div>`, color, htmlIfy(content))
|
return fmt.Sprintf(`<div class="p-2 my-2 rounded bg-%s-600">%s</div>`, color, htmlIfy(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loader() string {
|
||||||
|
return `<div class="loader"></div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputMessageDisabled(disabled bool) string {
|
||||||
|
if disabled {
|
||||||
|
return `<script> document.getElementById('inputMessage').disabled = true;</script>`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<script> document.getElementById('inputMessage').disabled = false;</script>`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -22,93 +20,73 @@
|
|||||||
.htmx-request .htmx-indicator{
|
.htmx-request .htmx-indicator{
|
||||||
opacity:1
|
opacity:1
|
||||||
}
|
}
|
||||||
/* https://cssloaders.github.io/ */
|
|
||||||
.loader {
|
.loader {
|
||||||
width: 4px;
|
width: 12px;
|
||||||
height: 20px;
|
height: 12px;
|
||||||
border-radius: 4px;
|
border-radius: 50%;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 20px auto;
|
margin:15px auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: currentColor;
|
color: #FFF;
|
||||||
color: #FFF;
|
box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
animation: animloader 2s linear infinite;
|
||||||
animation: animloader 0.3s 0.3s linear infinite alternate;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.loader::after, .loader::before {
|
|
||||||
content: '';
|
|
||||||
width: 4px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: currentColor;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
left: 20px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
animation: animloader 0.3s 0.45s linear infinite alternate;
|
|
||||||
}
|
|
||||||
.loader::before {
|
|
||||||
left: -20px;
|
|
||||||
animation-delay: 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animloader {
|
|
||||||
0% { height: 24px}
|
|
||||||
100% { height: 2px}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% { box-shadow: 14px 0 0 -2px, 38px 0 0 -2px, -14px 0 0 -2px, -38px 0 0 -2px; }
|
||||||
|
25% { box-shadow: 14px 0 0 -2px, 38px 0 0 -2px, -14px 0 0 -2px, -38px 0 0 2px; }
|
||||||
|
50% { box-shadow: 14px 0 0 -2px, 38px 0 0 -2px, -14px 0 0 2px, -38px 0 0 -2px; }
|
||||||
|
75% { box-shadow: 14px 0 0 2px, 38px 0 0 -2px, -14px 0 0 -2px, -38px 0 0 -2px; }
|
||||||
|
100% { box-shadow: 14px 0 0 -2px, 38px 0 0 2px, -14px 0 0 -2px, -38px 0 0 -2px; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-100 p-4">
|
<body class="bg-gray-900 p-4 text-white">
|
||||||
<div class="chat-container bg-white shadow-lg rounded-lg" hx-ext="sse" sse-connect="/sse">
|
<div class="chat-container bg-gray-800 shadow-lg rounded-lg" hx-ext="sse" sse-connect="/sse">
|
||||||
<!-- Chat Header -->
|
<!-- Chat Header -->
|
||||||
<div class="border-b border-gray-200 p-4">
|
<div class="border-b border-gray-700 p-4">
|
||||||
<h1 class="text-lg font-semibold">Talk to '{{.Character.Name}}'</h1>
|
<h1 class="text-lg font-semibold">Talk to '{{.Character.Name}}'</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Chat Messages -->
|
<!-- Chat Messages -->
|
||||||
<div class="chat-messages p-4">
|
<div class="chat-messages p-4">
|
||||||
<!-- Client Box -->
|
<!-- Client Box -->
|
||||||
<div class="bg-gray-100 p-4">
|
<div class="bg-gray-700 p-4">
|
||||||
<h2 class="text-sm font-semibold">Clients:</h2>
|
<h2 class="text-sm font-semibold">Clients:</h2>
|
||||||
<div id="clients" class="text-sm text-gray-700">
|
<div id="clients" class="text-sm text-gray-300">
|
||||||
<!-- Status updates dynamically here -->
|
<!-- Status updates dynamically here -->
|
||||||
<div sse-swap="clients" ></div>
|
<div sse-swap="clients"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- HUD Box -->
|
<!-- HUD Box -->
|
||||||
<div class="bg-gray-100 p-4">
|
<div class="bg-gray-700 p-4">
|
||||||
<h2 class="text-sm font-semibold">Status:</h2>
|
<h2 class="text-sm font-semibold">Status:</h2>
|
||||||
<div id="hud" class="text-sm text-gray-700">
|
<div id="hud" class="text-sm text-gray-300">
|
||||||
<!-- Status updates dynamically here -->
|
<!-- Status updates dynamically here -->
|
||||||
<div sse-swap="hud" ></div>
|
<div sse-swap="hud"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- https://github.com/bigskysoftware/htmx/issues/1882#issuecomment-1783463192 -->
|
<div sse-swap="messages" hx-swap="beforeend" id="messages" hx-on:htmx:after-settle="document.getElementById('messages').scrollIntoView(false)"></div>
|
||||||
<div sse-swap="messages" hx-swap="beforeend" id="messages" hx-on:htmx:after-settle="document.getElementById('messages').scrollIntoView(false)"></div>
|
<div sse-swap="message_status"></div>
|
||||||
<div sse-swap="message_status" ></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Agent Status Box -->
|
<!-- Agent Status Box -->
|
||||||
<div class="bg-gray-100 p-4">
|
<div class="bg-gray-700 p-4">
|
||||||
<h2 class="text-sm font-semibold">Agent:</h2>
|
<h2 class="text-sm font-semibold">Agent:</h2>
|
||||||
<div id="agentStatus" class="text-sm text-gray-700" >
|
<div id="agentStatus" class="text-sm text-gray-300">
|
||||||
<!-- Status updates dynamically here -->
|
<!-- Status updates dynamically here -->
|
||||||
<div sse-swap="status" ></div>
|
<div sse-swap="status" ></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Message Input -->
|
<!-- Message Input -->
|
||||||
<div class="p-4 border-t border-gray-200">
|
<div class="p-4 border-t border-gray-700">
|
||||||
<input id="inputMessage" name="message" type="text" hx-post="/chat" hx-target="#results" hx-indicator=".htmx-indicator"
|
<input id="inputMessage" name="message" type="text" hx-post="/chat" hx-target="#results" hx-indicator=".htmx-indicator"
|
||||||
class="p-2 border rounded w-full" placeholder="Type a message..." _="on htmx:afterRequest set my value to ''">
|
class="p-2 border rounded w-full bg-gray-600 text-white placeholder-gray-300" placeholder="Type a message..." _="on htmx:afterRequest set my value to ''">
|
||||||
<div class="my-2 htmx-indicator" >Loading...</div>
|
<div class="my-2 htmx-indicator" >Loading...</div>
|
||||||
<div id="results" class="flex justify-center"></div>
|
<div id="results" class="flex justify-center"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ func (a *App) Chat(m sse.Manager) func(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
m.Send(
|
m.Send(
|
||||||
sse.NewMessage(
|
sse.NewMessage(
|
||||||
chatDiv(query, "blue"),
|
chatDiv(query, "gray"),
|
||||||
).WithEvent("messages"))
|
).WithEvent("messages"))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -191,11 +191,11 @@ func (a *App) Chat(m sse.Manager) func(w http.ResponseWriter, r *http.Request) {
|
|||||||
fmt.Println("response is", res.Response)
|
fmt.Println("response is", res.Response)
|
||||||
m.Send(
|
m.Send(
|
||||||
sse.NewMessage(
|
sse.NewMessage(
|
||||||
chatDiv(res.Response, "red"),
|
chatDiv(res.Response, "blue"),
|
||||||
).WithEvent("messages"))
|
).WithEvent("messages"))
|
||||||
m.Send(
|
m.Send(
|
||||||
sse.NewMessage(
|
sse.NewMessage(
|
||||||
"<script> document.getElementById('inputMessage').disabled = false;</script>",
|
inputMessageDisabled(false), // show again the input
|
||||||
).WithEvent("message_status"))
|
).WithEvent("message_status"))
|
||||||
|
|
||||||
//result := `<i>done</i>`
|
//result := `<i>done</i>`
|
||||||
@@ -204,7 +204,7 @@ func (a *App) Chat(m sse.Manager) func(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
m.Send(
|
m.Send(
|
||||||
sse.NewMessage(
|
sse.NewMessage(
|
||||||
`<div class="p-2 my-2 rounded bg-gray-100"><span class="loader"></span></div><script> document.getElementById('inputMessage').disabled = true;</script>`,
|
loader() + inputMessageDisabled(true),
|
||||||
).WithEvent("message_status"))
|
).WithEvent("message_status"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user