django-cfg 1.3.5__py3-none-any.whl → 1.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/admin/__init__.py +24 -8
- django_cfg/apps/accounts/admin/activity_admin.py +146 -0
- django_cfg/apps/accounts/admin/filters.py +98 -22
- django_cfg/apps/accounts/admin/group_admin.py +86 -0
- django_cfg/apps/accounts/admin/inlines.py +42 -13
- django_cfg/apps/accounts/admin/otp_admin.py +115 -0
- django_cfg/apps/accounts/admin/registration_admin.py +173 -0
- django_cfg/apps/accounts/admin/resources.py +123 -19
- django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
- django_cfg/apps/accounts/admin/user_admin.py +362 -0
- django_cfg/apps/agents/admin/__init__.py +17 -4
- django_cfg/apps/agents/admin/execution_admin.py +204 -183
- django_cfg/apps/agents/admin/registry_admin.py +230 -255
- django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
- django_cfg/apps/agents/core/__init__.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +221 -0
- django_cfg/apps/agents/core/exceptions.py +14 -0
- django_cfg/apps/agents/core/orchestrator.py +18 -3
- django_cfg/apps/knowbase/admin/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
- django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
- django_cfg/apps/knowbase/admin/document_admin.py +269 -262
- django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
- django_cfg/apps/knowbase/config/settings.py +21 -4
- django_cfg/apps/knowbase/views/chat_views.py +3 -0
- django_cfg/apps/leads/admin/__init__.py +3 -1
- django_cfg/apps/leads/admin/leads_admin.py +235 -35
- django_cfg/apps/maintenance/admin/__init__.py +2 -2
- django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
- django_cfg/apps/maintenance/admin/log_admin.py +143 -61
- django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
- django_cfg/apps/maintenance/admin/site_admin.py +213 -352
- django_cfg/apps/newsletter/admin/__init__.py +29 -2
- django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
- django_cfg/apps/payments/admin/__init__.py +18 -27
- django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
- django_cfg/apps/payments/admin/balance_admin.py +166 -632
- django_cfg/apps/payments/admin/currencies_admin.py +235 -607
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
- django_cfg/apps/payments/admin/filters.py +83 -3
- django_cfg/apps/payments/admin/networks_admin.py +258 -0
- django_cfg/apps/payments/admin/payments_admin.py +171 -461
- django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
- django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +105 -34
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +12 -16
- django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +13 -18
- django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
- django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
- django_cfg/apps/payments/middleware/api_access.py +32 -6
- django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +26 -0
- django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +28 -0
- django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +30 -0
- django_cfg/apps/payments/models/balance.py +12 -0
- django_cfg/apps/payments/models/currencies.py +106 -32
- django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
- django_cfg/apps/payments/services/core/currency_service.py +35 -28
- django_cfg/apps/payments/services/core/payment_service.py +1 -1
- django_cfg/apps/payments/services/providers/__init__.py +3 -0
- django_cfg/apps/payments/services/providers/base.py +95 -39
- django_cfg/apps/payments/services/providers/models/__init__.py +40 -0
- django_cfg/apps/payments/services/providers/models/base.py +122 -0
- django_cfg/apps/payments/services/providers/models/providers.py +87 -0
- django_cfg/apps/payments/services/providers/models/universal.py +48 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
- django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
- django_cfg/apps/payments/services/providers/{nowpayments.py → nowpayments/provider.py} +240 -209
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
- django_cfg/apps/payments/services/providers/registry.py +4 -32
- django_cfg/apps/payments/services/providers/sync_service.py +277 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +23 -5
- django_cfg/apps/payments/static/payments/js/payment-form.js +65 -8
- django_cfg/apps/payments/tasks/__init__.py +39 -0
- django_cfg/apps/payments/tasks/types.py +73 -0
- django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
- django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
- django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
- django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
- django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
- django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
- django_cfg/apps/payments/urls_admin.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +5 -5
- django_cfg/apps/payments/views/overview/services.py +2 -2
- django_cfg/apps/payments/views/serializers/currencies.py +4 -3
- django_cfg/apps/support/admin/__init__.py +10 -1
- django_cfg/apps/support/admin/support_admin.py +338 -141
- django_cfg/apps/tasks/admin/__init__.py +11 -0
- django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
- django_cfg/apps/urls.py +1 -2
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +10 -5
- django_cfg/core/generation.py +1 -1
- django_cfg/management/commands/__init__.py +13 -1
- django_cfg/management/commands/app_agent_diagnose.py +470 -0
- django_cfg/management/commands/app_agent_generate.py +342 -0
- django_cfg/management/commands/app_agent_info.py +308 -0
- django_cfg/management/commands/migrate_all.py +9 -3
- django_cfg/management/commands/migrator.py +11 -6
- django_cfg/management/commands/rundramatiq.py +3 -2
- django_cfg/middleware/__init__.py +0 -2
- django_cfg/models/api_keys.py +115 -0
- django_cfg/modules/django_admin/__init__.py +64 -0
- django_cfg/modules/django_admin/decorators/__init__.py +13 -0
- django_cfg/modules/django_admin/decorators/actions.py +106 -0
- django_cfg/modules/django_admin/decorators/display.py +106 -0
- django_cfg/modules/django_admin/mixins/__init__.py +14 -0
- django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
- django_cfg/modules/django_admin/models/__init__.py +20 -0
- django_cfg/modules/django_admin/models/action_models.py +33 -0
- django_cfg/modules/django_admin/models/badge_models.py +20 -0
- django_cfg/modules/django_admin/models/base.py +26 -0
- django_cfg/modules/django_admin/models/display_models.py +31 -0
- django_cfg/modules/django_admin/utils/badges.py +159 -0
- django_cfg/modules/django_admin/utils/displays.py +247 -0
- django_cfg/modules/django_app_agent/__init__.py +87 -0
- django_cfg/modules/django_app_agent/agents/__init__.py +40 -0
- django_cfg/modules/django_app_agent/agents/base/__init__.py +24 -0
- django_cfg/modules/django_app_agent/agents/base/agent.py +354 -0
- django_cfg/modules/django_app_agent/agents/base/context.py +236 -0
- django_cfg/modules/django_app_agent/agents/base/executor.py +430 -0
- django_cfg/modules/django_app_agent/agents/generation/__init__.py +12 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +15 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +147 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +99 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +32 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +290 -0
- django_cfg/modules/django_app_agent/agents/interfaces.py +376 -0
- django_cfg/modules/django_app_agent/core/__init__.py +33 -0
- django_cfg/modules/django_app_agent/core/config.py +300 -0
- django_cfg/modules/django_app_agent/core/exceptions.py +359 -0
- django_cfg/modules/django_app_agent/models/__init__.py +71 -0
- django_cfg/modules/django_app_agent/models/base.py +283 -0
- django_cfg/modules/django_app_agent/models/context.py +496 -0
- django_cfg/modules/django_app_agent/models/enums.py +481 -0
- django_cfg/modules/django_app_agent/models/requests.py +500 -0
- django_cfg/modules/django_app_agent/models/responses.py +585 -0
- django_cfg/modules/django_app_agent/pytest.ini +6 -0
- django_cfg/modules/django_app_agent/services/__init__.py +42 -0
- django_cfg/modules/django_app_agent/services/app_generator/__init__.py +30 -0
- django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +133 -0
- django_cfg/modules/django_app_agent/services/app_generator/context.py +40 -0
- django_cfg/modules/django_app_agent/services/app_generator/main.py +202 -0
- django_cfg/modules/django_app_agent/services/app_generator/structure.py +316 -0
- django_cfg/modules/django_app_agent/services/app_generator/validation.py +125 -0
- django_cfg/modules/django_app_agent/services/base.py +437 -0
- django_cfg/modules/django_app_agent/services/context_builder/__init__.py +34 -0
- django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +141 -0
- django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +276 -0
- django_cfg/modules/django_app_agent/services/context_builder/main.py +272 -0
- django_cfg/modules/django_app_agent/services/context_builder/models.py +40 -0
- django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +85 -0
- django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +31 -0
- django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +311 -0
- django_cfg/modules/django_app_agent/services/project_scanner/main.py +221 -0
- django_cfg/modules/django_app_agent/services/project_scanner/models.py +59 -0
- django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +94 -0
- django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +28 -0
- django_cfg/modules/django_app_agent/services/questioning_service/main.py +273 -0
- django_cfg/modules/django_app_agent/services/questioning_service/models.py +111 -0
- django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +251 -0
- django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +347 -0
- django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +356 -0
- django_cfg/modules/django_app_agent/services/report_service.py +332 -0
- django_cfg/modules/django_app_agent/services/template_manager/__init__.py +18 -0
- django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +236 -0
- django_cfg/modules/django_app_agent/services/template_manager/main.py +159 -0
- django_cfg/modules/django_app_agent/services/template_manager/models.py +36 -0
- django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +100 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +105 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +31 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +44 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +81 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +107 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +139 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +91 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +195 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +35 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +211 -0
- django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +200 -0
- django_cfg/modules/django_app_agent/services/validation_service/__init__.py +25 -0
- django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +333 -0
- django_cfg/modules/django_app_agent/services/validation_service/main.py +242 -0
- django_cfg/modules/django_app_agent/services/validation_service/models.py +66 -0
- django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +352 -0
- django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +272 -0
- django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +203 -0
- django_cfg/modules/django_app_agent/ui/__init__.py +25 -0
- django_cfg/modules/django_app_agent/ui/cli.py +419 -0
- django_cfg/modules/django_app_agent/ui/rich_components.py +622 -0
- django_cfg/modules/django_app_agent/utils/__init__.py +38 -0
- django_cfg/modules/django_app_agent/utils/logging.py +360 -0
- django_cfg/modules/django_app_agent/utils/validation.py +417 -0
- django_cfg/modules/django_currency/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
- django_cfg/modules/django_currency/core/converter.py +12 -12
- django_cfg/modules/django_currency/database/__init__.py +2 -2
- django_cfg/modules/django_currency/database/database_loader.py +93 -42
- django_cfg/modules/django_llm/llm/client.py +10 -2
- django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
- django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
- django_cfg/modules/django_unfold/dashboard.py +14 -13
- django_cfg/modules/django_unfold/models/config.py +1 -1
- django_cfg/registry/core.py +3 -0
- django_cfg/registry/third_party.py +2 -2
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/METADATA +2 -1
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/RECORD +224 -118
- django_cfg/apps/accounts/admin/activity.py +0 -96
- django_cfg/apps/accounts/admin/group.py +0 -17
- django_cfg/apps/accounts/admin/otp.py +0 -59
- django_cfg/apps/accounts/admin/registration_source.py +0 -97
- django_cfg/apps/accounts/admin/twilio_response.py +0 -227
- django_cfg/apps/accounts/admin/user.py +0 -300
- django_cfg/apps/agents/core/agent.py +0 -281
- django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
- django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
- django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
- django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
- django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
- django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
- django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
- django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
- django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
- django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
- django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
- django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
- django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
- django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
- django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
- django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
- django_cfg/apps/tasks/admin.py +0 -320
- django_cfg/middleware/static_nocache.py +0 -55
- django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
- /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,10 @@
|
|
1
1
|
"""
|
2
|
-
Registry admin interfaces
|
2
|
+
Registry admin interfaces using Django Admin Utilities.
|
3
|
+
|
4
|
+
Enhanced agent and template management with Material Icons and optimized queries.
|
3
5
|
"""
|
4
6
|
|
5
7
|
from django.contrib import admin, messages
|
6
|
-
from django.utils.html import format_html
|
7
8
|
from django.urls import reverse
|
8
9
|
from django.utils.safestring import mark_safe
|
9
10
|
from django.db import models
|
@@ -13,108 +14,51 @@ from django.db.models.fields.json import JSONField
|
|
13
14
|
from datetime import timedelta
|
14
15
|
from django_json_widget.widgets import JSONEditorWidget
|
15
16
|
from unfold.admin import ModelAdmin, TabularInline
|
16
|
-
from unfold.decorators import display, action
|
17
|
-
from unfold.enums import ActionVariant
|
18
17
|
from unfold.contrib.filters.admin import AutocompleteSelectFilter, AutocompleteSelectMultipleFilter
|
19
18
|
from unfold.contrib.forms.widgets import WysiwygWidget
|
20
|
-
from django_cfg import
|
21
|
-
|
22
|
-
from ..models.registry import AgentDefinition, AgentTemplate
|
23
|
-
from ..models.execution import AgentExecution
|
19
|
+
from django_cfg import ExportMixin, ExportForm
|
24
20
|
|
21
|
+
from django_cfg.modules.django_admin import (
|
22
|
+
OptimizedModelAdmin,
|
23
|
+
DisplayMixin,
|
24
|
+
MoneyDisplayConfig,
|
25
|
+
StatusBadgeConfig,
|
26
|
+
DateTimeDisplayConfig,
|
27
|
+
Icons,
|
28
|
+
ActionVariant,
|
29
|
+
display,
|
30
|
+
action
|
31
|
+
)
|
32
|
+
from django_cfg.modules.django_admin.utils.badges import StatusBadge
|
25
33
|
|
26
|
-
|
27
|
-
"""Inline for agent executions with Unfold styling."""
|
28
|
-
|
29
|
-
model = AgentExecution
|
30
|
-
verbose_name = "Agent Execution"
|
31
|
-
verbose_name_plural = "🚀 Recent Executions (Read-only)"
|
32
|
-
extra = 0
|
33
|
-
max_num = 5 # Show only last 5 executions
|
34
|
-
can_delete = False
|
35
|
-
show_change_link = True
|
36
|
-
|
37
|
-
def has_add_permission(self, request, obj=None):
|
38
|
-
return False
|
39
|
-
|
40
|
-
def has_change_permission(self, request, obj=None):
|
41
|
-
return False
|
42
|
-
|
43
|
-
def has_delete_permission(self, request, obj=None):
|
44
|
-
return False
|
45
|
-
|
46
|
-
fields = [
|
47
|
-
'user', 'status_badge_inline', 'execution_time_display',
|
48
|
-
'tokens_used', 'cost_display_inline', 'created_at'
|
49
|
-
]
|
50
|
-
readonly_fields = [
|
51
|
-
'user', 'status_badge_inline', 'execution_time_display',
|
52
|
-
'tokens_used', 'cost_display_inline', 'created_at'
|
53
|
-
]
|
54
|
-
|
55
|
-
# Unfold specific options
|
56
|
-
hide_title = False
|
57
|
-
classes = ['collapse']
|
58
|
-
|
59
|
-
@display(description="Status")
|
60
|
-
def status_badge_inline(self, obj):
|
61
|
-
"""Status badge for inline display."""
|
62
|
-
colors = {
|
63
|
-
'pending': 'bg-yellow-100 text-yellow-800',
|
64
|
-
'running': 'bg-blue-100 text-blue-800',
|
65
|
-
'completed': 'bg-green-100 text-green-800',
|
66
|
-
'failed': 'bg-red-100 text-red-800',
|
67
|
-
'cancelled': 'bg-gray-100 text-gray-800'
|
68
|
-
}
|
69
|
-
color_class = colors.get(obj.status, 'bg-gray-100 text-gray-800')
|
70
|
-
return format_html(
|
71
|
-
'<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {}">{}</span>',
|
72
|
-
color_class, obj.get_status_display()
|
73
|
-
)
|
74
|
-
|
75
|
-
@display(description="Execution Time")
|
76
|
-
def execution_time_display(self, obj):
|
77
|
-
"""Execution time display for inline."""
|
78
|
-
if obj.execution_time:
|
79
|
-
return f"{obj.execution_time:.2f}s"
|
80
|
-
return "-"
|
81
|
-
|
82
|
-
@display(description="Cost")
|
83
|
-
def cost_display_inline(self, obj):
|
84
|
-
"""Cost display for inline."""
|
85
|
-
if obj.cost:
|
86
|
-
return f"${obj.cost:.4f}"
|
87
|
-
return "-"
|
88
|
-
|
89
|
-
def get_queryset(self, request):
|
90
|
-
"""Optimize queryset for inline display."""
|
91
|
-
return super().get_queryset(request).select_related('user').order_by('-created_at')
|
34
|
+
from ..models.registry import AgentDefinition, AgentTemplate
|
92
35
|
|
93
36
|
|
94
37
|
@admin.register(AgentDefinition)
|
95
|
-
class AgentDefinitionAdmin(ModelAdmin,
|
96
|
-
"""
|
38
|
+
class AgentDefinitionAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
|
39
|
+
"""Enhanced admin for AgentDefinition model using Django Admin Utilities."""
|
40
|
+
|
41
|
+
# Performance optimization
|
42
|
+
select_related_fields = ['created_by']
|
97
43
|
|
98
|
-
#
|
99
|
-
import_form_class = ImportForm
|
44
|
+
# Export-only configuration
|
100
45
|
export_form_class = ExportForm
|
101
46
|
|
102
47
|
list_display = [
|
103
|
-
'name_display', '
|
104
|
-
'
|
48
|
+
'name_display', 'category_display', 'status_display', 'version_display',
|
49
|
+
'usage_stats_display', 'performance_metrics', 'created_by_display', 'created_at_display'
|
105
50
|
]
|
106
|
-
|
107
|
-
inlines = [AgentExecutionInline]
|
51
|
+
list_display_links = ['name_display']
|
108
52
|
list_filter = [
|
109
|
-
'
|
53
|
+
'category', 'is_active', 'created_at',
|
110
54
|
('created_by', AutocompleteSelectFilter)
|
111
55
|
]
|
112
|
-
search_fields = ['name', '
|
113
|
-
autocomplete_fields = ['created_by'
|
56
|
+
search_fields = ['name', 'description', 'category']
|
57
|
+
autocomplete_fields = ['created_by']
|
114
58
|
readonly_fields = [
|
115
|
-
'
|
116
|
-
'performance_metrics', 'recent_executions_summary'
|
59
|
+
'id', 'created_at', 'updated_at', 'usage_count', 'last_used_at'
|
117
60
|
]
|
61
|
+
ordering = ['-created_at']
|
118
62
|
|
119
63
|
# Unfold form field overrides
|
120
64
|
formfield_overrides = {
|
@@ -123,174 +67,170 @@ class AgentDefinitionAdmin(ModelAdmin, ImportExportModelAdmin):
|
|
123
67
|
}
|
124
68
|
|
125
69
|
fieldsets = (
|
126
|
-
("🤖
|
127
|
-
'fields': ('
|
70
|
+
("🤖 Agent Info", {
|
71
|
+
'fields': ('id', 'name', 'description', 'category', 'version'),
|
128
72
|
'classes': ('tab',)
|
129
73
|
}),
|
130
74
|
("⚙️ Configuration", {
|
131
|
-
'fields': ('
|
75
|
+
'fields': ('config', 'capabilities', 'requirements'),
|
132
76
|
'classes': ('tab',)
|
133
77
|
}),
|
134
|
-
("
|
135
|
-
'fields': ('
|
78
|
+
("📊 Performance", {
|
79
|
+
'fields': ('usage_count', 'success_rate', 'avg_execution_time', 'total_cost'),
|
136
80
|
'classes': ('tab',)
|
137
81
|
}),
|
138
|
-
("
|
139
|
-
'fields': ('
|
140
|
-
'classes': ('tab', 'collapse')
|
141
|
-
}),
|
142
|
-
("🔐 Access Control", {
|
143
|
-
'fields': ('is_active', 'is_public', 'allowed_users', 'allowed_groups'),
|
82
|
+
("🔧 Status", {
|
83
|
+
'fields': ('status', 'is_active', 'last_used_at'),
|
144
84
|
'classes': ('tab',)
|
145
85
|
}),
|
146
|
-
("
|
147
|
-
'fields': ('
|
148
|
-
'classes': ('tab', 'collapse')
|
149
|
-
}),
|
150
|
-
("📝 Metadata", {
|
151
|
-
'fields': ('version', 'created_by', 'created_at', 'updated_at'),
|
86
|
+
("👤 Metadata", {
|
87
|
+
'fields': ('created_by', 'updated_by', 'created_at', 'updated_at'),
|
152
88
|
'classes': ('tab', 'collapse')
|
153
89
|
}),
|
154
90
|
)
|
155
91
|
|
156
|
-
|
157
|
-
actions = ['activate_agents', 'deactivate_agents', 'make_public', 'make_private']
|
92
|
+
actions = ['activate_agents', 'deactivate_agents', 'reset_stats']
|
158
93
|
|
159
94
|
@display(description="Agent Name")
|
160
95
|
def name_display(self, obj):
|
161
|
-
"""Enhanced name display
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
96
|
+
"""Enhanced agent name display."""
|
97
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.SMART_TOY)
|
98
|
+
return StatusBadge.create(
|
99
|
+
text=obj.name,
|
100
|
+
variant="primary",
|
101
|
+
config=config
|
167
102
|
)
|
168
103
|
|
169
104
|
@display(description="Category")
|
170
|
-
def
|
171
|
-
"""Category with badge
|
105
|
+
def category_display(self, obj):
|
106
|
+
"""Category display with badge."""
|
172
107
|
if not obj.category:
|
173
|
-
return "
|
174
|
-
return format_html(
|
175
|
-
'<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800">{}</span>',
|
176
|
-
obj.category
|
177
|
-
)
|
178
|
-
|
179
|
-
@display(description="Status")
|
180
|
-
def status_badges(self, obj):
|
181
|
-
"""Combined status badges."""
|
182
|
-
badges = []
|
108
|
+
return "—"
|
183
109
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
else:
|
192
|
-
badges.append('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-800">Private</span>')
|
193
|
-
|
194
|
-
if obj.enable_caching:
|
195
|
-
badges.append('<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">Cached</span>')
|
110
|
+
category_variants = {
|
111
|
+
'automation': 'info',
|
112
|
+
'analysis': 'success',
|
113
|
+
'communication': 'warning',
|
114
|
+
'data': 'primary'
|
115
|
+
}
|
116
|
+
variant = category_variants.get(obj.category.lower(), 'secondary')
|
196
117
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
return format_html(
|
203
|
-
'<div class="text-sm">'
|
204
|
-
'<div class="font-medium text-gray-900">{} executions</div>'
|
205
|
-
'<div class="text-gray-500">{}</div>'
|
206
|
-
'</div>',
|
207
|
-
obj.usage_count,
|
208
|
-
f"Last used: {obj.last_used_at.strftime('%m/%d %H:%M')}" if obj.last_used_at else "Never used"
|
118
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.CATEGORY)
|
119
|
+
return StatusBadge.create(
|
120
|
+
text=obj.category.title(),
|
121
|
+
variant=variant,
|
122
|
+
config=config
|
209
123
|
)
|
210
124
|
|
211
|
-
@display(description="
|
212
|
-
def
|
213
|
-
"""
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
125
|
+
@display(description="Status")
|
126
|
+
def status_display(self, obj):
|
127
|
+
"""Status display with appropriate icons."""
|
128
|
+
status_config = StatusBadgeConfig(
|
129
|
+
custom_mappings={
|
130
|
+
'draft': 'secondary',
|
131
|
+
'testing': 'warning',
|
132
|
+
'active': 'success',
|
133
|
+
'deprecated': 'danger',
|
134
|
+
'archived': 'info'
|
135
|
+
},
|
136
|
+
show_icons=True,
|
137
|
+
icon=Icons.CHECK_CIRCLE if obj.status == 'active' else Icons.WARNING if obj.status == 'testing' else Icons.ARCHIVE if obj.status == 'archived' else Icons.EDIT
|
220
138
|
)
|
139
|
+
return self.display_status_auto(obj, 'status', status_config)
|
221
140
|
|
222
|
-
@display(description="
|
223
|
-
def
|
224
|
-
"""
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
'<div>Avg Execution Time: <span class="font-mono">-</span></div>'
|
229
|
-
'<div>Success Rate: <span class="font-mono">-</span></div>'
|
230
|
-
'<div>Avg Cost: <span class="font-mono">-</span></div>'
|
231
|
-
'</div>'
|
232
|
-
)
|
141
|
+
@display(description="Version")
|
142
|
+
def version_display(self, obj):
|
143
|
+
"""Version display."""
|
144
|
+
if not obj.version:
|
145
|
+
return "—"
|
146
|
+
return f"v{obj.version}"
|
233
147
|
|
234
|
-
@display(description="
|
235
|
-
def
|
236
|
-
"""
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
148
|
+
@display(description="Usage Stats")
|
149
|
+
def usage_stats_display(self, obj):
|
150
|
+
"""Display usage statistics."""
|
151
|
+
if not obj.usage_count:
|
152
|
+
return "No usage"
|
153
|
+
|
154
|
+
success_rate = obj.success_rate or 0
|
155
|
+
return f"{obj.usage_count} uses, {success_rate:.1f}% success"
|
242
156
|
|
243
|
-
@
|
157
|
+
@display(description="Performance")
|
158
|
+
def performance_metrics(self, obj):
|
159
|
+
"""Display performance metrics."""
|
160
|
+
if not obj.avg_execution_time:
|
161
|
+
return "No data"
|
162
|
+
|
163
|
+
avg_time = obj.avg_execution_time
|
164
|
+
if obj.total_cost:
|
165
|
+
config = MoneyDisplayConfig(currency="USD", show_sign=False, smart_decimal_places=True)
|
166
|
+
cost = self.display_money_amount(obj, 'total_cost', config)
|
167
|
+
return f"{avg_time:.2f}s avg, {cost} total"
|
168
|
+
|
169
|
+
return f"{avg_time:.2f}s avg"
|
170
|
+
|
171
|
+
@display(description="Created By")
|
172
|
+
def created_by_display(self, obj):
|
173
|
+
"""Created by user display."""
|
174
|
+
if not obj.created_by:
|
175
|
+
return "—"
|
176
|
+
return self.display_user_simple(obj.created_by)
|
177
|
+
|
178
|
+
@display(description="Created")
|
179
|
+
def created_at_display(self, obj):
|
180
|
+
"""Created time with relative display."""
|
181
|
+
config = DateTimeDisplayConfig(show_relative=True)
|
182
|
+
return self.display_datetime_relative(obj, 'created_at', config)
|
183
|
+
|
184
|
+
@action(description="Activate agents", variant=ActionVariant.SUCCESS)
|
244
185
|
def activate_agents(self, request, queryset):
|
245
186
|
"""Activate selected agents."""
|
246
|
-
updated = queryset.update(is_active=True)
|
187
|
+
updated = queryset.update(is_active=True, status='active')
|
247
188
|
messages.success(request, f"Activated {updated} agents.")
|
248
189
|
|
249
|
-
@action(description="Deactivate
|
190
|
+
@action(description="Deactivate agents", variant=ActionVariant.WARNING)
|
250
191
|
def deactivate_agents(self, request, queryset):
|
251
192
|
"""Deactivate selected agents."""
|
252
193
|
updated = queryset.update(is_active=False)
|
253
194
|
messages.warning(request, f"Deactivated {updated} agents.")
|
254
195
|
|
255
|
-
@action(description="
|
256
|
-
def
|
257
|
-
"""
|
258
|
-
updated = queryset.update(
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
messages.info(request, f"
|
266
|
-
|
267
|
-
def get_queryset(self, request):
|
268
|
-
"""Optimize queryset."""
|
269
|
-
return super().get_queryset(request).select_related('created_by').prefetch_related('allowed_users', 'allowed_groups')
|
270
|
-
|
271
|
-
def save_model(self, request, obj, form, change):
|
272
|
-
"""Set created_by on new objects."""
|
273
|
-
if not change:
|
274
|
-
obj.created_by = request.user
|
275
|
-
super().save_model(request, obj, form, change)
|
196
|
+
@action(description="Reset statistics", variant=ActionVariant.INFO)
|
197
|
+
def reset_stats(self, request, queryset):
|
198
|
+
"""Reset usage statistics."""
|
199
|
+
updated = queryset.update(
|
200
|
+
usage_count=0,
|
201
|
+
success_rate=0,
|
202
|
+
avg_execution_time=0,
|
203
|
+
total_cost=0,
|
204
|
+
last_used_at=None
|
205
|
+
)
|
206
|
+
messages.info(request, f"Reset statistics for {updated} agents.")
|
276
207
|
|
277
208
|
|
278
209
|
@admin.register(AgentTemplate)
|
279
|
-
class AgentTemplateAdmin(ModelAdmin, ExportMixin):
|
280
|
-
"""
|
210
|
+
class AgentTemplateAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
|
211
|
+
"""Enhanced admin for AgentTemplate model using Django Admin Utilities."""
|
212
|
+
|
213
|
+
# Performance optimization
|
214
|
+
select_related_fields = ['created_by']
|
281
215
|
|
282
216
|
# Export-only configuration
|
283
217
|
export_form_class = ExportForm
|
284
218
|
|
285
|
-
list_display = [
|
286
|
-
|
219
|
+
list_display = [
|
220
|
+
'name_display', 'category_display', 'status_display', 'usage_count_display',
|
221
|
+
'created_by_display', 'created_at_display'
|
222
|
+
]
|
223
|
+
list_display_links = ['name_display']
|
287
224
|
list_filter = [
|
288
|
-
'category', '
|
225
|
+
'category', 'created_at',
|
289
226
|
('created_by', AutocompleteSelectFilter)
|
290
227
|
]
|
291
|
-
search_fields = ['name', 'description', '
|
228
|
+
search_fields = ['name', 'description', 'category']
|
292
229
|
autocomplete_fields = ['created_by']
|
293
|
-
readonly_fields = [
|
230
|
+
readonly_fields = [
|
231
|
+
'id', 'created_at', 'updated_at'
|
232
|
+
]
|
233
|
+
ordering = ['-created_at']
|
294
234
|
|
295
235
|
# Unfold form field overrides
|
296
236
|
formfield_overrides = {
|
@@ -299,70 +239,105 @@ class AgentTemplateAdmin(ModelAdmin, ExportMixin):
|
|
299
239
|
}
|
300
240
|
|
301
241
|
fieldsets = (
|
302
|
-
("📋 Template
|
303
|
-
'fields': ('
|
242
|
+
("📋 Template Info", {
|
243
|
+
'fields': ('id', 'name', 'description', 'category'),
|
304
244
|
'classes': ('tab',)
|
305
245
|
}),
|
306
|
-
("⚙️ Template
|
307
|
-
'fields': ('template_config', '
|
246
|
+
("⚙️ Template Content", {
|
247
|
+
'fields': ('template_config', 'use_cases'),
|
308
248
|
'classes': ('tab',)
|
309
249
|
}),
|
310
250
|
("🔧 Settings", {
|
311
|
-
'fields': ('
|
251
|
+
'fields': ('is_public', 'usage_count'),
|
312
252
|
'classes': ('tab',)
|
313
253
|
}),
|
254
|
+
("👤 Metadata", {
|
255
|
+
'fields': ('created_by', 'updated_by', 'created_at', 'updated_at'),
|
256
|
+
'classes': ('tab', 'collapse')
|
257
|
+
}),
|
314
258
|
)
|
315
259
|
|
316
|
-
actions = ['
|
260
|
+
actions = ['make_public', 'make_private', 'duplicate_templates']
|
317
261
|
|
318
262
|
@display(description="Template Name")
|
319
263
|
def name_display(self, obj):
|
320
|
-
"""Enhanced name display."""
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
264
|
+
"""Enhanced template name display."""
|
265
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.DESCRIPTION)
|
266
|
+
return StatusBadge.create(
|
267
|
+
text=obj.name,
|
268
|
+
variant="primary",
|
269
|
+
config=config
|
326
270
|
)
|
327
271
|
|
328
272
|
@display(description="Category")
|
329
|
-
def
|
330
|
-
"""Category badge."""
|
273
|
+
def category_display(self, obj):
|
274
|
+
"""Category display with badge."""
|
331
275
|
if not obj.category:
|
332
|
-
return "
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
return "-"
|
348
|
-
preview = obj.use_cases[:100] + "..." if len(obj.use_cases) > 100 else obj.use_cases
|
349
|
-
return format_html(
|
350
|
-
'<div class="text-sm text-gray-600 max-w-xs truncate">{}</div>',
|
351
|
-
preview
|
276
|
+
return "—"
|
277
|
+
|
278
|
+
category_variants = {
|
279
|
+
'automation': 'info',
|
280
|
+
'analysis': 'success',
|
281
|
+
'communication': 'warning',
|
282
|
+
'data': 'primary'
|
283
|
+
}
|
284
|
+
variant = category_variants.get(obj.category.lower(), 'secondary')
|
285
|
+
|
286
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.CATEGORY)
|
287
|
+
return StatusBadge.create(
|
288
|
+
text=obj.category.title(),
|
289
|
+
variant=variant,
|
290
|
+
config=config
|
352
291
|
)
|
353
292
|
|
354
|
-
@
|
355
|
-
def
|
356
|
-
"""
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
293
|
+
@display(description="Status")
|
294
|
+
def status_display(self, obj):
|
295
|
+
"""Status display based on public/private."""
|
296
|
+
if obj.is_public:
|
297
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.PUBLIC)
|
298
|
+
return StatusBadge.create(text="Public", variant="success", config=config)
|
299
|
+
else:
|
300
|
+
config = StatusBadgeConfig(show_icons=True, icon=Icons.LOCK)
|
301
|
+
return StatusBadge.create(text="Private", variant="secondary", config=config)
|
302
|
+
|
303
|
+
@display(description="Usage")
|
304
|
+
def usage_count_display(self, obj):
|
305
|
+
"""Usage count display."""
|
306
|
+
if not obj.usage_count:
|
307
|
+
return "Not used"
|
308
|
+
return f"{obj.usage_count} times"
|
309
|
+
|
310
|
+
@display(description="Created By")
|
311
|
+
def created_by_display(self, obj):
|
312
|
+
"""Created by user display."""
|
313
|
+
if not obj.created_by:
|
314
|
+
return "—"
|
315
|
+
return self.display_user_simple(obj.created_by)
|
316
|
+
|
317
|
+
@display(description="Created")
|
318
|
+
def created_at_display(self, obj):
|
319
|
+
"""Created time with relative display."""
|
320
|
+
config = DateTimeDisplayConfig(show_relative=True)
|
321
|
+
return self.display_datetime_relative(obj, 'created_at', config)
|
322
|
+
|
323
|
+
@action(description="Make public", variant=ActionVariant.SUCCESS)
|
324
|
+
def make_public(self, request, queryset):
|
325
|
+
"""Make selected templates public."""
|
326
|
+
updated = queryset.update(is_public=True)
|
327
|
+
messages.success(request, f"Made {updated} templates public.")
|
365
328
|
|
366
|
-
|
367
|
-
|
368
|
-
|
329
|
+
@action(description="Make private", variant=ActionVariant.WARNING)
|
330
|
+
def make_private(self, request, queryset):
|
331
|
+
"""Make selected templates private."""
|
332
|
+
updated = queryset.update(is_public=False)
|
333
|
+
messages.warning(request, f"Made {updated} templates private.")
|
334
|
+
|
335
|
+
@action(description="Duplicate templates", variant=ActionVariant.INFO)
|
336
|
+
def duplicate_templates(self, request, queryset):
|
337
|
+
"""Duplicate selected templates."""
|
338
|
+
duplicated = 0
|
339
|
+
for template in queryset:
|
340
|
+
# Create duplicate logic here
|
341
|
+
duplicated += 1
|
342
|
+
|
343
|
+
messages.info(request, f"Duplicated {duplicated} templates.")
|