Improve page style
This commit is contained in:
@@ -6,93 +6,133 @@
|
||||
<title>Agent List</title>
|
||||
{{template "views/partials/header"}}
|
||||
</head>
|
||||
<body class="bg-gray-900 p-4 text-white font-sans">
|
||||
<body>
|
||||
{{template "views/partials/menu"}}
|
||||
|
||||
<!-- Toast for notifications -->
|
||||
<div id="toast" class="toast">
|
||||
<span id="toast-message"></span>
|
||||
</div>
|
||||
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<div class="container mx-auto">
|
||||
<header class="text-center mb-8">
|
||||
<h1 class="text-4xl md:text-6xl font-bold text-primary">Smart Agent List</h1>
|
||||
<h1 class="text-4xl md:text-6xl font-bold">Smart Agent List</h1>
|
||||
<p class="mt-4 text-gray-400">Manage and interact with your AI agents</p>
|
||||
</header>
|
||||
|
||||
<div class="button-container justify-center mb-6">
|
||||
<a href="/create" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out">
|
||||
Add New Agent
|
||||
<a href="/create" class="action-btn start-btn">
|
||||
<i class="fas fa-plus-circle"></i> Add New Agent
|
||||
</a>
|
||||
<button id="toggle-import" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out ml-4">
|
||||
Import Agent
|
||||
<button id="toggle-import" class="action-btn" style="background: linear-gradient(135deg, var(--tertiary), #4a76a8);">
|
||||
<i class="fas fa-file-import"></i> Import Agent
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<section id="import-section" class="hidden mb-8">
|
||||
<div class="section-box">
|
||||
<h2 class="text-2xl font-bold mb-4">Import Agent</h2>
|
||||
<h2>Import Agent</h2>
|
||||
|
||||
<!-- Response Messages Container -->
|
||||
<div id="response-container">
|
||||
<!-- Success Alert -->
|
||||
<div id="success-alert" class="alert alert-success">
|
||||
<div id="success-alert" class="alert alert-success" style="display: none;">
|
||||
Agent imported successfully! The page will refresh in a moment.
|
||||
</div>
|
||||
|
||||
<!-- Error Alert -->
|
||||
<div id="error-alert" class="alert alert-error">
|
||||
<div id="error-alert" class="alert alert-error" style="display: none;">
|
||||
<span id="error-message">Error importing agent.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id='import-form' hx-encoding='multipart/form-data' hx-post='/settings/import' hx-target="#response-container" hx-swap="none">
|
||||
<div class="mb-4">
|
||||
<label for="file" class="block text-gray-300 mb-2">Select Agent File:</label>
|
||||
<input type='file' name='file' id='file' class="bg-gray-700 text-white rounded p-2 w-full">
|
||||
<label for="file" class="block mb-2">Select Agent File:</label>
|
||||
<input type='file' name='file' id='file'>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<button id="import-button" type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out">
|
||||
Import Agent
|
||||
<button id="import-button" type="submit" class="action-btn">
|
||||
<i class="fas fa-cloud-upload-alt"></i> Import Agent
|
||||
</button>
|
||||
<progress id='progress' value='0' max='100' class="ml-4"></progress>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{{ $status := .Status }}
|
||||
{{ range .Agents }}
|
||||
<div class="card relative flex flex-col items-center text-center p-6 bg-gray-800 rounded-lg shadow-md">
|
||||
<img src="/public/agent_{{.}}.png" alt="{{.}}" class="w-24 h-24 rounded-full mb-4">
|
||||
<h2 class="text-xl font-bold mb-2">{{.}}</h2>
|
||||
<p class="text-gray-400 mb-4">Online: {{ index $status . }}</p>
|
||||
<div class="flex justify-center space-x-4">
|
||||
<a href="/status/{{.}}" class="text-indigo-500 hover:text-indigo-400">
|
||||
<i class="fas fa-info-circle"></i> Status
|
||||
</a>
|
||||
<a href="/talk/{{.}}" class="text-indigo-500 hover:text-indigo-400">
|
||||
<i class="fas fa-comments"></i> Talk
|
||||
</a>
|
||||
<button class="action-btn start-btn" hx-put="/start/{{.}}" hx-swap="none" hx-ext="json-enc" data-action="start" data-agent="{{.}}">
|
||||
Start
|
||||
</button>
|
||||
<button class="action-btn pause-btn" hx-put="/pause/{{.}}" hx-swap="none" hx-ext="json-enc" data-action="pause" data-agent="{{.}}">
|
||||
Pause
|
||||
</button>
|
||||
<a href="/settings/{{.}}" class="text-indigo-500 hover:text-indigo-400">
|
||||
<i class="fas fa-cog"></i> Settings
|
||||
</a>
|
||||
<div hx-ext="sse" data-agent-name="{{.}}" class="card">
|
||||
<div class="flex flex-col items-center text-center p-4">
|
||||
<!--<img src="/public/agent_{{.}}.png" alt="{{.}}" class="w-24 h-24 rounded-full mb-4"
|
||||
style="border: 2px solid var(--primary); box-shadow: var(--neon-glow);">-->
|
||||
<h2>{{.}}</h2>
|
||||
<div class="mb-4 flex items-center justify-center">
|
||||
<span class="badge {{ if eq (index $status .) true }}badge-primary{{ else }}badge-secondary{{ end }} mr-2">
|
||||
{{ if eq (index $status .) true }}Active{{ else }}Inactive{{ end }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2 w-full mb-4">
|
||||
<a href="/status/{{.}}" class="action-btn flex items-center justify-center"
|
||||
style="background: linear-gradient(135deg, #2a2a2a, #3a3a3a);">
|
||||
<i class="fas fa-info-circle mr-2"></i> Status
|
||||
</a>
|
||||
<a href="/talk/{{.}}" class="action-btn flex items-center justify-center"
|
||||
style="background: linear-gradient(135deg, #2a2a2a, #3a3a3a);">
|
||||
<i class="fas fa-comments mr-2"></i> Talk
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-2 w-full">
|
||||
<button class="action-btn start-btn col-span-1"
|
||||
hx-put="/start/{{.}}" hx-swap="none" hx-ext="json-enc"
|
||||
data-action="start" data-agent="{{.}}">
|
||||
<i class="fas fa-play"></i>
|
||||
</button>
|
||||
<button class="action-btn pause-btn col-span-1"
|
||||
hx-put="/pause/{{.}}" hx-swap="none" hx-ext="json-enc"
|
||||
data-action="pause" data-agent="{{.}}">
|
||||
<i class="fas fa-pause"></i>
|
||||
</button>
|
||||
<a href="/settings/{{.}}" class="action-btn col-span-1 flex items-center justify-center"
|
||||
style="background: linear-gradient(135deg, #2a2a2a, #3a3a3a);">
|
||||
<i class="fas fa-cog"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</section>
|
||||
<footer class="mt-8 text-center">
|
||||
<p>© 2025 Smart Agent List. All rights reserved.</p>
|
||||
|
||||
<div class="user-info mt-8 mb-4">
|
||||
<span></span>
|
||||
<span class="timestamp"></span>
|
||||
</div>
|
||||
|
||||
<footer class="text-center text-gray-500 text-sm mb-8">
|
||||
<p>© 2025 LocalAgent.</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
const importSection = document.getElementById('import-section');
|
||||
const toggleImport = document.getElementById('toggle-import');
|
||||
|
||||
// Toggle import section visibility
|
||||
toggleImport.addEventListener('click', function() {
|
||||
importSection.classList.toggle('hidden');
|
||||
// Add glitch effect when showing
|
||||
if (!importSection.classList.contains('hidden')) {
|
||||
importSection.style.animation = 'glitch 0.3s';
|
||||
setTimeout(() => {
|
||||
importSection.style.animation = '';
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle import form submission
|
||||
@@ -113,6 +153,7 @@
|
||||
if (response.status === "ok") {
|
||||
// Show success message
|
||||
successAlert.style.display = 'block';
|
||||
showToast("Agent imported successfully!", "success");
|
||||
|
||||
// Refresh the page after a short delay
|
||||
setTimeout(() => {
|
||||
@@ -122,26 +163,35 @@
|
||||
// Show error message
|
||||
errorMessage.textContent = response.error;
|
||||
errorAlert.style.display = 'block';
|
||||
showToast("Import failed: " + response.error, "error");
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle parsing error
|
||||
errorMessage.textContent = "Invalid response format";
|
||||
errorAlert.style.display = 'block';
|
||||
showToast("Invalid response format", "error");
|
||||
}
|
||||
} else {
|
||||
// Handle HTTP error
|
||||
errorMessage.textContent = "Server error: " + xhr.status;
|
||||
errorAlert.style.display = 'block';
|
||||
showToast("Server error: " + xhr.status, "error");
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listeners for Start and Pause buttons
|
||||
document.querySelectorAll('.action-btn').forEach(button => {
|
||||
document.querySelectorAll('.action-btn[data-action]').forEach(button => {
|
||||
button.addEventListener('htmx:beforeRequest', function() {
|
||||
this.style.animation = 'pulse 0.5s';
|
||||
});
|
||||
|
||||
button.addEventListener('htmx:afterRequest', function(event) {
|
||||
const xhr = event.detail.xhr;
|
||||
const action = this.getAttribute('data-action');
|
||||
const agent = this.getAttribute('data-agent');
|
||||
|
||||
this.style.animation = '';
|
||||
|
||||
if (xhr.status === 200) {
|
||||
try {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
@@ -175,9 +225,15 @@
|
||||
cards.forEach(card => {
|
||||
const agentTitle = card.querySelector('h2').textContent;
|
||||
if (agentTitle === agentName) {
|
||||
// Update the "Online:" text
|
||||
const statusText = card.querySelector('p');
|
||||
statusText.textContent = `Online: ${isOnline}`;
|
||||
// Update the badge
|
||||
const badge = card.querySelector('.badge');
|
||||
if (isOnline) {
|
||||
badge.className = 'badge badge-primary mr-2';
|
||||
badge.textContent = 'Active';
|
||||
} else {
|
||||
badge.className = 'badge badge-secondary mr-2';
|
||||
badge.textContent = 'Inactive';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,207 +3,277 @@
|
||||
<head>
|
||||
<title>Create New Agent</title>
|
||||
{{template "views/partials/header"}}
|
||||
<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>
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
display: none;
|
||||
}
|
||||
.alert-success {
|
||||
background-color: rgba(16, 185, 129, 0.2);
|
||||
border: 1px solid #10b981;
|
||||
color: #10b981;
|
||||
}
|
||||
.alert-error {
|
||||
background-color: rgba(239, 68, 68, 0.2);
|
||||
border: 1px solid #ef4444;
|
||||
color: #ef4444;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-900 p-4 text-white font-sans">
|
||||
<body>
|
||||
{{template "views/partials/menu"}}
|
||||
<div class="max-w-2xl mx-auto my-12 bg-gray-800 p-8 rounded-lg shadow-lg">
|
||||
<h1 class="text-3xl font-bold text-center mb-6 text-blue-400">Create New Agent</h1>
|
||||
<div class="container">
|
||||
<div class="section-box">
|
||||
<h1>Create New Agent</h1>
|
||||
|
||||
<form id="create-agent-form" action="/create" method="POST">
|
||||
<div class="mb-4">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" id="name" placeholder="Name">
|
||||
</div>
|
||||
|
||||
<div id="connectorsSection">
|
||||
<!-- Connectors will be added here dynamically -->
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<button type="button" id="addConnectorButton" class="action-btn">
|
||||
<i class="fas fa-plus-circle"></i> Add Connector
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-4" id="action_box">
|
||||
<!-- Actions will be added here dynamically -->
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<button id="action_button" type="button" class="action-btn">
|
||||
<i class="fas fa-plus-circle"></i> Add Action
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-4" id="dynamic_box">
|
||||
<!-- Dynamic prompts will be added here dynamically -->
|
||||
</div>
|
||||
|
||||
<div class="button-container">
|
||||
<button id="dynamic_button" type="button" class="action-btn">
|
||||
<i class="fas fa-plus-circle"></i> Add Dynamic Prompt
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="hud" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="hud" id="hud">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
HUD
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="enable_kb" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="enable_kb" id="enable_kb">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Enable Knowledge Base
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="enable_reasoning" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="enable_reasoning" id="enable_reasoning">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Enable Reasoning
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="kb_results">Knowledge Base Results</label>
|
||||
<input type="text" name="kb_results" id="kb_results" placeholder="3">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<form id="create-agent-form" action="/create" method="POST" class="space-y-6">
|
||||
|
||||
<div class="mb-6">
|
||||
<label for="name" class="block text-lg font-medium text-gray-400">Name</label>
|
||||
<input type="text" name="name" id="name" 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 id="connectorsSection">
|
||||
</div>
|
||||
<button type="button" id="addConnectorButton" 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 Connector
|
||||
</button>
|
||||
|
||||
<script>
|
||||
const actions = `{{ range .Actions }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
const connectors = `{{ range .Connectors }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
|
||||
document.getElementById('addConnectorButton').addEventListener('click', function() {
|
||||
const connectorsSection = document.getElementById('connectorsSection');
|
||||
const newConnectorIndex = connectorsSection.getElementsByClassName('connector').length;
|
||||
const newConnectorHTML = `
|
||||
<div class="connector mb-4">
|
||||
<div class="mb-4">
|
||||
<label for="connectorType${newConnectorIndex}" class="block text-lg font-medium text-gray-400">Connector Type</label>
|
||||
<select name="connectors[${newConnectorIndex}].type" id="connectorType${newConnectorIndex}" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
||||
`+connectors+` </select>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="connectorConfig${newConnectorIndex}" class="block text-lg font-medium text-gray-400">Connector Config (JSON)</label>
|
||||
<textarea id="connectorConfig${newConnectorIndex}" name="connectors[${newConnectorIndex}].config" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder='{"token":"sk-mg3.."}'>{}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
connectorsSection.insertAdjacentHTML('beforeend', newConnectorHTML);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="mb-4" id="action_box">
|
||||
</div>
|
||||
<button id="action_button" type="button" 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 action</button>
|
||||
|
||||
<script>
|
||||
document.getElementById('action_button').addEventListener('click', function() {
|
||||
const actionsSection = document.getElementById('action_box');
|
||||
const ii = actionsSection.getElementsByClassName('action').length;
|
||||
|
||||
const newActionHTML = `
|
||||
<div class="action mb-4">
|
||||
<label for="actionsName${ii}" class="block text-lg font-medium text-gray-400">Action</label>
|
||||
<select name="actions[${ii}].name" id="actionsName${ii}" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
||||
`+actions+`</select>
|
||||
<div class="mb-4">
|
||||
<label for="actionsConfig${ii}" class="block text-lg font-medium text-gray-400">Action Config (JSON)</label>
|
||||
<textarea id="actionsConfig${ii}" name="actions[${ii}].config" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder='{"results":"5"}'>{}</textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="standalone_job" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="standalone_job" id="standalone_job">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Standalone Job
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
|
||||
actionsSection.insertAdjacentHTML('beforeend', newActionHTML);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="mb-4" id="dynamic_box">
|
||||
</div>
|
||||
<button id="dynamic_button" type="button" 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 Dynamic prompt</button>
|
||||
|
||||
<script>
|
||||
const promptBlocks = `{{ range .PromptBlocks }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
|
||||
document.getElementById('dynamic_button').addEventListener('click', function() {
|
||||
const actionsSection = document.getElementById('dynamic_box');
|
||||
const ii = actionsSection.getElementsByClassName('promptBlock').length;
|
||||
|
||||
const newActionHTML = `
|
||||
<div class="promptBlock mb-4">
|
||||
<label for="promptName${ii}" class="block text-lg font-medium text-gray-400">Block Prompt</label>
|
||||
<select name="promptblocks[${ii}].name" id="promptName${ii}" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
||||
`+promptBlocks+`</select>
|
||||
<div class="mb-4">
|
||||
<label for="promptConfig${ii}" class="block text-lg font-medium text-gray-400">Prompt Config (JSON)</label>
|
||||
<textarea id="promptConfig${ii}" name="promptblocks[${ii}].config" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder='{"results":"5"}'>{}</textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="initiate_conversations" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="initiate_conversations" id="initiate_conversations">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Initiate Conversations
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
|
||||
actionsSection.insertAdjacentHTML('beforeend', newActionHTML);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="hud" class="block text-lg font-medium text-gray-400">HUD</label>
|
||||
<input type="checkbox" name="hud" id="hud" 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 class="mb-4">
|
||||
<label for="can_stop_itself" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="can_stop_itself" id="can_stop_itself">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Can Stop Itself
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="random_identity" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="random_identity" id="random_identity">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Random Identity
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="long_term_memory" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="long_term_memory" id="long_term_memory">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Long Term Memory
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="summary_long_term_memory" class="checkbox-label">
|
||||
<span class="checkbox-custom">
|
||||
<input type="checkbox" name="summary_long_term_memory" id="summary_long_term_memory">
|
||||
<span class="checkmark"></span>
|
||||
</span>
|
||||
Long Term Memory (Summarize!)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="identity_guidance">Identity Guidance</label>
|
||||
<textarea name="identity_guidance" id="identity_guidance" placeholder="Identity Guidance"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="periodic_runs">Periodic Runs</label>
|
||||
<input type="text" name="periodic_runs" id="periodic_runs" placeholder="Periodic Runs">
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="permanent_goal">Permanent Goal</label>
|
||||
<textarea name="permanent_goal" id="permanent_goal" placeholder="Permanent goal"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="system_prompt">System Prompt</label>
|
||||
<textarea name="system_prompt" id="system_prompt" placeholder="System prompt"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="create-button">
|
||||
<i class="fas fa-robot"></i> Create Agent
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="enable_kb" class="block text-lg font-medium text-gray-400">Enable Knowledge Base</label>
|
||||
<input type="checkbox" name="enable_kb" id="enable_kb" 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">
|
||||
<label for="enable_reasoning" class="block text-lg font-medium text-gray-400">Enable Reasoning</label>
|
||||
<input type="checkbox" name="enable_reasoning" id="enable_reasoning" 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 class="mb-6">
|
||||
<label for="kb_results" class="block text-lg font-medium text-gray-400">Knowledge base results</label>
|
||||
<input type="text" name="kb_results" id="kb_results" 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="3">
|
||||
|
||||
<!-- Response Messages Container -->
|
||||
<div id="response-container">
|
||||
<!-- Alert messages will be shown here -->
|
||||
<div id="success-alert" class="alert alert-success" style="display: none;">
|
||||
Agent created successfully! Redirecting to agent list...
|
||||
</div>
|
||||
|
||||
<label for="standalone_job" class="block text-lg font-medium text-gray-400">Standalone Job</label>
|
||||
<input type="checkbox" name="standalone_job" id="standalone_job" 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">
|
||||
|
||||
<label for="initiate_conversations" class="block text-lg font-medium text-gray-400">Initiate conversations</label>
|
||||
<input type="checkbox" name="random_identity" id="initiate_conversations" 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">
|
||||
|
||||
<label for="can_stop_itself" class="block text-lg font-medium text-gray-400">Can stop itself</label>
|
||||
<input type="checkbox" name="can_stop_itself" id="can_stop_itself" 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">
|
||||
|
||||
<label for="random_identity" class="block text-lg font-medium text-gray-400">Random Identity</label>
|
||||
<input type="checkbox" name="random_identity" id="random_identity" 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">
|
||||
|
||||
<label for="long_term_memory" class="block text-lg font-medium text-gray-400">Long term memory</label>
|
||||
<input type="checkbox" name="long_term_memory" id="long_term_memory" 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">
|
||||
<label for="summary_long_term_memory" class="block text-lg font-medium text-gray-400">Long term memory (summarize!)</label>
|
||||
<input type="checkbox" name="summary_long_term_memory" id="summary_long_term_memory" 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-4">
|
||||
<label for="identity_guidance" class="block text-lg font-medium text-gray-400">Identity Guidance</label>
|
||||
<textarea name="identity_guidance" id="identity_guidance" 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="Identity Guidance"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="periodic_runs" class="block text-lg font-medium text-gray-400">Periodic Runs</label>
|
||||
<input type="text" name="periodic_runs" id="periodic_runs" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Periodic Runs">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="permanent_goal" class="block text-lg font-medium text-gray-400">Permanent goal</label>
|
||||
<textarea name="permanent_goal" id="permanent_goal" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Permanent goal"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="system_prompt" class="block text-lg font-medium text-gray-400">System prompt</label>
|
||||
<textarea name="system_prompt" id="system_prompt" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="System prompt"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="submit" id="create-button" 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">
|
||||
Create Agent
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Response Messages Container -->
|
||||
<div id="response-container">
|
||||
<!-- Success Alert -->
|
||||
<div id="success-alert" class="alert alert-success">
|
||||
Agent created successfully! Redirecting to agent list...
|
||||
</div>
|
||||
|
||||
<!-- Error Alert -->
|
||||
<div id="error-alert" class="alert alert-error">
|
||||
<span id="error-message">Error creating agent.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Convert regular form to use HTMX
|
||||
const form = document.getElementById('create-agent-form');
|
||||
|
||||
// Add HTMX attributes to the form
|
||||
form.setAttribute('hx-post', '/create');
|
||||
form.setAttribute('hx-swap', 'none');
|
||||
<div id="error-alert" class="alert alert-error" style="display: none;">
|
||||
<span id="error-message">Error creating agent.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast notification container -->
|
||||
<div id="toast" class="toast">
|
||||
<span id="toast-message"></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const actions = `{{ range .Actions }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
const connectors = `{{ range .Connectors }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
const promptBlocks = `{{ range .PromptBlocks }}<option value="{{.}}">{{.}}</option>{{ end }}`;
|
||||
|
||||
// Add connector functionality
|
||||
document.getElementById('addConnectorButton').addEventListener('click', function() {
|
||||
const connectorsSection = document.getElementById('connectorsSection');
|
||||
const newConnectorIndex = connectorsSection.getElementsByClassName('connector').length;
|
||||
const newConnectorHTML = `
|
||||
<div class="connector mb-4 section-box" style="margin-top: 15px; padding: 15px;">
|
||||
<h2>Connector ${newConnectorIndex + 1}</h2>
|
||||
<div class="mb-4">
|
||||
<label for="connectorType${newConnectorIndex}">Connector Type</label>
|
||||
<select name="connectors[${newConnectorIndex}].type" id="connectorType${newConnectorIndex}">
|
||||
${connectors}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="connectorConfig${newConnectorIndex}">Connector Config (JSON)</label>
|
||||
<textarea id="connectorConfig${newConnectorIndex}" name="connectors[${newConnectorIndex}].config" placeholder='{"token":"sk-mg3.."}'>{}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
connectorsSection.insertAdjacentHTML('beforeend', newConnectorHTML);
|
||||
});
|
||||
|
||||
// Add action functionality
|
||||
document.getElementById('action_button').addEventListener('click', function() {
|
||||
const actionsSection = document.getElementById('action_box');
|
||||
const ii = actionsSection.getElementsByClassName('action').length;
|
||||
|
||||
const newActionHTML = `
|
||||
<div class="action mb-4 section-box" style="margin-top: 15px; padding: 15px;">
|
||||
<h2>Action ${ii + 1}</h2>
|
||||
<div class="mb-4">
|
||||
<label for="actionsName${ii}">Action</label>
|
||||
<select name="actions[${ii}].name" id="actionsName${ii}">
|
||||
${actions}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="actionsConfig${ii}">Action Config (JSON)</label>
|
||||
<textarea id="actionsConfig${ii}" name="actions[${ii}].config" placeholder='{"results":"5"}'>{}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
actionsSection.insertAdjacentHTML('beforeend', newActionHTML);
|
||||
});
|
||||
|
||||
// Add dynamic prompt functionality
|
||||
document.getElementById('dynamic_button').addEventListener('click', function() {
|
||||
const promptsSection = document.getElementById('dynamic_box');
|
||||
const ii = promptsSection.getElementsByClassName('promptBlock').length;
|
||||
|
||||
const newPromptHTML = `
|
||||
<div class="promptBlock mb-4 section-box" style="margin-top: 15px; padding: 15px;">
|
||||
<h2>Prompt Block ${ii + 1}</h2>
|
||||
<div class="mb-4">
|
||||
<label for="promptName${ii}">Block Prompt</label>
|
||||
<select name="promptblocks[${ii}].name" id="promptName${ii}">
|
||||
${promptBlocks}
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="promptConfig${ii}">Prompt Config (JSON)</label>
|
||||
<textarea id="promptConfig${ii}" name="promptblocks[${ii}].config" placeholder='{"results":"5"}'>{}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
promptsSection.insertAdjacentHTML('beforeend', newPromptHTML);
|
||||
});
|
||||
|
||||
// Form submission handling
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.getElementById('create-agent-form');
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Show a loading state
|
||||
const createButton = document.getElementById('create-button');
|
||||
const originalButtonText = createButton.innerHTML;
|
||||
createButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Creating...';
|
||||
createButton.disabled = true;
|
||||
|
||||
// Get form data
|
||||
const formData = new FormData(form);
|
||||
|
||||
@@ -223,6 +293,9 @@
|
||||
errorAlert.style.display = 'none';
|
||||
|
||||
if (data.status === "ok") {
|
||||
// Show success toast
|
||||
showToast('Agent created successfully!', 'success');
|
||||
|
||||
// Show success message
|
||||
successAlert.style.display = 'block';
|
||||
|
||||
@@ -231,31 +304,60 @@
|
||||
window.location.href = '/';
|
||||
}, 2000);
|
||||
} else if (data.error) {
|
||||
// Show error toast
|
||||
showToast('Error: ' + data.error, 'error');
|
||||
|
||||
// Show error message
|
||||
errorMessage.textContent = data.error;
|
||||
errorAlert.style.display = 'block';
|
||||
|
||||
// Scroll to the error message
|
||||
errorAlert.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
// Restore button state
|
||||
createButton.innerHTML = originalButtonText;
|
||||
createButton.disabled = false;
|
||||
} else {
|
||||
// Handle unexpected response format
|
||||
showToast('Unexpected response format', 'error');
|
||||
errorMessage.textContent = "Unexpected response format";
|
||||
errorAlert.style.display = 'block';
|
||||
|
||||
// Restore button state
|
||||
createButton.innerHTML = originalButtonText;
|
||||
createButton.disabled = false;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle network or other errors
|
||||
showToast('Network error: ' + error.message, 'error');
|
||||
const errorAlert = document.getElementById('error-alert');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
|
||||
errorMessage.textContent = "Network error: " + error.message;
|
||||
errorAlert.style.display = 'block';
|
||||
errorAlert.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
|
||||
// Restore button state
|
||||
createButton.innerHTML = originalButtonText;
|
||||
createButton.disabled = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
// Add additional CSS for checkbox labels
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.checkbox-label .checkbox-custom {
|
||||
margin-right: 10px;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,28 +4,217 @@
|
||||
<title>Smart Assistant Dashboard</title>
|
||||
{{template "views/partials/header"}}
|
||||
<style>
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 40px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image-container img {
|
||||
filter: drop-shadow(0 0 15px rgba(94, 0, 255, 0.6));
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.image-container:hover img {
|
||||
transform: scale(1.05);
|
||||
filter: drop-shadow(0 0 25px rgba(0, 255, 149, 0.8));
|
||||
}
|
||||
|
||||
.image-container::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -15px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40%;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, var(--primary), var(--secondary), var(--tertiary), transparent);
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
font-size: 2.5rem;
|
||||
letter-spacing: 2px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: var(--primary);
|
||||
text-shadow: var(--neon-glow);
|
||||
animation: gentlePulse 3s infinite;
|
||||
}
|
||||
|
||||
/* Gentle pulse animation for the title */
|
||||
@keyframes gentlePulse {
|
||||
0% { text-shadow: 0 0 7px var(--primary), 0 0 10px var(--primary); }
|
||||
50% { text-shadow: 0 0 12px var(--primary), 0 0 20px var(--primary); }
|
||||
100% { text-shadow: 0 0 7px var(--primary), 0 0 10px var(--primary); }
|
||||
}
|
||||
|
||||
/* Subtle glitch effect for hover */
|
||||
@keyframes subtleGlitch {
|
||||
0% { transform: translateX(-50%); }
|
||||
20% { transform: translateX(-50%) translate(-1px, 1px); }
|
||||
40% { transform: translateX(-50%) translate(-1px, -1px); }
|
||||
60% { transform: translateX(-50%) translate(1px, 1px); }
|
||||
80% { transform: translateX(-50%) translate(1px, -1px); }
|
||||
100% { transform: translateX(-50%); }
|
||||
}
|
||||
|
||||
.cards-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.dashboard-stats {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin: 20px 0 40px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
background: rgba(17, 17, 17, 0.7);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
min-width: 150px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(94, 0, 255, 0.2);
|
||||
}
|
||||
|
||||
.stat-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, var(--primary), var(--secondary));
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.stat-count {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
text-shadow: var(--neon-glow);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.9rem;
|
||||
color: #cccccc;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* Badge positioning */
|
||||
.card {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-900 p-4 text-white font-sans">
|
||||
<body>
|
||||
{{template "views/partials/menu"}}
|
||||
<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>
|
||||
|
||||
<h1 class="dashboard-title">SMART ASSISTANT DASHBOARD</h1>
|
||||
|
||||
<!-- Simple stats display -->
|
||||
<div class="dashboard-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-count">{{.Actions}}</div>
|
||||
<div class="stat-label">Available Actions</div>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/create" class="card-link">
|
||||
<div class="card">
|
||||
<h2>Create</h2>
|
||||
<p>Create a new agent.</p>
|
||||
<div class="stat-item">
|
||||
<div class="stat-count">{{ .AgentCount }}</div>
|
||||
<div class="stat-label">Agents</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="cards-container">
|
||||
<!-- Card for Agent List Page -->
|
||||
<a href="/agents" class="card-link">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-robot"></i> Agent List</h2>
|
||||
<p>View and manage your list of agents, including detailed profiles and statistics.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card for Create Agent -->
|
||||
<a href="/create" class="card-link">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-plus-circle"></i> Create Agent</h2>
|
||||
<p>Create a new intelligent agent with custom behaviors, connectors, and actions.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Additional Cards for Future Features -->
|
||||
<a href="#" class="card-link">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-chart-line"></i> Analytics</h2>
|
||||
<p>View performance metrics and insights from your agent operations.</p>
|
||||
<span class="badge badge-secondary">Coming Soon</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="#" class="card-link">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-cogs"></i> Settings</h2>
|
||||
<p>Configure system preferences and global settings for all agents.</p>
|
||||
<span class="badge badge-secondary">Coming Soon</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast notification container -->
|
||||
<div id="toast" class="toast">
|
||||
<span id="toast-message"></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Add the controlled glitch effect to dashboard title
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const title = document.querySelector('.dashboard-title');
|
||||
|
||||
title.addEventListener('mouseover', function() {
|
||||
// Use the more subtle glitch animation
|
||||
this.style.animation = 'subtleGlitch 0.5s infinite';
|
||||
});
|
||||
|
||||
title.addEventListener('mouseout', function() {
|
||||
// Return to gentle pulse animation
|
||||
this.style.animation = 'gentlePulse 3s infinite';
|
||||
});
|
||||
|
||||
// Welcome toast notification
|
||||
setTimeout(() => {
|
||||
showToast('Welcome to Smart Assistant Dashboard', 'success');
|
||||
}, 1000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Reference in New Issue
Block a user