django-cfg 1.1.81__py3-none-any.whl → 1.2.0__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.
Files changed (246) hide show
  1. django_cfg/__init__.py +20 -448
  2. django_cfg/apps/accounts/README.md +3 -3
  3. django_cfg/apps/accounts/admin/__init__.py +0 -2
  4. django_cfg/apps/accounts/admin/activity.py +2 -9
  5. django_cfg/apps/accounts/admin/filters.py +0 -42
  6. django_cfg/apps/accounts/admin/inlines.py +8 -8
  7. django_cfg/apps/accounts/admin/otp.py +5 -5
  8. django_cfg/apps/accounts/admin/registration_source.py +1 -8
  9. django_cfg/apps/accounts/admin/user.py +12 -20
  10. django_cfg/apps/accounts/managers/user_manager.py +2 -129
  11. django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
  12. django_cfg/apps/accounts/models.py +3 -123
  13. django_cfg/apps/accounts/serializers/otp.py +40 -44
  14. django_cfg/apps/accounts/serializers/profile.py +0 -2
  15. django_cfg/apps/accounts/services/otp_service.py +98 -186
  16. django_cfg/apps/accounts/signals.py +25 -15
  17. django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
  18. django_cfg/apps/accounts/views/otp.py +35 -36
  19. django_cfg/apps/agents/README.md +129 -0
  20. django_cfg/apps/agents/__init__.py +68 -0
  21. django_cfg/apps/agents/admin/__init__.py +17 -0
  22. django_cfg/apps/agents/admin/execution_admin.py +460 -0
  23. django_cfg/apps/agents/admin/registry_admin.py +360 -0
  24. django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
  25. django_cfg/apps/agents/apps.py +29 -0
  26. django_cfg/apps/agents/core/__init__.py +20 -0
  27. django_cfg/apps/agents/core/agent.py +281 -0
  28. django_cfg/apps/agents/core/dependencies.py +154 -0
  29. django_cfg/apps/agents/core/exceptions.py +66 -0
  30. django_cfg/apps/agents/core/models.py +106 -0
  31. django_cfg/apps/agents/core/orchestrator.py +391 -0
  32. django_cfg/apps/agents/examples/__init__.py +3 -0
  33. django_cfg/apps/agents/examples/simple_example.py +161 -0
  34. django_cfg/apps/agents/integration/__init__.py +14 -0
  35. django_cfg/apps/agents/integration/middleware.py +80 -0
  36. django_cfg/apps/agents/integration/registry.py +345 -0
  37. django_cfg/apps/agents/integration/signals.py +50 -0
  38. django_cfg/apps/agents/management/__init__.py +3 -0
  39. django_cfg/apps/agents/management/commands/__init__.py +3 -0
  40. django_cfg/apps/agents/management/commands/create_agent.py +365 -0
  41. django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
  42. django_cfg/apps/agents/managers/__init__.py +23 -0
  43. django_cfg/apps/agents/managers/execution.py +236 -0
  44. django_cfg/apps/agents/managers/registry.py +254 -0
  45. django_cfg/apps/agents/managers/toolsets.py +496 -0
  46. django_cfg/apps/agents/migrations/0001_initial.py +286 -0
  47. django_cfg/apps/agents/migrations/__init__.py +5 -0
  48. django_cfg/apps/agents/models/__init__.py +15 -0
  49. django_cfg/apps/agents/models/execution.py +215 -0
  50. django_cfg/apps/agents/models/registry.py +220 -0
  51. django_cfg/apps/agents/models/toolsets.py +305 -0
  52. django_cfg/apps/agents/patterns/__init__.py +24 -0
  53. django_cfg/apps/agents/patterns/content_agents.py +234 -0
  54. django_cfg/apps/agents/toolsets/__init__.py +15 -0
  55. django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
  56. django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
  57. django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
  58. django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
  59. django_cfg/apps/agents/urls.py +46 -0
  60. django_cfg/apps/knowbase/README.md +150 -0
  61. django_cfg/apps/knowbase/__init__.py +27 -0
  62. django_cfg/apps/knowbase/admin/__init__.py +23 -0
  63. django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
  64. django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
  65. django_cfg/apps/knowbase/admin/document_admin.py +650 -0
  66. django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
  67. django_cfg/apps/knowbase/apps.py +81 -0
  68. django_cfg/apps/knowbase/config/README.md +176 -0
  69. django_cfg/apps/knowbase/config/__init__.py +51 -0
  70. django_cfg/apps/knowbase/config/constance_fields.py +186 -0
  71. django_cfg/apps/knowbase/config/constance_settings.py +200 -0
  72. django_cfg/apps/knowbase/config/settings.py +444 -0
  73. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  74. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  75. django_cfg/apps/knowbase/management/__init__.py +0 -0
  76. django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
  77. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
  78. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
  79. django_cfg/apps/knowbase/managers/__init__.py +22 -0
  80. django_cfg/apps/knowbase/managers/archive.py +426 -0
  81. django_cfg/apps/knowbase/managers/base.py +32 -0
  82. django_cfg/apps/knowbase/managers/chat.py +141 -0
  83. django_cfg/apps/knowbase/managers/document.py +203 -0
  84. django_cfg/apps/knowbase/managers/external_data.py +471 -0
  85. django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
  86. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
  87. django_cfg/apps/knowbase/migrations/__init__.py +5 -0
  88. django_cfg/apps/knowbase/mixins/__init__.py +15 -0
  89. django_cfg/apps/knowbase/mixins/config.py +108 -0
  90. django_cfg/apps/knowbase/mixins/creator.py +81 -0
  91. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  92. django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
  93. django_cfg/apps/knowbase/mixins/service.py +362 -0
  94. django_cfg/apps/knowbase/models/__init__.py +41 -0
  95. django_cfg/apps/knowbase/models/archive.py +599 -0
  96. django_cfg/apps/knowbase/models/base.py +58 -0
  97. django_cfg/apps/knowbase/models/chat.py +157 -0
  98. django_cfg/apps/knowbase/models/document.py +267 -0
  99. django_cfg/apps/knowbase/models/external_data.py +376 -0
  100. django_cfg/apps/knowbase/serializers/__init__.py +68 -0
  101. django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
  102. django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
  103. django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
  104. django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
  105. django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
  106. django_cfg/apps/knowbase/services/__init__.py +40 -0
  107. django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
  108. django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
  109. django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
  110. django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
  111. django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
  112. django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
  113. django_cfg/apps/knowbase/services/base.py +53 -0
  114. django_cfg/apps/knowbase/services/chat_service.py +239 -0
  115. django_cfg/apps/knowbase/services/document_service.py +144 -0
  116. django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
  117. django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
  118. django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
  119. django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
  120. django_cfg/apps/knowbase/services/embedding/models.py +229 -0
  121. django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
  122. django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
  123. django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
  124. django_cfg/apps/knowbase/services/search_service.py +293 -0
  125. django_cfg/apps/knowbase/signals/__init__.py +21 -0
  126. django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
  127. django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
  128. django_cfg/apps/knowbase/signals/document_signals.py +143 -0
  129. django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
  130. django_cfg/apps/knowbase/tasks/__init__.py +39 -0
  131. django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
  132. django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
  133. django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
  134. django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
  135. django_cfg/apps/knowbase/urls.py +43 -0
  136. django_cfg/apps/knowbase/utils/__init__.py +12 -0
  137. django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
  138. django_cfg/apps/knowbase/utils/text_processing.py +375 -0
  139. django_cfg/apps/knowbase/utils/validation.py +99 -0
  140. django_cfg/apps/knowbase/views/__init__.py +28 -0
  141. django_cfg/apps/knowbase/views/archive_views.py +469 -0
  142. django_cfg/apps/knowbase/views/base.py +49 -0
  143. django_cfg/apps/knowbase/views/chat_views.py +181 -0
  144. django_cfg/apps/knowbase/views/document_views.py +183 -0
  145. django_cfg/apps/knowbase/views/public_views.py +129 -0
  146. django_cfg/apps/leads/admin.py +70 -0
  147. django_cfg/apps/newsletter/admin.py +234 -0
  148. django_cfg/apps/newsletter/admin_filters.py +124 -0
  149. django_cfg/apps/support/admin.py +196 -0
  150. django_cfg/apps/support/admin_filters.py +71 -0
  151. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  152. django_cfg/apps/urls.py +5 -4
  153. django_cfg/cli/README.md +1 -1
  154. django_cfg/cli/commands/create_project.py +2 -2
  155. django_cfg/cli/commands/info.py +1 -1
  156. django_cfg/config.py +44 -0
  157. django_cfg/core/config.py +29 -82
  158. django_cfg/core/environment.py +1 -1
  159. django_cfg/core/generation.py +19 -107
  160. django_cfg/{integration.py → core/integration.py} +18 -16
  161. django_cfg/core/validation.py +1 -1
  162. django_cfg/management/__init__.py +1 -1
  163. django_cfg/management/commands/__init__.py +1 -1
  164. django_cfg/management/commands/auto_generate.py +482 -0
  165. django_cfg/management/commands/migrator.py +19 -101
  166. django_cfg/management/commands/test_email.py +1 -1
  167. django_cfg/middleware/README.md +0 -158
  168. django_cfg/middleware/__init__.py +0 -2
  169. django_cfg/middleware/user_activity.py +3 -3
  170. django_cfg/models/api.py +145 -0
  171. django_cfg/models/base.py +287 -0
  172. django_cfg/models/cache.py +4 -4
  173. django_cfg/models/constance.py +25 -88
  174. django_cfg/models/database.py +9 -9
  175. django_cfg/models/drf.py +3 -36
  176. django_cfg/models/email.py +163 -0
  177. django_cfg/models/environment.py +276 -0
  178. django_cfg/models/limits.py +1 -1
  179. django_cfg/models/logging.py +366 -0
  180. django_cfg/models/revolution.py +41 -2
  181. django_cfg/models/security.py +125 -0
  182. django_cfg/models/services.py +1 -1
  183. django_cfg/modules/__init__.py +2 -56
  184. django_cfg/modules/base.py +78 -52
  185. django_cfg/modules/django_currency/service.py +2 -2
  186. django_cfg/modules/django_email.py +2 -2
  187. django_cfg/modules/django_health.py +267 -0
  188. django_cfg/modules/django_llm/llm/client.py +79 -17
  189. django_cfg/modules/django_llm/translator/translator.py +2 -2
  190. django_cfg/modules/django_logger.py +2 -2
  191. django_cfg/modules/django_ngrok.py +2 -2
  192. django_cfg/modules/django_tasks.py +68 -3
  193. django_cfg/modules/django_telegram.py +3 -3
  194. django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
  195. django_cfg/modules/django_twilio/service.py +2 -2
  196. django_cfg/modules/django_twilio/simple_service.py +2 -2
  197. django_cfg/modules/django_twilio/templates/guide.md +266 -0
  198. django_cfg/modules/django_twilio/twilio_service.py +2 -2
  199. django_cfg/modules/django_unfold/__init__.py +69 -0
  200. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  201. django_cfg/modules/django_unfold/dashboard.py +278 -0
  202. django_cfg/modules/django_unfold/icons/README.md +145 -0
  203. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  204. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  205. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  206. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  207. django_cfg/modules/django_unfold/models/config.py +601 -0
  208. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  209. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  210. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  211. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  212. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  213. django_cfg/modules/django_unfold/utils.py +140 -0
  214. django_cfg/registry/__init__.py +23 -0
  215. django_cfg/registry/core.py +61 -0
  216. django_cfg/registry/exceptions.py +11 -0
  217. django_cfg/registry/modules.py +12 -0
  218. django_cfg/registry/services.py +26 -0
  219. django_cfg/registry/third_party.py +52 -0
  220. django_cfg/routing/__init__.py +19 -0
  221. django_cfg/routing/callbacks.py +198 -0
  222. django_cfg/routing/routers.py +48 -0
  223. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  224. django_cfg/templatetags/__init__.py +0 -0
  225. django_cfg/templatetags/django_cfg.py +33 -0
  226. django_cfg/urls.py +33 -0
  227. django_cfg/utils/path_resolution.py +1 -1
  228. django_cfg/utils/smart_defaults.py +7 -61
  229. django_cfg/utils/toolkit.py +663 -0
  230. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
  231. django_cfg-1.2.0.dist-info/RECORD +441 -0
  232. django_cfg/apps/tasks/@docs/README.md +0 -195
  233. django_cfg/archive/django_sample.zip +0 -0
  234. django_cfg/models/unfold.py +0 -271
  235. django_cfg/modules/unfold/__init__.py +0 -29
  236. django_cfg/modules/unfold/dashboard.py +0 -318
  237. django_cfg/pyproject.toml +0 -370
  238. django_cfg/routers.py +0 -83
  239. django_cfg-1.1.81.dist-info/RECORD +0 -278
  240. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  241. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  242. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  243. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  244. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
  246. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.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
- logger.debug(f"Starting OTP request for {identifier} via {channel}, source: {source_url}")
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 == 'phone':
51
- success, error_type = OTPService.request_phone_otp(identifier, source_url)
52
- else: # email channel (default)
53
- success, error_type = OTPService.request_email_otp(identifier, source_url)
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": f"OTP sent to your {channel_name}"}, status=status.HTTP_200_OK
70
+ {"message": "OTP sent to your email address"}, status=status.HTTP_200_OK
67
71
  )
68
72
  else:
69
- if error_type in ["invalid_email", "invalid_phone"]:
70
- field_name = "phone number" if error_type == "invalid_phone" else "email address"
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": f"Invalid {field_name}"},
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 {identifier}: {error_type}")
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 == 'phone':
113
- user = OTPService.verify_phone_otp(identifier, otp, source_url)
114
- else: # email channel (default)
115
- user = OTPService.verify_email_otp(identifier, otp, source_url)
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
- if channel == 'phone':
146
- User.objects.get(phone=identifier)
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
+ ]