From 88be54298d30d49568c148672c1b8aca1b308177 Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Sun, 15 Feb 2026 12:46:07 +0330 Subject: [PATCH] Add initial implementation of Agent app with settings management - Created `Agent` app including models, admin configuration, and migrations for managing agent settings. - Introduced `AgentSettings` model to store configuration parameters such as system prompt and model settings. - Implemented `AgentSettingsAdmin` to provide a singleton admin interface for managing agent configurations. - Registered the app in the project settings for integration. --- apps/agent/__init__.py | 0 apps/agent/admin.py | 61 +++++++++++++++++++++++++++ apps/agent/apps.py | 6 +++ apps/agent/migrations/0001_initial.py | 28 ++++++++++++ apps/agent/migrations/__init__.py | 0 apps/agent/models.py | 32 ++++++++++++++ config/settings/base.py | 1 + 7 files changed, 128 insertions(+) create mode 100644 apps/agent/__init__.py create mode 100644 apps/agent/admin.py create mode 100644 apps/agent/apps.py create mode 100644 apps/agent/migrations/0001_initial.py create mode 100644 apps/agent/migrations/__init__.py create mode 100644 apps/agent/models.py diff --git a/apps/agent/__init__.py b/apps/agent/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/agent/admin.py b/apps/agent/admin.py new file mode 100644 index 0000000..b2bfe65 --- /dev/null +++ b/apps/agent/admin.py @@ -0,0 +1,61 @@ +from django.shortcuts import redirect +from django.urls import reverse +from unfold.admin import ModelAdmin + +from utils.admin import dovoodi_admin_site, project_admin_site +from apps.agent.models import AgentSettings + + +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 + 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." + }), + ) + + +# Register with your custom admin site +dovoodi_admin_site.register(AgentSettings, AgentSettingsAdmin) +project_admin_site.register(AgentSettings, AgentSettingsAdmin) \ No newline at end of file diff --git a/apps/agent/apps.py b/apps/agent/apps.py new file mode 100644 index 0000000..2c93b8c --- /dev/null +++ b/apps/agent/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AgentConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.agent' diff --git a/apps/agent/migrations/0001_initial.py b/apps/agent/migrations/0001_initial.py new file mode 100644 index 0000000..0a5a32c --- /dev/null +++ b/apps/agent/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.27 on 2026-02-14 15:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='AgentSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('system_prompt', models.TextField(default='You are a helpful assistant.')), + ('model_id', models.CharField(default='deepseek/deepseek-r1', max_length=50)), + ('temperature', models.FloatField(default=0.3)), + ('is_maintenance_mode', models.BooleanField(default=False)), + ], + options={ + 'verbose_name': 'Agent Configuration', + 'verbose_name_plural': 'Agent Configuration', + }, + ), + ] diff --git a/apps/agent/migrations/__init__.py b/apps/agent/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/agent/models.py b/apps/agent/models.py new file mode 100644 index 0000000..c70e22a --- /dev/null +++ b/apps/agent/models.py @@ -0,0 +1,32 @@ +from django.db import models +from django.core.cache import cache + + +class AgentSettings(models.Model): + # Fixed Settings + system_prompt = models.TextField(default="You are a helpful assistant.") + model_id = models.CharField(max_length=50, default="deepseek/deepseek-r1") + temperature = models.FloatField(default=0.3) + + # Switches + is_maintenance_mode = models.BooleanField(default=False) + + class Meta: + verbose_name = "Agent Configuration" + verbose_name_plural = "Agent Configuration" + + def save(self, *args, **kwargs): + self.pk = 1 + super().save(*args, **kwargs) + + # Clear cache whenever you save + cache.delete("agent_config_1") + + def __str__(self): + return "Global Agent Settings" + + @classmethod + def load(cls): + """Helper to get the singleton instance, creating it if missing.""" + obj, created = cls.objects.get_or_create(pk=1) + return obj \ No newline at end of file diff --git a/config/settings/base.py b/config/settings/base.py index 07a0be2..5482d9f 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -57,6 +57,7 @@ LOCAL_APPS = [ 'apps.article.apps.ArticleConfig', 'apps.dobodbi_calendar.apps.DobodbiCalendarConfig', 'apps.blog.apps.BlogConfig', + 'apps.agent.apps.AgentConfig', 'dynamic_preferences', 'apps.geolocation_package',