basic ui
This commit is contained in:
parent
1a0bdce02d
commit
0e7d284f09
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
21
main.go
21
main.go
|
|
@ -5,12 +5,12 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
|
@ -230,6 +230,17 @@ func renderPrompt(tmplStr string, data any) (string, error) {
|
|||
return buf.String(), nil
|
||||
}
|
||||
|
||||
var uiTemplate *template.Template
|
||||
|
||||
func loadUITemplate(path string) error {
|
||||
tmpl, err := template.ParseFiles(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uiTemplate = tmpl
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := loadConfig("config.yaml"); err != nil {
|
||||
log.Fatalf("Failed to load config.yaml: %v", err)
|
||||
|
|
@ -239,12 +250,18 @@ func main() {
|
|||
log.Fatalf("Failed to load db.yaml: %v", err)
|
||||
}
|
||||
fmt.Printf("Loaded %d reasons from db.yaml\n", len(reasonsDB))
|
||||
|
||||
if err := loadUITemplate("ui.html"); err != nil {
|
||||
log.Fatalf("Failed to load ui.html: %v", err)
|
||||
}
|
||||
llm := &LLMClient{
|
||||
APIKey: os.Getenv("OPENAI_API_KEY"),
|
||||
BaseURL: os.Getenv("OPENAI_BASE_URL"), // e.g. http://localhost:1234/v1/completions
|
||||
}
|
||||
r := gin.Default()
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
c.Status(200)
|
||||
uiTemplate.Execute(c.Writer, nil)
|
||||
})
|
||||
r.POST("/chat", func(c *gin.Context) {
|
||||
var req ChatRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Vet Clinic Chat Assistant</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; margin: 2em; }
|
||||
#chatbox { width: 100%; max-width: 600px; margin: 0 auto; }
|
||||
#messages { border: 1px solid #ccc; min-height: 120px; padding: 1em; margin-bottom: 1em; background: #fafafa; }
|
||||
.msg-user { color: #333; }
|
||||
.msg-bot { color: #007a3d; margin-bottom: 1em; }
|
||||
#input { width: 80%; padding: 0.5em; }
|
||||
#send { padding: 0.5em 1em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="chatbox">
|
||||
<h2>Vet Clinic Chat Assistant</h2>
|
||||
<div id="messages"></div>
|
||||
<input id="input" type="text" placeholder="Type your message..." autofocus />
|
||||
<button id="send">Send</button>
|
||||
</div>
|
||||
<script>
|
||||
const messages = document.getElementById('messages');
|
||||
const input = document.getElementById('input');
|
||||
const send = document.getElementById('send');
|
||||
function appendMsg(text, who) {
|
||||
const div = document.createElement('div');
|
||||
div.className = who === 'user' ? 'msg-user' : 'msg-bot';
|
||||
div.textContent = text;
|
||||
messages.appendChild(div);
|
||||
messages.scrollTop = messages.scrollHeight;
|
||||
}
|
||||
send.onclick = async function() {
|
||||
const msg = input.value.trim();
|
||||
if (!msg) return;
|
||||
appendMsg(msg, 'user');
|
||||
input.value = '';
|
||||
appendMsg('Thinking...', 'bot');
|
||||
const resp = await fetch('/chat', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message: msg })
|
||||
});
|
||||
const data = await resp.json();
|
||||
messages.lastChild.remove(); // remove 'Thinking...'
|
||||
if (data.match) {
|
||||
var txt = "Match: " + data.match + "\n";
|
||||
if (data.procedures) {
|
||||
txt += "Procedures:\n";
|
||||
data.procedures.forEach(function(p) {
|
||||
txt += "- " + p.name + ": " + p.price + " Ft, " + p.duration_minutes + " perc\n";
|
||||
});
|
||||
}
|
||||
if (data.total_price) txt += "Total: " + data.total_price + " Ft\n";
|
||||
if (data.total_duration) txt += "Total duration: " + data.total_duration + " perc\n";
|
||||
if (data.notes) txt += "Notes: " + data.notes + "\n";
|
||||
appendMsg(txt, 'bot');
|
||||
} else {
|
||||
appendMsg('Sorry, no match found. Your message will be sent to the vet.', 'bot');
|
||||
}
|
||||
};
|
||||
input.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') send.onclick();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue