django-cfg 1.1.82__py3-none-any.whl → 1.2.1__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 +20 -448
- django_cfg/apps/accounts/README.md +3 -3
- django_cfg/apps/accounts/admin/__init__.py +0 -2
- django_cfg/apps/accounts/admin/activity.py +2 -9
- django_cfg/apps/accounts/admin/filters.py +0 -42
- django_cfg/apps/accounts/admin/inlines.py +8 -8
- django_cfg/apps/accounts/admin/otp.py +5 -5
- django_cfg/apps/accounts/admin/registration_source.py +1 -8
- django_cfg/apps/accounts/admin/user.py +12 -20
- django_cfg/apps/accounts/managers/user_manager.py +2 -129
- django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
- django_cfg/apps/accounts/models.py +3 -123
- django_cfg/apps/accounts/serializers/otp.py +40 -44
- django_cfg/apps/accounts/serializers/profile.py +0 -2
- django_cfg/apps/accounts/services/otp_service.py +98 -186
- django_cfg/apps/accounts/signals.py +25 -15
- django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
- django_cfg/apps/accounts/views/otp.py +35 -36
- django_cfg/apps/agents/README.md +129 -0
- django_cfg/apps/agents/__init__.py +68 -0
- django_cfg/apps/agents/admin/__init__.py +17 -0
- django_cfg/apps/agents/admin/execution_admin.py +460 -0
- django_cfg/apps/agents/admin/registry_admin.py +360 -0
- django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
- django_cfg/apps/agents/apps.py +29 -0
- django_cfg/apps/agents/core/__init__.py +20 -0
- django_cfg/apps/agents/core/agent.py +281 -0
- django_cfg/apps/agents/core/dependencies.py +154 -0
- django_cfg/apps/agents/core/exceptions.py +66 -0
- django_cfg/apps/agents/core/models.py +106 -0
- django_cfg/apps/agents/core/orchestrator.py +391 -0
- django_cfg/apps/agents/examples/__init__.py +3 -0
- django_cfg/apps/agents/examples/simple_example.py +161 -0
- django_cfg/apps/agents/integration/__init__.py +14 -0
- django_cfg/apps/agents/integration/middleware.py +80 -0
- django_cfg/apps/agents/integration/registry.py +345 -0
- django_cfg/apps/agents/integration/signals.py +50 -0
- django_cfg/apps/agents/management/__init__.py +3 -0
- django_cfg/apps/agents/management/commands/__init__.py +3 -0
- django_cfg/apps/agents/management/commands/create_agent.py +365 -0
- django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
- django_cfg/apps/agents/managers/__init__.py +23 -0
- django_cfg/apps/agents/managers/execution.py +236 -0
- django_cfg/apps/agents/managers/registry.py +254 -0
- django_cfg/apps/agents/managers/toolsets.py +496 -0
- django_cfg/apps/agents/migrations/0001_initial.py +286 -0
- django_cfg/apps/agents/migrations/__init__.py +5 -0
- django_cfg/apps/agents/models/__init__.py +15 -0
- django_cfg/apps/agents/models/execution.py +215 -0
- django_cfg/apps/agents/models/registry.py +220 -0
- django_cfg/apps/agents/models/toolsets.py +305 -0
- django_cfg/apps/agents/patterns/__init__.py +24 -0
- django_cfg/apps/agents/patterns/content_agents.py +234 -0
- django_cfg/apps/agents/toolsets/__init__.py +15 -0
- django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
- django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
- django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
- django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
- django_cfg/apps/agents/urls.py +46 -0
- django_cfg/apps/knowbase/README.md +150 -0
- django_cfg/apps/knowbase/__init__.py +27 -0
- django_cfg/apps/knowbase/admin/__init__.py +23 -0
- django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
- django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
- django_cfg/apps/knowbase/admin/document_admin.py +650 -0
- django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
- django_cfg/apps/knowbase/apps.py +81 -0
- django_cfg/apps/knowbase/config/README.md +176 -0
- django_cfg/apps/knowbase/config/__init__.py +51 -0
- django_cfg/apps/knowbase/config/constance_fields.py +186 -0
- django_cfg/apps/knowbase/config/constance_settings.py +200 -0
- django_cfg/apps/knowbase/config/settings.py +450 -0
- django_cfg/apps/knowbase/examples/__init__.py +3 -0
- django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
- django_cfg/apps/knowbase/management/__init__.py +0 -0
- django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
- django_cfg/apps/knowbase/managers/__init__.py +22 -0
- django_cfg/apps/knowbase/managers/archive.py +426 -0
- django_cfg/apps/knowbase/managers/base.py +32 -0
- django_cfg/apps/knowbase/managers/chat.py +141 -0
- django_cfg/apps/knowbase/managers/document.py +203 -0
- django_cfg/apps/knowbase/managers/external_data.py +471 -0
- django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
- django_cfg/apps/knowbase/migrations/__init__.py +5 -0
- django_cfg/apps/knowbase/mixins/__init__.py +15 -0
- django_cfg/apps/knowbase/mixins/config.py +108 -0
- django_cfg/apps/knowbase/mixins/creator.py +81 -0
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
- django_cfg/apps/knowbase/mixins/service.py +362 -0
- django_cfg/apps/knowbase/models/__init__.py +41 -0
- django_cfg/apps/knowbase/models/archive.py +599 -0
- django_cfg/apps/knowbase/models/base.py +58 -0
- django_cfg/apps/knowbase/models/chat.py +157 -0
- django_cfg/apps/knowbase/models/document.py +267 -0
- django_cfg/apps/knowbase/models/external_data.py +376 -0
- django_cfg/apps/knowbase/serializers/__init__.py +68 -0
- django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
- django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
- django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
- django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
- django_cfg/apps/knowbase/services/__init__.py +40 -0
- django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
- django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
- django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
- django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
- django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
- django_cfg/apps/knowbase/services/base.py +53 -0
- django_cfg/apps/knowbase/services/chat_service.py +239 -0
- django_cfg/apps/knowbase/services/document_service.py +144 -0
- django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
- django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
- django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
- django_cfg/apps/knowbase/services/embedding/models.py +229 -0
- django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
- django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
- django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
- django_cfg/apps/knowbase/services/search_service.py +293 -0
- django_cfg/apps/knowbase/signals/__init__.py +21 -0
- django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
- django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
- django_cfg/apps/knowbase/signals/document_signals.py +143 -0
- django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
- django_cfg/apps/knowbase/tasks/__init__.py +39 -0
- django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
- django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
- django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
- django_cfg/apps/knowbase/urls.py +43 -0
- django_cfg/apps/knowbase/utils/__init__.py +12 -0
- django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
- django_cfg/apps/knowbase/utils/text_processing.py +375 -0
- django_cfg/apps/knowbase/utils/validation.py +99 -0
- django_cfg/apps/knowbase/views/__init__.py +28 -0
- django_cfg/apps/knowbase/views/archive_views.py +469 -0
- django_cfg/apps/knowbase/views/base.py +49 -0
- django_cfg/apps/knowbase/views/chat_views.py +181 -0
- django_cfg/apps/knowbase/views/document_views.py +183 -0
- django_cfg/apps/knowbase/views/public_views.py +129 -0
- django_cfg/apps/leads/admin.py +70 -0
- django_cfg/apps/newsletter/admin.py +234 -0
- django_cfg/apps/newsletter/admin_filters.py +124 -0
- django_cfg/apps/support/admin.py +196 -0
- django_cfg/apps/support/admin_filters.py +71 -0
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
- django_cfg/apps/urls.py +5 -4
- django_cfg/cli/README.md +1 -1
- django_cfg/cli/commands/create_project.py +2 -2
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/config.py +44 -0
- django_cfg/core/config.py +29 -82
- django_cfg/core/environment.py +1 -1
- django_cfg/core/generation.py +19 -107
- django_cfg/{integration.py → core/integration.py} +18 -16
- django_cfg/core/validation.py +1 -1
- django_cfg/management/__init__.py +1 -1
- django_cfg/management/commands/__init__.py +1 -1
- django_cfg/management/commands/auto_generate.py +482 -0
- django_cfg/management/commands/migrator.py +19 -101
- django_cfg/management/commands/test_email.py +1 -1
- django_cfg/middleware/README.md +0 -158
- django_cfg/middleware/__init__.py +0 -2
- django_cfg/middleware/user_activity.py +3 -3
- django_cfg/models/api.py +145 -0
- django_cfg/models/base.py +287 -0
- django_cfg/models/cache.py +4 -4
- django_cfg/models/constance.py +25 -88
- django_cfg/models/database.py +9 -9
- django_cfg/models/drf.py +3 -36
- django_cfg/models/email.py +163 -0
- django_cfg/models/environment.py +276 -0
- django_cfg/models/limits.py +1 -1
- django_cfg/models/logging.py +366 -0
- django_cfg/models/revolution.py +41 -2
- django_cfg/models/security.py +125 -0
- django_cfg/models/services.py +1 -1
- django_cfg/modules/__init__.py +2 -56
- django_cfg/modules/base.py +78 -52
- django_cfg/modules/django_currency/service.py +2 -2
- django_cfg/modules/django_email.py +2 -2
- django_cfg/modules/django_health.py +267 -0
- django_cfg/modules/django_llm/llm/client.py +91 -19
- django_cfg/modules/django_llm/translator/translator.py +2 -2
- django_cfg/modules/django_logger.py +2 -2
- django_cfg/modules/django_ngrok.py +2 -2
- django_cfg/modules/django_tasks.py +68 -3
- django_cfg/modules/django_telegram.py +3 -3
- django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
- django_cfg/modules/django_twilio/service.py +2 -2
- django_cfg/modules/django_twilio/simple_service.py +2 -2
- django_cfg/modules/django_twilio/twilio_service.py +2 -2
- django_cfg/modules/django_unfold/__init__.py +69 -0
- django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
- django_cfg/modules/django_unfold/dashboard.py +278 -0
- django_cfg/modules/django_unfold/icons/README.md +145 -0
- django_cfg/modules/django_unfold/icons/__init__.py +12 -0
- django_cfg/modules/django_unfold/icons/constants.py +2851 -0
- django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
- django_cfg/modules/django_unfold/models/__init__.py +42 -0
- django_cfg/modules/django_unfold/models/config.py +601 -0
- django_cfg/modules/django_unfold/models/dashboard.py +206 -0
- django_cfg/modules/django_unfold/models/dropdown.py +40 -0
- django_cfg/modules/django_unfold/models/navigation.py +73 -0
- django_cfg/modules/django_unfold/models/tabs.py +25 -0
- django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
- django_cfg/modules/django_unfold/utils.py +140 -0
- django_cfg/registry/__init__.py +23 -0
- django_cfg/registry/core.py +61 -0
- django_cfg/registry/exceptions.py +11 -0
- django_cfg/registry/modules.py +12 -0
- django_cfg/registry/services.py +26 -0
- django_cfg/registry/third_party.py +52 -0
- django_cfg/routing/__init__.py +19 -0
- django_cfg/routing/callbacks.py +198 -0
- django_cfg/routing/routers.py +48 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
- django_cfg/templatetags/__init__.py +0 -0
- django_cfg/templatetags/django_cfg.py +33 -0
- django_cfg/urls.py +33 -0
- django_cfg/utils/path_resolution.py +1 -1
- django_cfg/utils/smart_defaults.py +7 -61
- django_cfg/utils/toolkit.py +663 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/METADATA +83 -86
- django_cfg-1.2.1.dist-info/RECORD +441 -0
- django_cfg/archive/django_sample.zip +0 -0
- django_cfg/models/unfold.py +0 -271
- django_cfg/modules/unfold/__init__.py +0 -29
- django_cfg/modules/unfold/dashboard.py +0 -318
- django_cfg/pyproject.toml +0 -370
- django_cfg/routers.py +0 -83
- django_cfg-1.1.82.dist-info/RECORD +0 -278
- /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
- /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
- /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
- /django_cfg/{version_check.py → utils/version_check.py} +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -16,7 +16,6 @@ from ..serializers.otp import (
|
|
16
16
|
)
|
17
17
|
from ..serializers.profile import UserSerializer
|
18
18
|
from django.contrib.auth import get_user_model
|
19
|
-
from ..utils.notifications import AccountNotifications
|
20
19
|
|
21
20
|
logger = logging.getLogger(__name__)
|
22
21
|
|
@@ -25,7 +24,6 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
25
24
|
"""OTP authentication ViewSet with nested router support."""
|
26
25
|
|
27
26
|
permission_classes = [permissions.AllowAny]
|
28
|
-
serializer_class = OTPRequestSerializer # Default serializer for OPTIONS requests
|
29
27
|
|
30
28
|
@extend_schema(
|
31
29
|
request=OTPRequestSerializer,
|
@@ -37,20 +35,27 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
37
35
|
)
|
38
36
|
@action(detail=False, methods=["post"], url_path="request")
|
39
37
|
def request_otp(self, request):
|
40
|
-
"""Request OTP code to email."""
|
38
|
+
"""Request OTP code to email or phone."""
|
41
39
|
serializer = OTPRequestSerializer(data=request.data)
|
42
40
|
serializer.is_valid(raise_exception=True)
|
43
41
|
|
44
42
|
identifier = serializer.validated_data["identifier"]
|
45
43
|
channel = serializer.validated_data.get("channel")
|
46
44
|
source_url = serializer.validated_data.get("source_url")
|
47
|
-
|
45
|
+
|
46
|
+
# Auto-detect channel if not provided
|
47
|
+
if not channel:
|
48
|
+
channel = 'email' if '@' in identifier else 'phone'
|
49
|
+
|
50
|
+
logger.debug(f"Starting OTP request for {channel}: {identifier}, source: {source_url}")
|
48
51
|
|
49
52
|
try:
|
50
|
-
if channel == '
|
51
|
-
success, error_type = OTPService.
|
52
|
-
else:
|
53
|
-
|
53
|
+
if channel == 'email':
|
54
|
+
success, error_type = OTPService.request_otp(identifier, source_url)
|
55
|
+
else:
|
56
|
+
# For phone OTP, we'll need to implement phone OTP service
|
57
|
+
# For now, fallback to email-based service
|
58
|
+
success, error_type = OTPService.request_otp(identifier, source_url)
|
54
59
|
except Exception as e:
|
55
60
|
# Log the full traceback for debugging
|
56
61
|
logger.error(f"OTP request failed with exception: {str(e)}")
|
@@ -61,21 +66,20 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
61
66
|
)
|
62
67
|
|
63
68
|
if success:
|
64
|
-
channel_name = "phone number" if channel == 'phone' else "email address"
|
65
69
|
return Response(
|
66
|
-
{"message":
|
70
|
+
{"message": "OTP sent to your email address"}, status=status.HTTP_200_OK
|
67
71
|
)
|
68
72
|
else:
|
69
|
-
if error_type
|
70
|
-
|
71
|
-
logger.warning(f"Invalid {field_name} provided: {identifier}")
|
73
|
+
if error_type == "invalid_email":
|
74
|
+
logger.warning(f"Invalid identifier provided: {identifier}")
|
72
75
|
return Response(
|
73
|
-
{"error":
|
76
|
+
{"error": "Invalid identifier format"},
|
74
77
|
status=status.HTTP_400_BAD_REQUEST,
|
75
78
|
)
|
76
79
|
elif error_type == "user_creation_failed":
|
77
80
|
# Log additional details for user creation failure
|
78
|
-
logger.error(f"User creation failed for
|
81
|
+
logger.error(f"User creation failed for identifier: {identifier}")
|
82
|
+
logger.error(f"Error type: {error_type}")
|
79
83
|
logger.error(
|
80
84
|
f"Full traceback for user creation failure: {traceback.format_exc()}"
|
81
85
|
)
|
@@ -84,7 +88,7 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
84
88
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
85
89
|
)
|
86
90
|
else:
|
87
|
-
logger.error(f"Unknown error type: {error_type} for {identifier}")
|
91
|
+
logger.error(f"Unknown error type: {error_type} for identifier: {identifier}")
|
88
92
|
return Response(
|
89
93
|
{"error": "Failed to send OTP"},
|
90
94
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
@@ -108,27 +112,19 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
108
112
|
otp = serializer.validated_data["otp"]
|
109
113
|
channel = serializer.validated_data.get("channel")
|
110
114
|
source_url = serializer.validated_data.get("source_url")
|
115
|
+
|
116
|
+
# Auto-detect channel if not provided
|
117
|
+
if not channel:
|
118
|
+
channel = 'email' if '@' in identifier else 'phone'
|
111
119
|
|
112
|
-
if channel == '
|
113
|
-
user = OTPService.
|
114
|
-
else:
|
115
|
-
|
120
|
+
if channel == 'email':
|
121
|
+
user = OTPService.verify_otp(identifier, otp, source_url)
|
122
|
+
else:
|
123
|
+
# For phone OTP, we'll need to implement phone OTP verification
|
124
|
+
# For now, fallback to email-based service
|
125
|
+
user = OTPService.verify_otp(identifier, otp, source_url)
|
116
126
|
|
117
127
|
if user:
|
118
|
-
# Check if this is a new user (created recently, within last 5 minutes)
|
119
|
-
from django.utils import timezone
|
120
|
-
from datetime import timedelta
|
121
|
-
|
122
|
-
is_new_user = (timezone.now() - user.date_joined) < timedelta(minutes=5)
|
123
|
-
|
124
|
-
# Send welcome email only for new users
|
125
|
-
if is_new_user:
|
126
|
-
try:
|
127
|
-
AccountNotifications.send_welcome_email(user, send_email=True, send_telegram=False)
|
128
|
-
logger.info(f"Welcome email sent to new user: {user.email}")
|
129
|
-
except Exception as e:
|
130
|
-
logger.error(f"Failed to send welcome email to {user.email}: {e}")
|
131
|
-
|
132
128
|
refresh = RefreshToken.for_user(user)
|
133
129
|
return Response(
|
134
130
|
{
|
@@ -142,9 +138,12 @@ class OTPViewSet(viewsets.GenericViewSet):
|
|
142
138
|
# Check if user was deleted after OTP was sent
|
143
139
|
try:
|
144
140
|
User = get_user_model()
|
145
|
-
|
146
|
-
|
141
|
+
# For email identifiers, check by email; for phone, we'd need phone field
|
142
|
+
if '@' in identifier:
|
143
|
+
User.objects.get(email=identifier)
|
147
144
|
else:
|
145
|
+
# For phone numbers, we'd need to implement phone field lookup
|
146
|
+
# For now, assume email-based lookup
|
148
147
|
User.objects.get(email=identifier)
|
149
148
|
# User exists but OTP is invalid
|
150
149
|
return Response(
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# Django Orchestrator
|
2
|
+
|
3
|
+
Universal agent orchestration system for Django applications using Pydantic AI.
|
4
|
+
|
5
|
+
## Quick Start
|
6
|
+
|
7
|
+
```python
|
8
|
+
from django_cfg.modules.django_orchestrator import DjangoAgent, SimpleOrchestrator, DjangoDeps
|
9
|
+
from pydantic import BaseModel
|
10
|
+
|
11
|
+
# Define output model
|
12
|
+
class GreetingResult(BaseModel):
|
13
|
+
greeting: str
|
14
|
+
personalized: bool
|
15
|
+
|
16
|
+
# Create agent
|
17
|
+
agent = DjangoAgent[DjangoDeps, GreetingResult](
|
18
|
+
name="greeter",
|
19
|
+
deps_type=DjangoDeps,
|
20
|
+
output_type=GreetingResult,
|
21
|
+
instructions="Generate personalized greetings"
|
22
|
+
)
|
23
|
+
|
24
|
+
# Use orchestrator
|
25
|
+
orchestrator = SimpleOrchestrator()
|
26
|
+
orchestrator.register_agent(agent)
|
27
|
+
|
28
|
+
# Execute
|
29
|
+
deps = await DjangoDeps.from_user_id(user_id)
|
30
|
+
results = await orchestrator.execute(
|
31
|
+
pattern="sequential",
|
32
|
+
agents=["greeter"],
|
33
|
+
prompt="Say hello",
|
34
|
+
deps=deps
|
35
|
+
)
|
36
|
+
```
|
37
|
+
|
38
|
+
## Features
|
39
|
+
|
40
|
+
- 🎯 **Type-Safe Agents** - Full typing with `Agent[DepsT, OutputT]`
|
41
|
+
- 🔧 **Django Integration** - Native ORM, signals, and task support
|
42
|
+
- 📊 **Multiple Patterns** - Sequential, parallel, conditional execution
|
43
|
+
- ⚡ **KISS Design** - Simple, clean, no overengineering
|
44
|
+
- 🔄 **Reuses Existing** - Built on django_llm module
|
45
|
+
- 🧪 **Easy Testing** - Mock-friendly design
|
46
|
+
|
47
|
+
## Installation
|
48
|
+
|
49
|
+
Add to your Django settings:
|
50
|
+
|
51
|
+
```python
|
52
|
+
INSTALLED_APPS = [
|
53
|
+
'django_cfg.modules.django_orchestrator',
|
54
|
+
]
|
55
|
+
```
|
56
|
+
|
57
|
+
Run migrations:
|
58
|
+
|
59
|
+
```bash
|
60
|
+
python manage.py migrate django_orchestrator
|
61
|
+
```
|
62
|
+
|
63
|
+
## Documentation
|
64
|
+
|
65
|
+
See the complete documentation in the `@docs2/` directory:
|
66
|
+
|
67
|
+
- **[index.md](@docs2/index.md)** - Module overview
|
68
|
+
- **[quick-start.md](@docs2/quick-start.md)** - Get started in 5 minutes
|
69
|
+
- **[api.md](@docs2/api.md)** - Complete API reference
|
70
|
+
- **[examples.md](@docs2/examples.md)** - Real-world usage patterns
|
71
|
+
|
72
|
+
## Architecture
|
73
|
+
|
74
|
+
```
|
75
|
+
django_orchestrator/
|
76
|
+
├── core/
|
77
|
+
│ ├── agent.py # DjangoAgent wrapper
|
78
|
+
│ ├── orchestrator.py # Main orchestrator
|
79
|
+
│ ├── dependencies.py # Dependency injection
|
80
|
+
│ ├── models.py # Data models
|
81
|
+
│ └── exceptions.py # Custom exceptions
|
82
|
+
├── models/
|
83
|
+
│ ├── execution.py # Execution tracking
|
84
|
+
│ ├── registry.py # Agent registry
|
85
|
+
│ └── toolsets.py # Tool management
|
86
|
+
├── examples/
|
87
|
+
│ └── simple_example.py # Working examples
|
88
|
+
└── tests/
|
89
|
+
└── test_core.py # Test suite
|
90
|
+
```
|
91
|
+
|
92
|
+
## Examples
|
93
|
+
|
94
|
+
### Basic Agent
|
95
|
+
|
96
|
+
```python
|
97
|
+
@agent.tool
|
98
|
+
async def get_user_data(ctx: RunContext[DjangoDeps]) -> str:
|
99
|
+
user = await User.objects.aget(id=ctx.deps.user.id)
|
100
|
+
return f"User: {user.username}"
|
101
|
+
|
102
|
+
result = await agent.run("Get user info", deps=deps)
|
103
|
+
```
|
104
|
+
|
105
|
+
### Multi-Agent Pipeline
|
106
|
+
|
107
|
+
```python
|
108
|
+
orchestrator.register_agent(analyzer)
|
109
|
+
orchestrator.register_agent(processor)
|
110
|
+
|
111
|
+
results = await orchestrator.execute(
|
112
|
+
pattern="sequential",
|
113
|
+
agents=["analyzer", "processor"],
|
114
|
+
prompt="Process content",
|
115
|
+
deps=deps
|
116
|
+
)
|
117
|
+
```
|
118
|
+
|
119
|
+
## Testing
|
120
|
+
|
121
|
+
Run tests:
|
122
|
+
|
123
|
+
```bash
|
124
|
+
python -m pytest django_cfg/modules/django_orchestrator/tests/
|
125
|
+
```
|
126
|
+
|
127
|
+
## License
|
128
|
+
|
129
|
+
Part of django-cfg package.
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"""
|
2
|
+
Django Agents - Universal AI agent system for Django applications.
|
3
|
+
|
4
|
+
Built on Pydantic AI with KISS principles and proper decomposition.
|
5
|
+
"""
|
6
|
+
|
7
|
+
__version__ = "0.1.0"
|
8
|
+
__author__ = "Django-CFG Team"
|
9
|
+
|
10
|
+
# Set default app config
|
11
|
+
default_app_config = 'django_cfg.apps.agents.apps.AgentsConfig'
|
12
|
+
|
13
|
+
__all__ = [
|
14
|
+
# Core classes
|
15
|
+
"DjangoAgent",
|
16
|
+
"SimpleOrchestrator",
|
17
|
+
"DjangoDeps",
|
18
|
+
"RunContext",
|
19
|
+
|
20
|
+
# Models
|
21
|
+
"ExecutionResult",
|
22
|
+
"WorkflowConfig",
|
23
|
+
"ProcessResult",
|
24
|
+
"AnalysisResult",
|
25
|
+
|
26
|
+
# Exceptions
|
27
|
+
"AgentError",
|
28
|
+
"AgentNotFoundError",
|
29
|
+
"ExecutionError",
|
30
|
+
]
|
31
|
+
|
32
|
+
def __getattr__(name):
|
33
|
+
"""Lazy import for agents components."""
|
34
|
+
if name == "DjangoAgent":
|
35
|
+
from .core.agent import DjangoAgent
|
36
|
+
return DjangoAgent
|
37
|
+
elif name == "SimpleOrchestrator":
|
38
|
+
from .core.orchestrator import SimpleOrchestrator
|
39
|
+
return SimpleOrchestrator
|
40
|
+
elif name == "DjangoDeps":
|
41
|
+
from .core.dependencies import DjangoDeps
|
42
|
+
return DjangoDeps
|
43
|
+
elif name == "RunContext":
|
44
|
+
from .core.dependencies import RunContext
|
45
|
+
return RunContext
|
46
|
+
elif name == "ExecutionResult":
|
47
|
+
from .core.models import ExecutionResult
|
48
|
+
return ExecutionResult
|
49
|
+
elif name == "WorkflowConfig":
|
50
|
+
from .core.models import WorkflowConfig
|
51
|
+
return WorkflowConfig
|
52
|
+
elif name == "ProcessResult":
|
53
|
+
from .core.models import ProcessResult
|
54
|
+
return ProcessResult
|
55
|
+
elif name == "AnalysisResult":
|
56
|
+
from .core.models import AnalysisResult
|
57
|
+
return AnalysisResult
|
58
|
+
elif name == "AgentError":
|
59
|
+
from .core.exceptions import AgentError
|
60
|
+
return AgentError
|
61
|
+
elif name == "AgentNotFoundError":
|
62
|
+
from .core.exceptions import AgentNotFoundError
|
63
|
+
return AgentNotFoundError
|
64
|
+
elif name == "ExecutionError":
|
65
|
+
from .core.exceptions import ExecutionError
|
66
|
+
return ExecutionError
|
67
|
+
else:
|
68
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"""
|
2
|
+
Django admin interfaces for Django Orchestrator.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from .registry_admin import AgentDefinitionAdmin, AgentTemplateAdmin
|
6
|
+
from .execution_admin import AgentExecutionAdmin, WorkflowExecutionAdmin
|
7
|
+
from .toolsets_admin import ToolExecutionAdmin, ApprovalLogAdmin, ToolsetConfigurationAdmin
|
8
|
+
|
9
|
+
__all__ = [
|
10
|
+
'AgentDefinitionAdmin',
|
11
|
+
'AgentTemplateAdmin',
|
12
|
+
'AgentExecutionAdmin',
|
13
|
+
'WorkflowExecutionAdmin',
|
14
|
+
'ToolExecutionAdmin',
|
15
|
+
'ApprovalLogAdmin',
|
16
|
+
'ToolsetConfigurationAdmin',
|
17
|
+
]
|