This commit is contained in:
Flatlogic Bot 2025-12-17 05:03:15 +00:00
parent 551b959be1
commit ac6e16f3bd
23 changed files with 302 additions and 116 deletions

View File

@ -155,6 +155,8 @@ STATICFILES_DIRS = [
BASE_DIR / 'node_modules', BASE_DIR / 'node_modules',
] ]
LOGIN_URL = '/login/'
# Email # Email
EMAIL_BACKEND = os.getenv( EMAIL_BACKEND = os.getenv(
"EMAIL_BACKEND", "EMAIL_BACKEND",

Binary file not shown.

View File

@ -1,3 +1,10 @@
from django.contrib import admin from django.contrib import admin
from .models import Agent
# Register your models here. # Register your models here.
@admin.register(Agent)
class AgentAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'published', 'created_at')
list_filter = ('published', 'user')
search_fields = ('name', 'description')

10
core/forms.py Normal file
View File

@ -0,0 +1,10 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
class Meta:
model = User
fields = ('username', 'email', 'password', 'password2')

View File

@ -0,0 +1,29 @@
# Generated by Django 5.2.7 on 2025-12-17 04:36
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Agent',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('description', models.TextField(blank=True)),
('published', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,3 +1,15 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User
# Create your models here. # Create your models here.
class Agent(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # Allow null user for now
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Knowledge Base{% endblock %}</title> <title>{% block title %}AI Agent Studio{% endblock %}</title>
{% if project_description %} {% if project_description %}
<meta name="description" content="{{ project_description }}"> <meta name="description" content="{{ project_description }}">
<meta property="og:description" content="{{ project_description }}"> <meta property="og:description" content="{{ project_description }}">
@ -17,12 +17,37 @@
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}"> <link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
{% block head %}{% endblock %} {% block head %}{% endblock %}
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: #1A237E;">
<div class="container">
<a class="navbar-brand" href="{% url 'home' %}">AI Agent Studio</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="{% url 'home' %}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'create_agent' %}">Create Agent</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'my_agents' %}">My Agents</a>
</li>
</ul>
</div>
</div>
</nav>
{% block content %}{% endblock %} {% block content %}{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
{% block extra_js %}{% endblock %} {% block extra_js %}{% endblock %}
</body> </body>

View File

@ -1,14 +1,19 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}{{ article.title }}{% endblock %} {% block title %}{{ agent.name }} - AI Agent{% endblock %}
{% block content %} {% block content %}
<div class="container mt-5"> <div class="container mt-5">
<h1>{{ article.title }}</h1> <div class="row">
<p class="text-muted">Published on {{ article.created_at|date:"F d, Y" }}</p> <div class="col-lg-8 offset-lg-2">
<hr> <div class="agent-detail-header text-center mb-4">
<div> <h1 class="display-4">{{ agent.name }}</h1>
{{ article.content|safe }} </div>
<div class="agent-detail-body">
<p class="lead">{{ agent.description }}</p>
<!-- Add more agent details here as needed -->
</div>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,79 +1,21 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load static %}
{% block title %}Create New AI Agent{% endblock %}
{% block content %} {% block content %}
<div class="container-fluid h-100"> <div class="container mt-5">
<div class="row h-100"> <h1 class="display-4">Create a New Agent</h1>
<main class="col-12 h-100" style="padding-top: 60px;"> <p class="lead">Define the name and description of your new AI agent.</p>
<div class="chat-container h-100 d-flex flex-column">
<div class="chat-messages flex-grow-1 overflow-auto"> <form method="post">
<div class="message-bubble received"> {% csrf_token %}
<p>Hello! I'm here to help you create a new AI agent. What is the agent's purpose?</p> <div class="mb-3">
</div> <label for="name" class="form-label">Name</label>
</div> <input type="text" class="form-control" id="name" name="name" placeholder="e.g., 'Customer Support Bot'">
<div class="chat-input-container"> </div>
{% csrf_token %} <div class="mb-3">
<div class="input-group"> <label for="description" class="form-label">Description</label>
<input type="text" id="userInput" class="form-control" placeholder="Describe your agent..."> <textarea class="form-control" id="description" name="description" rows="3" placeholder="e.g., 'An AI assistant that answers customer questions.'"></textarea>
<button class="btn btn-primary" id="sendButton">Send</button> </div>
</div> <button type="submit" class="btn btn-primary">Create Agent</button>
</div> </form>
</div>
</main>
</div>
</div> </div>
{% endblock %} {% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const sendButton = document.getElementById('sendButton');
const userInput = document.getElementById('userInput');
const chatMessages = document.querySelector('.chat-messages');
sendButton.addEventListener('click', sendMessage);
userInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
function sendMessage() {
const messageText = userInput.value.trim();
if (messageText === '') return;
// Display user's message
const userMessageBubble = document.createElement('div');
userMessageBubble.className = 'message-bubble sent';
userMessageBubble.innerHTML = `<p>${messageText}</p>`;
chatMessages.appendChild(userMessageBubble);
userInput.value = '';
chatMessages.scrollTop = chatMessages.scrollHeight;
// Get CSRF token
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
// Send message to server and get response
fetch('{% url 'create_agent' %}', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrftoken
},
body: `message=${encodeURIComponent(messageText)}`
})
.then(response => response.json())
.then(data => {
const botMessageBubble = document.createElement('div');
botMessageBubble.className = 'message-bubble received';
botMessageBubble.innerHTML = `<p>${data.message}</p>`;
chatMessages.appendChild(botMessageBubble);
chatMessages.scrollTop = chatMessages.scrollHeight;
});
}
});
</script>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5">
<h1 class="display-4">Edit Agent</h1>
<p class="lead">Edit the details of your AI agent.</p>
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" value="{{ agent.name }}">
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="3">{{ agent.description }}</textarea>
</div>
<button type="submit" class="btn btn-primary">Save Changes</button>
</form>
</div>
{% endblock %}

View File

@ -18,37 +18,35 @@
</div> </div>
</div> </div>
<div class="container agent-showcase"> <div class="container agent-showcase">
<div class="text-center mb-5"> <div class="text-center mb-5">
<h2>Explore What You Can Build</h2>
<p class="lead">These examples are just the beginning. Your imagination is the only limit.</p> <h2>Explore Published Agents</h2>
<p class="lead">These are the agents that have been published by our users.</p>
</div> </div>
<div class="agent-grid"> <div class="agent-grid">
<!-- Sample Agent 1 --> {% for agent in agents %}
<div class="agent-card"> <a href="{% url 'agent_detail' agent.id %}" class="agent-card-link">
<div class="icon"><i class="fas fa-robot"></i></div> <div class="agent-card">
<h3>Customer Support Bot</h3> <div class="card-body d-flex flex-column">
<p>An intelligent bot that handles common customer queries, freeing up your team for complex issues.</p> <h3 class="card-title">{{ agent.name }}</h3>
<p class="card-text flex-grow-1">{{ agent.description }}</p>
</div>
</div>
</a>
{% empty %}
<div class="text-center w-100">
<p class="lead">No agents have been published yet. Be the first!</p>
</div> </div>
{% endfor %}
<!-- Sample Agent 2 -->
<div class="agent-card">
<div class="icon"><i class="fas fa-chart-line"></i></div>
<h3>Data Analyst Agent</h3>
<p>Connect your data sources and let this agent find trends, generate reports, and provide insights.</p>
</div>
<!-- Sample Agent 3 -->
<div class="agent-card">
<div class="icon"><i class="fas fa-code"></i></div>
<h3>Code Generation Assistant</h3>
<p>Describe a function or component, and this agent will generate the boilerplate code for you in any language.</p>
</div>
</div>
<div class="text-center mt-5">
<a href="{% url 'create_agent' %}" class="btn btn-primary btn-lg">Create a New Agent</a>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block content %}
<h2>Login to Your Account</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<p>Don't have an account? <a href="{% url 'signup' %}">Sign up</a></p>
{% endblock %}

View File

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block content %}
<div class="container mt-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="display-4">My Agents</h1>
<a href="{% url 'create_agent' %}" class="btn btn-primary">Create New Agent</a>
</div>
<p class="lead mb-5">Here is a list of all the AI agents you have created.</p>
{% if agents %}
<div class="agent-grid">
{% for agent in agents %}
<div class="agent-card">
<div class="card-body d-flex flex-column">
<h3 class="card-title">{{ agent.name }}</h3>
<p class="card-text flex-grow-1">{{ agent.description }}</p>
<div class="d-flex justify-content-between align-items-center mb-3">
<strong>Status:</strong>
{% if agent.published %}
<span class="badge bg-success">Published</span>
{% else %}
<span class="badge bg-secondary">Draft</span>
{% endif %}
</div>
<div class="d-flex justify-content-center">
<a href="{% url 'edit_agent' agent.id %}" class="btn btn-sm btn-outline-primary me-2">Edit</a>
<form action="{% url 'delete_agent' agent.id %}" method="post" onsubmit="return confirm('Are you sure you want to delete this agent?');">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-outline-danger me-2">Delete</button>
</form>
<a href="{% url 'publish_agent' agent.id %}" class="btn btn-sm btn-outline-info">
{% if agent.published %}Unpublish{% else %}Publish{% endif %}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-5">
<h2 class="display-5">No Agents Yet</h2>
<p class="lead">You haven't created any agents. Why not create your first one?</p>
<a href="{% url 'create_agent' %}" class="btn btn-primary btn-lg mt-3">Create an Agent</a>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends 'base.html' %}
{% block content %}
<h2>Create a New Account</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}

View File

@ -1,8 +1,15 @@
from django.urls import path from django.urls import path
from .views import home, create_agent from .views import home, create_agent, my_agents, publish_agent, delete_agent, edit_agent, agent_detail, signup, CustomLoginView
urlpatterns = [ urlpatterns = [
path("", home, name="home"), path("", home, name="home"),
path("signup/", signup, name="signup"),
path("login/", CustomLoginView.as_view(), name="login"),
path("create-agent/", create_agent, name="create_agent"), path("create-agent/", create_agent, name="create_agent"),
path("my-agents/", my_agents, name="my_agents"),
path("agents/<int:agent_id>/publish/", publish_agent, name="publish_agent"),
path("agents/<int:agent_id>/delete/", delete_agent, name="delete_agent"),
path("agents/<int:agent_id>/edit/", edit_agent, name="edit_agent"),
path("agent/<int:agent_id>/", agent_detail, name="agent_detail"),
] ]

View File

@ -2,15 +2,25 @@ import os
import platform import platform
from django import get_version as django_version from django import get_version as django_version
from django.shortcuts import render from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from django.http import JsonResponse from django.http import JsonResponse
from django.utils import timezone from django.utils import timezone
from .models import Agent
from .forms import SignUpForm
from django.contrib.auth import login
from django.contrib.auth import views as auth_views
class CustomLoginView(auth_views.LoginView):
template_name = 'core/login.html'
def home(request): def home(request):
"""Render the landing screen with loader and environment details.""" """Render the landing screen with loader and environment details."""
host_name = request.get_host().lower() host_name = request.get_host().lower()
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
now = timezone.now() now = timezone.now()
published_agents = Agent.objects.filter(published=True)
context = { context = {
"project_name": "New Style", "project_name": "New Style",
@ -21,14 +31,59 @@ def home(request):
"host_name": host_name, "host_name": host_name,
"project_description": os.getenv("PROJECT_DESCRIPTION", ""), "project_description": os.getenv("PROJECT_DESCRIPTION", ""),
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
"agents": published_agents,
} }
return render(request, "core/index.html", context) return render(request, "core/index.html", context)
@login_required
def create_agent(request): def create_agent(request):
# This is the agent creation view
if request.method == 'POST': if request.method == 'POST':
message = request.POST.get('message', '') name = request.POST.get('name')
# Simple echo response for now description = request.POST.get('description')
response_message = f"This is a simulated response to: '{message}'" agent = Agent.objects.create(name=name, description=description, owner=request.user)
return JsonResponse({'message': response_message}) return redirect('my_agents')
return render(request, "core/create_agent.html") return render(request, "core/create_agent.html")
@login_required
def my_agents(request):
agents = Agent.objects.filter(owner=request.user)
return render(request, "core/my_agents.html", {"agents": agents})
@login_required
def publish_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, owner=request.user)
agent.published = not agent.published
agent.save()
return redirect('my_agents')
@login_required
@require_POST
def delete_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, owner=request.user)
agent.delete()
return redirect('my_agents')
@login_required
def edit_agent(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id, owner=request.user)
if request.method == 'POST':
agent.name = request.POST.get('name')
agent.description = request.POST.get('description')
agent.save()
return redirect('my_agents')
return render(request, 'core/edit_agent.html', {'agent': agent})
def agent_detail(request, agent_id):
agent = get_object_or_404(Agent, id=agent_id)
return render(request, 'core/article_detail.html', {'agent': agent})
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'core/signup.html', {'form': form})

View File

@ -122,6 +122,10 @@ a:hover {
} }
.agent-card-link {
text-decoration: none;
color: inherit;
}
/* Chat Interface */ /* Chat Interface */