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
-
37apps/agent/models.py
@ -1,61 +1,57 @@ |
|||||
|
from django.contrib import admin |
||||
|
from django.db import models |
||||
from django.shortcuts import redirect |
from django.shortcuts import redirect |
||||
from django.urls import reverse |
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 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 AgentSettingsAdmin(ModelAdmin): |
|
||||
""" |
|
||||
Singleton Admin for Agent Configuration. |
|
||||
Acts as a 'Settings Page' by redirecting list view to the edit page of ID=1. |
|
||||
""" |
|
||||
|
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): |
||||
def has_add_permission(self, request): |
def has_add_permission(self, request): |
||||
# Disable 'Add' button to prevent creating multiple configs |
|
||||
return False |
return False |
||||
|
|
||||
def has_delete_permission(self, request, obj=None): |
def has_delete_permission(self, request, obj=None): |
||||
# Disable 'Delete' button to ensure settings always exist |
|
||||
return False |
return False |
||||
|
|
||||
def changelist_view(self, request, extra_context=None): |
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( |
url = reverse( |
||||
f"{self.admin_site.name}:{self.model._meta.app_label}_{self.model._meta.model_name}_change", |
f"{self.admin_site.name}:{self.model._meta.app_label}_{self.model._meta.model_name}_change", |
||||
args=[obj.pk] |
args=[obj.pk] |
||||
) |
) |
||||
|
|
||||
return redirect(url) |
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." |
|
||||
}), |
|
||||
) |
|
||||
|
|
||||
|
|
||||
# Register with your custom admin site |
|
||||
|
inlines = [AgentPromptInline] |
||||
|
|
||||
|
# Register |
||||
dovoodi_admin_site.register(AgentSettings, AgentSettingsAdmin) |
dovoodi_admin_site.register(AgentSettings, AgentSettingsAdmin) |
||||
project_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