Browse Source
Refactor Agent app to enhance settings management and introduce prompts
Refactor Agent app to enhance settings management and introduce prompts
- Updated `AgentSettings` model to serve as a singleton container, removing unnecessary fields and adding an `updated_at` timestamp. - Introduced `AgentPrompt` model to manage instruction prompts associated with agent settings. - Enhanced `AgentSettingsAdmin` to include inline management of prompts, improving the admin interface for better usability. - Created migrations to reflect the updated model structure and ensure database integrity.master
4 changed files with 156 additions and 53 deletions
-
76apps/agent/admin.py
-
56apps/agent/migrations/0002_alter_agentsettings_options_and_more.py
-
38apps/agent/migrations/0003_alter_agentprompt_options_and_more.py
-
39apps/agent/models.py
@ -1,61 +1,57 @@ |
|||
from django.contrib import admin |
|||
from django.db import models |
|||
from django.shortcuts import redirect |
|||
from django.urls import reverse |
|||
from unfold.admin import ModelAdmin |
|||
|
|||
from unfold.admin import ModelAdmin, TabularInline |
|||
from utils.admin import dovoodi_admin_site, project_admin_site |
|||
from apps.agent.models import AgentSettings |
|||
|
|||
from .models import AgentSettings, AgentPrompt |
|||
from unfold.contrib.forms.widgets import WysiwygWidget |
|||
|
|||
|
|||
class AgentPromptInline(TabularInline): |
|||
model = AgentPrompt |
|||
extra = 0 |
|||
fields = ('is_active', 'content') |
|||
|
|||
formfield_overrides = { |
|||
models.TextField: { |
|||
'widget': admin.widgets.AdminTextareaWidget(attrs={ |
|||
# 1. REDUCE HEIGHT: Set rows to 1 or 2 |
|||
'rows': 2, |
|||
|
|||
# 🎨 STYLING |
|||
# w-full: Fills the available space |
|||
# bg-black: Black background |
|||
# text-white: White text (Fixed typo from 'text-blacka') |
|||
# border-gray-600: Border color |
|||
# leading-normal: Adjusts line height for better vertical centering |
|||
'class': 'w-full p-2 border rounded-md bg-black text-white border-gray-600 focus:ring-primary-500 focus:border-primary-500 leading-normal', |
|||
|
|||
'placeholder': 'Enter instruction prompt here...', |
|||
|
|||
# 2. INCREASE WIDTH: 'min-width' forces the table cell to expand |
|||
'style': 'width: 100%; min-width: 600px; resize: vertical;' |
|||
}) |
|||
}, |
|||
} |
|||
|
|||
class AgentSettingsAdmin(ModelAdmin): |
|||
""" |
|||
Singleton Admin for Agent Configuration. |
|||
Acts as a 'Settings Page' by redirecting list view to the edit page of ID=1. |
|||
""" |
|||
|
|||
def has_add_permission(self, request): |
|||
# Disable 'Add' button to prevent creating multiple configs |
|||
return False |
|||
|
|||
def has_delete_permission(self, request, obj=None): |
|||
# Disable 'Delete' button to ensure settings always exist |
|||
return False |
|||
|
|||
def changelist_view(self, request, extra_context=None): |
|||
""" |
|||
Redirect the 'List View' directly to the 'Edit View' of ID=1. |
|||
Auto-creates the default config if it doesn't exist. |
|||
""" |
|||
# Ensure ID=1 exists |
|||
obj, created = self.model.objects.get_or_create(pk=1, defaults={ |
|||
"system_prompt": "You are a helpful assistant.", |
|||
}) |
|||
|
|||
# Build the URL dynamically based on the registered admin site |
|||
obj, created = self.model.objects.get_or_create(pk=1) |
|||
url = reverse( |
|||
f"{self.admin_site.name}:{self.model._meta.app_label}_{self.model._meta.model_name}_change", |
|||
args=[obj.pk] |
|||
) |
|||
|
|||
return redirect(url) |
|||
|
|||
fieldsets = ( |
|||
("Status", { |
|||
"fields": ("is_maintenance_mode",), |
|||
"classes": ("tab",), |
|||
}), |
|||
("Brain (System Instructions)", { |
|||
"fields": ("system_prompt",), |
|||
"classes": ("tab",), |
|||
"description": "Define the core personality and rules for the AI Agent." |
|||
}), |
|||
("Model Parameters", { |
|||
"fields": ("model_id", "temperature"), |
|||
"classes": ("tab",), |
|||
"description": "Technical settings for the inference engine." |
|||
}), |
|||
) |
|||
|
|||
inlines = [AgentPromptInline] |
|||
|
|||
# Register with your custom admin site |
|||
# Register |
|||
dovoodi_admin_site.register(AgentSettings, AgentSettingsAdmin) |
|||
project_admin_site.register(AgentSettings, AgentSettingsAdmin) |
|||
@ -0,0 +1,56 @@ |
|||
# Generated by Django 4.2.27 on 2026-02-15 13:58 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('agent', '0001_initial'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterModelOptions( |
|||
name='agentsettings', |
|||
options={'verbose_name': 'Agent Control Panel', 'verbose_name_plural': 'Agent Control Panel'}, |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentsettings', |
|||
name='model_id', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentsettings', |
|||
name='system_prompt', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentsettings', |
|||
name='temperature', |
|||
), |
|||
migrations.AddField( |
|||
model_name='agentsettings', |
|||
name='updated_at', |
|||
field=models.DateTimeField(auto_now=True), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='agentsettings', |
|||
name='is_maintenance_mode', |
|||
field=models.BooleanField(default=False, help_text='If checked, the agent will reply with a maintenance message.'), |
|||
), |
|||
migrations.CreateModel( |
|||
name='AgentPrompt', |
|||
fields=[ |
|||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('title', models.CharField(help_text="Internal Label (e.g., 'Core Identity')", max_length=100)), |
|||
('content', models.TextField(help_text='The actual instruction text.')), |
|||
('is_active', models.BooleanField(default=True)), |
|||
('order', models.PositiveIntegerField(default=0, help_text='Order of injection (1, 2, 3...)')), |
|||
('settings', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prompts', to='agent.agentsettings')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'System Instruction', |
|||
'verbose_name_plural': 'System Instructions', |
|||
'ordering': ['order'], |
|||
}, |
|||
), |
|||
] |
|||
@ -0,0 +1,38 @@ |
|||
# Generated by Django 4.2.27 on 2026-02-15 14:08 |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('agent', '0002_alter_agentsettings_options_and_more'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterModelOptions( |
|||
name='agentprompt', |
|||
options={}, |
|||
), |
|||
migrations.AlterModelOptions( |
|||
name='agentsettings', |
|||
options={'verbose_name': 'Agent Configuration', 'verbose_name_plural': 'Agent Configuration'}, |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentprompt', |
|||
name='order', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentprompt', |
|||
name='title', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='agentsettings', |
|||
name='is_maintenance_mode', |
|||
), |
|||
migrations.AlterField( |
|||
model_name='agentprompt', |
|||
name='content', |
|||
field=models.TextField(help_text='The instruction text.'), |
|||
), |
|||
] |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue