Add reset, some minor UX tweaks
This commit is contained in:
3
Makefile
3
Makefile
@@ -4,6 +4,9 @@ IMAGE_NAME?=webui
|
||||
tests:
|
||||
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --fail-fast -v -r ./...
|
||||
|
||||
webui-nokb:
|
||||
$(MAKE) webui KBDISABLEINDEX=true
|
||||
|
||||
webui:
|
||||
cd example/webui && $(GOCMD) run ./
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ type Agent struct {
|
||||
|
||||
type RAGDB interface {
|
||||
Store(s string) error
|
||||
Reset() error
|
||||
Search(s string, similarEntries int) ([]string, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,13 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func (a *App) KnowledgeBaseReset(db *InMemoryDatabase) func(c *fiber.Ctx) error {
|
||||
return func(c *fiber.Ctx) error {
|
||||
db.Reset()
|
||||
return c.Redirect("/knowledgebase")
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) KnowledgeBaseFile(db *InMemoryDatabase) func(c *fiber.Ctx) error {
|
||||
return func(c *fiber.Ctx) error {
|
||||
// https://golang.withcodeexample.com/blog/file-upload-handling-golang-fiber-guide/
|
||||
|
||||
@@ -74,6 +74,17 @@ func (db *InMemoryDatabase) SaveToStore() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *InMemoryDatabase) Reset() error {
|
||||
db.Lock()
|
||||
db.Database = []string{}
|
||||
db.Unlock()
|
||||
if err := db.rag.Reset(); err != nil {
|
||||
return err
|
||||
}
|
||||
return db.SaveDB()
|
||||
}
|
||||
|
||||
func (db *InMemoryDatabase) AddEntry(entry string) error {
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
|
||||
@@ -58,8 +58,10 @@ func RegisterRoutes(webapp *fiber.App, pool *AgentPool, db *InMemoryDatabase, ap
|
||||
webapp.Post("/chat/:name", app.Chat(pool))
|
||||
webapp.Post("/create", app.Create(pool))
|
||||
webapp.Get("/delete/:name", app.Delete(pool))
|
||||
|
||||
webapp.Post("/knowledgebase", app.KnowledgeBase(db))
|
||||
webapp.Post("/knowledgebase/upload", app.KnowledgeBaseFile(db))
|
||||
webapp.Delete("/knowledgebase/reset", app.KnowledgeBaseReset(db))
|
||||
|
||||
webapp.Get("/talk/:name", func(c *fiber.Ctx) error {
|
||||
return c.Render("views/chat", fiber.Map{
|
||||
|
||||
@@ -3,24 +3,70 @@
|
||||
<head>
|
||||
<title>Smart Assistant Dashboard</title>
|
||||
{{template "views/partials/header"}}
|
||||
<style>
|
||||
.container {
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.card-link {
|
||||
text-decoration: none; /* Removes underline from links */
|
||||
}
|
||||
.card {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px auto;
|
||||
text-align: left;
|
||||
width: 90%;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease; /* Smooth transition for hover effects */
|
||||
display: block; /* Ensures the link fills the card */
|
||||
}
|
||||
.card:hover {
|
||||
transform: translateY(-5px); /* Slight lift effect */
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); /* Shadow for depth */
|
||||
}
|
||||
.card h2 {
|
||||
font-size: 1.5em; /* Larger and more prominent */
|
||||
font-weight: bold; /* Ensures boldness */
|
||||
color: white; /* Ensures visibility against the card's background */
|
||||
margin-bottom: 0.5em; /* Space below the heading */
|
||||
}
|
||||
.card a,
|
||||
.card p {
|
||||
color: white; /* Ensures text color is consistent */
|
||||
}
|
||||
.card p {
|
||||
font-size: 1em;
|
||||
}
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-900 p-4 text-white font-sans">
|
||||
{{template "views/partials/menu"}}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<header class="text-center mb-8">
|
||||
<h1 class="text-3xl md:text-5xl font-bold">Smart Agent Dashboard</h1>
|
||||
</header>
|
||||
<div class="flex flex-col items-center space-y-4">
|
||||
<img class="flex" src="/public/logo_1.png" width="250">
|
||||
<!-- Button to Agent List Page -->
|
||||
<a href="/agents" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||
Agent List
|
||||
<div class="container">
|
||||
<div class="image-container">
|
||||
<img src="/public/logo_1.png" width="250" alt="Company Logo">
|
||||
</div>
|
||||
<!-- Card for Agent List Page -->
|
||||
<a href="/agents" class="card-link">
|
||||
<div class="card">
|
||||
<h2>Agent List</h2>
|
||||
<p>View and manage your list of agents, including detailed profiles and statistics.</p>
|
||||
</div>
|
||||
</a>
|
||||
<!-- Button to Knowledgebase Management Page -->
|
||||
<a href="/knowledgebase" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
|
||||
Manage Knowledgebase
|
||||
<!-- Card for Knowledgebase Management Page -->
|
||||
<a href="/knowledgebase" class="card-link">
|
||||
<div class="card">
|
||||
<h2>Manage Knowledgebase</h2>
|
||||
<p>Access and update your knowledgebase to improve agent responses and efficiency.</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,55 +6,86 @@
|
||||
<script src="https://unpkg.com/htmx.org"></script>
|
||||
<script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>
|
||||
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
|
||||
<style>
|
||||
.section-box {
|
||||
background-color: #2a2a2a; /* Darker background for the form */
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #1a1a1a; /* Lighter overall background */
|
||||
color: #ffffff;
|
||||
font-family: sans-serif;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
input, button {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-top: 5px;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
input[type="text"], input[type="file"] {
|
||||
background-color: #333333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #4a76a8; /* Blue color for buttons */
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #5a86b8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-900 p-4 text-white font-sans">
|
||||
<body>
|
||||
{{template "views/partials/menu"}}
|
||||
<header class="text-center mb-8">
|
||||
<h1 class="text-3xl md:text-5xl font-bold">Knowledgebase (items: {{.KnowledgebaseItemsCount}})</h1>
|
||||
</header>
|
||||
<div class="max-w-2xl mx-auto my-12 bg-gray-800 p-8 rounded-lg shadow-lg">
|
||||
<form action="/knowledgebase" method="POST" class="space-y-6">
|
||||
Add sites to KB
|
||||
<div class="mb-6">
|
||||
<label for="url" class="block text-lg font-medium text-gray-400">URL</label>
|
||||
<input type="text" name="url" id="url" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-lg border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Name">
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="chunk_size" class="block text-lg font-medium text-gray-400">Chunk size</label>
|
||||
<input type="text" name="chunk_size" id="chunk_size" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-lg border-gray-300 rounded-md bg-gray-700 text-white" placeholder="380">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-500 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||
Add Site
|
||||
</button>
|
||||
</div>
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<!-- Add Site Form -->
|
||||
<div class="section-box">
|
||||
<form action="/knowledgebase" method="POST">
|
||||
<h2>Add sites to KB</h2>
|
||||
<label for="url">URL:</label>
|
||||
<input type="text" name="url" id="url" placeholder="Enter URL here">
|
||||
<label for="chunk_size">Chunk size:</label>
|
||||
<input type="text" name="chunk_size" id="chunk_size" placeholder="Enter chunk size here">
|
||||
<button type="submit">Add Site</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- File Upload Form -->
|
||||
<div class="section-box">
|
||||
<form id='form' hx-encoding='multipart/form-data' hx-post='/knowledgebase/upload'>
|
||||
<div class="mb-6">
|
||||
<label for="file" class="block text-lg font-medium text-gray-400">File</label>
|
||||
<input type='file' name='file' id='file' class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-lg border-gray-300 rounded-md bg-gray-700 text-white">
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="chunk_size" class="block text-lg font-medium text-gray-400">Chunk size</label>
|
||||
<input type="text" name="chunk_size" id="chunk_size" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-lg border-gray-300 rounded-md bg-gray-700 text-white" placeholder="380">
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-500 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||
Upload file
|
||||
</button>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<h2>Upload File</h2>
|
||||
<label for="file">File:</label>
|
||||
<input type='file' name='file' id='file'>
|
||||
<label for="chunk_size">Chunk size:</label>
|
||||
<input type="text" name="chunk_size" id="chunk_size" placeholder="Enter chunk size here">
|
||||
<button type="submit">Upload File</button>
|
||||
<progress id='progress' value='0' max='100'></progress>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Reset Knowledge Base -->
|
||||
<div class="section-box">
|
||||
<button hx-swap="none" hx-trigger="click" hx-delete="/knowledgebase/reset">Reset Knowledge Base</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
htmx.on('#form', 'htmx:xhr:progress', function(evt) {
|
||||
htmx.find('#progress').setAttribute('value', evt.detail.loaded/evt.detail.total * 100)
|
||||
htmx.find('#progress').setAttribute('value', evt.detail.loaded / evt.detail.total * 100);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex">
|
||||
<!-- Logo container -->
|
||||
<div class="flex-shrink-0 flex items-center">
|
||||
<!-- Replace 'logo.png' with the actual path to your logo image -->
|
||||
<a href="/" >
|
||||
<img src="/public/logo_1.png" alt="Logo" class="h-8 w-auto mr-3">
|
||||
</a>
|
||||
<a href="/" class="px-3 py-2 rounded-md text-sm font-medium text-white bg-gray-900 focus:outline-none focus:text-white focus:bg-gray-700">
|
||||
<i class="fas fa-home"></i> Home
|
||||
<i class="fas fa-home"></i> LocalAgent
|
||||
</a>
|
||||
<a href="/agents" class="px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">
|
||||
<i class="fas fa-users"></i> Agent list
|
||||
|
||||
@@ -13,6 +13,8 @@ type ChromemDB struct {
|
||||
collectionName string
|
||||
collection *chromem.Collection
|
||||
index int
|
||||
client *openai.Client
|
||||
db *chromem.DB
|
||||
}
|
||||
|
||||
func NewChromemDB(collection, path string, openaiClient *openai.Client) (*ChromemDB, error) {
|
||||
@@ -22,9 +24,39 @@ func NewChromemDB(collection, path string, openaiClient *openai.Client) (*Chrome
|
||||
// }
|
||||
db := chromem.NewDB()
|
||||
|
||||
embeddingFunc := chromem.EmbeddingFunc(
|
||||
chromem := &ChromemDB{
|
||||
collectionName: collection,
|
||||
index: 1,
|
||||
db: db,
|
||||
client: openaiClient,
|
||||
}
|
||||
|
||||
c, err := db.GetOrCreateCollection(collection, nil, chromem.embedding())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chromem.collection = c
|
||||
|
||||
return chromem, nil
|
||||
}
|
||||
|
||||
func (c *ChromemDB) Reset() error {
|
||||
if err := c.db.DeleteCollection(c.collectionName); err != nil {
|
||||
return err
|
||||
}
|
||||
collection, err := c.db.GetOrCreateCollection(c.collectionName, nil, c.embedding())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.collection = collection
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ChromemDB) embedding() chromem.EmbeddingFunc {
|
||||
return chromem.EmbeddingFunc(
|
||||
func(ctx context.Context, text string) ([]float32, error) {
|
||||
resp, err := openaiClient.CreateEmbeddings(ctx,
|
||||
resp, err := c.client.CreateEmbeddings(ctx,
|
||||
openai.EmbeddingRequestStrings{
|
||||
Input: []string{text},
|
||||
Model: openai.AdaEmbeddingV2,
|
||||
@@ -43,17 +75,6 @@ func NewChromemDB(collection, path string, openaiClient *openai.Client) (*Chrome
|
||||
return embedding, nil
|
||||
},
|
||||
)
|
||||
|
||||
c, err := db.GetOrCreateCollection(collection, nil, embeddingFunc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ChromemDB{
|
||||
collectionName: collection,
|
||||
collection: c,
|
||||
index: 1,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ChromemDB) Store(s string) error {
|
||||
|
||||
@@ -19,6 +19,10 @@ func NewLocalAIRAGDB(storeClient *StoreClient, openaiClient *openai.Client) *Loc
|
||||
}
|
||||
}
|
||||
|
||||
func (db *LocalAIRAGDB) Reset() error {
|
||||
return fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (db *LocalAIRAGDB) Store(s string) error {
|
||||
resp, err := db.openaiClient.CreateEmbeddings(context.TODO(),
|
||||
openai.EmbeddingRequestStrings{
|
||||
|
||||
Reference in New Issue
Block a user