django-cfg 1.1.82__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 (244) 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/twilio_service.py +2 -2
  198. django_cfg/modules/django_unfold/__init__.py +69 -0
  199. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  200. django_cfg/modules/django_unfold/dashboard.py +278 -0
  201. django_cfg/modules/django_unfold/icons/README.md +145 -0
  202. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  203. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  204. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  205. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  206. django_cfg/modules/django_unfold/models/config.py +601 -0
  207. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  208. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  209. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  210. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  211. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  212. django_cfg/modules/django_unfold/utils.py +140 -0
  213. django_cfg/registry/__init__.py +23 -0
  214. django_cfg/registry/core.py +61 -0
  215. django_cfg/registry/exceptions.py +11 -0
  216. django_cfg/registry/modules.py +12 -0
  217. django_cfg/registry/services.py +26 -0
  218. django_cfg/registry/third_party.py +52 -0
  219. django_cfg/routing/__init__.py +19 -0
  220. django_cfg/routing/callbacks.py +198 -0
  221. django_cfg/routing/routers.py +48 -0
  222. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  223. django_cfg/templatetags/__init__.py +0 -0
  224. django_cfg/templatetags/django_cfg.py +33 -0
  225. django_cfg/urls.py +33 -0
  226. django_cfg/utils/path_resolution.py +1 -1
  227. django_cfg/utils/smart_defaults.py +7 -61
  228. django_cfg/utils/toolkit.py +663 -0
  229. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
  230. django_cfg-1.2.0.dist-info/RECORD +441 -0
  231. django_cfg/archive/django_sample.zip +0 -0
  232. django_cfg/models/unfold.py +0 -271
  233. django_cfg/modules/unfold/__init__.py +0 -29
  234. django_cfg/modules/unfold/dashboard.py +0 -318
  235. django_cfg/pyproject.toml +0 -370
  236. django_cfg/routers.py +0 -83
  237. django_cfg-1.1.82.dist-info/RECORD +0 -278
  238. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  239. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  240. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  241. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  242. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
  243. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
  244. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,345 @@
1
+ """
2
+ Agent registry for Django integration.
3
+ """
4
+
5
+ import logging
6
+ from typing import Dict, List, Optional, Type, Any
7
+ from django.contrib.auth.models import User
8
+
9
+ from ..core.agent import DjangoAgent
10
+ from ..core.orchestrator import SimpleOrchestrator
11
+ from ..core.dependencies import DjangoDeps
12
+ from ..models.registry import AgentDefinition
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class AgentRegistry:
18
+ """
19
+ Central registry for managing agents in Django application.
20
+
21
+ Provides:
22
+ - Agent registration and discovery
23
+ - Database-backed agent definitions
24
+ - Runtime agent creation
25
+ - Permission checking
26
+ """
27
+
28
+ def __init__(self):
29
+ """Initialize agent registry."""
30
+ self._runtime_agents: Dict[str, DjangoAgent] = {}
31
+ self._orchestrator = SimpleOrchestrator()
32
+
33
+ logger.info("Initialized AgentRegistry")
34
+
35
+ @property
36
+ def orchestrator(self) -> SimpleOrchestrator:
37
+ """Get orchestrator instance."""
38
+ return self._orchestrator
39
+
40
+ async def register_agent_definition(
41
+ self,
42
+ name: str,
43
+ instructions: str,
44
+ deps_type: str,
45
+ output_type: str,
46
+ user: User,
47
+ **kwargs
48
+ ) -> AgentDefinition:
49
+ """
50
+ Register new agent definition in database.
51
+
52
+ Args:
53
+ name: Agent identifier
54
+ instructions: System prompt
55
+ deps_type: Dependencies type name
56
+ output_type: Output type name
57
+ user: User creating the agent
58
+ **kwargs: Additional agent configuration
59
+
60
+ Returns:
61
+ Created AgentDefinition instance
62
+ """
63
+ # Check if agent already exists
64
+ if await AgentDefinition.objects.filter(name=name).aexists():
65
+ raise ValueError(f"Agent '{name}' already exists")
66
+
67
+ # Create agent definition
68
+ agent_def = await AgentDefinition.objects.acreate(
69
+ name=name,
70
+ instructions=instructions,
71
+ deps_type=deps_type,
72
+ output_type=output_type,
73
+ created_by=user,
74
+ **kwargs
75
+ )
76
+
77
+ logger.info(f"Registered agent definition: {name}")
78
+ return agent_def
79
+
80
+ async def get_agent_definition(self, name: str) -> Optional[AgentDefinition]:
81
+ """Get agent definition by name."""
82
+ try:
83
+ return await AgentDefinition.objects.aget(name=name, is_active=True)
84
+ except AgentDefinition.DoesNotExist:
85
+ return None
86
+
87
+ async def list_agent_definitions(
88
+ self,
89
+ user: Optional[User] = None,
90
+ category: Optional[str] = None
91
+ ) -> List[AgentDefinition]:
92
+ """List available agent definitions."""
93
+ queryset = AgentDefinition.objects.filter(is_active=True)
94
+
95
+ if user:
96
+ queryset = AgentDefinition.get_available_for_user(user)
97
+
98
+ if category:
99
+ queryset = queryset.filter(category=category)
100
+
101
+ return [agent_def async for agent_def in queryset.order_by('name')]
102
+
103
+ async def create_runtime_agent(
104
+ self,
105
+ agent_def: AgentDefinition,
106
+ llm_client: Optional[Any] = None
107
+ ) -> DjangoAgent:
108
+ """
109
+ Create runtime agent from definition.
110
+
111
+ Args:
112
+ agent_def: Agent definition from database
113
+ llm_client: Optional LLM client override
114
+
115
+ Returns:
116
+ DjangoAgent instance
117
+ """
118
+ # Import dependency and output types
119
+ deps_type = self._import_type(agent_def.deps_type)
120
+ output_type = self._import_type(agent_def.output_type)
121
+
122
+ # Create agent
123
+ agent = DjangoAgent(
124
+ name=agent_def.name,
125
+ deps_type=deps_type,
126
+ output_type=output_type,
127
+ instructions=agent_def.instructions,
128
+ model=agent_def.model,
129
+ llm_client=llm_client,
130
+ timeout=agent_def.timeout,
131
+ max_retries=agent_def.max_retries,
132
+ enable_caching=agent_def.enable_caching
133
+ )
134
+
135
+ # Apply tools configuration if available
136
+ if agent_def.tools_config:
137
+ await self._apply_tools_config(agent, agent_def.tools_config)
138
+
139
+ # Cache runtime agent
140
+ self._runtime_agents[agent_def.name] = agent
141
+
142
+ # Register with orchestrator
143
+ self._orchestrator.register_agent(agent)
144
+
145
+ logger.info(f"Created runtime agent: {agent_def.name}")
146
+ return agent
147
+
148
+ async def get_or_create_agent(
149
+ self,
150
+ name: str,
151
+ user: Optional[User] = None,
152
+ llm_client: Optional[Any] = None
153
+ ) -> Optional[DjangoAgent]:
154
+ """
155
+ Get existing runtime agent or create from definition.
156
+
157
+ Args:
158
+ name: Agent name
159
+ user: User requesting agent (for permission check)
160
+ llm_client: Optional LLM client override
161
+
162
+ Returns:
163
+ DjangoAgent instance or None if not found/not allowed
164
+ """
165
+ # Check if already in runtime cache
166
+ if name in self._runtime_agents:
167
+ agent = self._runtime_agents[name]
168
+
169
+ # Verify agent is still valid
170
+ agent_def = await self.get_agent_definition(name)
171
+ if agent_def and (not user or agent_def.can_be_used_by(user)):
172
+ return agent
173
+ else:
174
+ # Remove invalid agent
175
+ del self._runtime_agents[name]
176
+ self._orchestrator.unregister_agent(name)
177
+
178
+ # Get agent definition
179
+ agent_def = await self.get_agent_definition(name)
180
+ if not agent_def:
181
+ return None
182
+
183
+ # Check permissions
184
+ if user and not agent_def.can_be_used_by(user):
185
+ logger.warning(f"User {user.username} denied access to agent '{name}'")
186
+ return None
187
+
188
+ # Create runtime agent
189
+ return await self.create_runtime_agent(agent_def, llm_client)
190
+
191
+ async def execute_agent(
192
+ self,
193
+ agent_name: str,
194
+ prompt: str,
195
+ deps: DjangoDeps,
196
+ user: Optional[User] = None,
197
+ **kwargs
198
+ ):
199
+ """
200
+ Execute agent by name.
201
+
202
+ Args:
203
+ agent_name: Name of agent to execute
204
+ prompt: Input prompt
205
+ deps: Dependencies
206
+ user: User executing agent
207
+ **kwargs: Additional execution parameters
208
+
209
+ Returns:
210
+ Execution result
211
+ """
212
+ # Get agent
213
+ agent = await self.get_or_create_agent(agent_name, user)
214
+ if not agent:
215
+ raise ValueError(f"Agent '{agent_name}' not found or not accessible")
216
+
217
+ # Update usage statistics
218
+ agent_def = await self.get_agent_definition(agent_name)
219
+ if agent_def:
220
+ agent_def.increment_usage()
221
+
222
+ # Execute agent
223
+ return await agent.run(prompt, deps, **kwargs)
224
+
225
+ async def reload_agent(self, name: str) -> bool:
226
+ """
227
+ Reload agent from database definition.
228
+
229
+ Args:
230
+ name: Agent name to reload
231
+
232
+ Returns:
233
+ True if reloaded successfully
234
+ """
235
+ # Remove from runtime cache
236
+ if name in self._runtime_agents:
237
+ del self._runtime_agents[name]
238
+ self._orchestrator.unregister_agent(name)
239
+
240
+ # Recreate from definition
241
+ agent_def = await self.get_agent_definition(name)
242
+ if agent_def:
243
+ await self.create_runtime_agent(agent_def)
244
+ return True
245
+
246
+ return False
247
+
248
+ async def reload_all_agents(self) -> int:
249
+ """
250
+ Reload all agents from database.
251
+
252
+ Returns:
253
+ Number of agents reloaded
254
+ """
255
+ # Clear runtime cache
256
+ self._runtime_agents.clear()
257
+
258
+ # Clear orchestrator
259
+ for agent_name in list(self._orchestrator.agents.keys()):
260
+ self._orchestrator.unregister_agent(agent_name)
261
+
262
+ # Reload all active agents
263
+ agent_defs = await self.list_agent_definitions()
264
+ count = 0
265
+
266
+ for agent_def in agent_defs:
267
+ try:
268
+ await self.create_runtime_agent(agent_def)
269
+ count += 1
270
+ except Exception as e:
271
+ logger.error(f"Failed to reload agent '{agent_def.name}': {e}")
272
+
273
+ logger.info(f"Reloaded {count} agents")
274
+ return count
275
+
276
+ def _import_type(self, type_name: str) -> Type:
277
+ """Import type by name."""
278
+ # Handle built-in types
279
+ if type_name in ['DjangoDeps', 'ContentDeps', 'DataProcessingDeps', 'BusinessLogicDeps']:
280
+ from ..core.dependencies import DjangoDeps, ContentDeps, DataProcessingDeps, BusinessLogicDeps
281
+ return locals()[type_name]
282
+
283
+ if type_name in ['ProcessResult', 'AnalysisResult', 'ValidationResult']:
284
+ from ..core.models import ProcessResult, AnalysisResult, ValidationResult
285
+ return locals()[type_name]
286
+
287
+ # Handle custom types
288
+ try:
289
+ module_name, class_name = type_name.rsplit('.', 1)
290
+ module = __import__(module_name, fromlist=[class_name])
291
+ return getattr(module, class_name)
292
+ except (ValueError, ImportError, AttributeError) as e:
293
+ logger.error(f"Failed to import type '{type_name}': {e}")
294
+ # Fallback to basic types
295
+ from ..core.dependencies import DjangoDeps
296
+ from ..core.models import ProcessResult
297
+
298
+ if 'Deps' in type_name:
299
+ return DjangoDeps
300
+ else:
301
+ return ProcessResult
302
+
303
+ async def _apply_tools_config(self, agent: DjangoAgent, tools_config: Dict[str, Any]):
304
+ """Apply tools configuration to agent."""
305
+ # This would be extended to support dynamic tool loading
306
+ # For now, just log the configuration
307
+ logger.debug(f"Tools config for agent '{agent.name}': {tools_config}")
308
+
309
+ def get_runtime_agents(self) -> Dict[str, DjangoAgent]:
310
+ """Get all runtime agents."""
311
+ return self._runtime_agents.copy()
312
+
313
+ def get_agent_metrics(self) -> Dict[str, Any]:
314
+ """Get registry metrics."""
315
+ return {
316
+ 'runtime_agents_count': len(self._runtime_agents),
317
+ 'orchestrator_metrics': self._orchestrator.get_metrics(),
318
+ 'agent_names': list(self._runtime_agents.keys()),
319
+ }
320
+
321
+
322
+ # Global registry instance
323
+ _registry: Optional[AgentRegistry] = None
324
+
325
+
326
+ def get_registry() -> AgentRegistry:
327
+ """Get global agent registry instance."""
328
+ global _registry
329
+ if _registry is None:
330
+ _registry = AgentRegistry()
331
+ return _registry
332
+
333
+
334
+ async def initialize_registry() -> AgentRegistry:
335
+ """Initialize registry and load agents from database."""
336
+ registry = get_registry()
337
+
338
+ try:
339
+ # Load all active agents
340
+ count = await registry.reload_all_agents()
341
+ logger.info(f"Initialized registry with {count} agents")
342
+ except Exception as e:
343
+ logger.error(f"Failed to initialize registry: {e}")
344
+
345
+ return registry
@@ -0,0 +1,50 @@
1
+ """
2
+ Django signals for orchestrator integration.
3
+ """
4
+
5
+ import logging
6
+ from django.db.models.signals import post_save, post_delete
7
+ from django.dispatch import receiver
8
+ from django.contrib.auth.models import User
9
+
10
+ from ..models.registry import AgentDefinition
11
+ from .registry import get_registry
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @receiver(post_save, sender=AgentDefinition)
17
+ async def agent_definition_saved(sender, instance: AgentDefinition, created, **kwargs):
18
+ """Handle agent definition save."""
19
+ registry = get_registry()
20
+
21
+ if created:
22
+ logger.info(f"New agent definition created: {instance.name}")
23
+ else:
24
+ logger.info(f"Agent definition updated: {instance.name}")
25
+
26
+ # Reload agent if it exists in runtime
27
+ if instance.name in registry.get_runtime_agents():
28
+ try:
29
+ await registry.reload_agent(instance.name)
30
+ logger.info(f"Reloaded runtime agent: {instance.name}")
31
+ except Exception as e:
32
+ logger.error(f"Failed to reload agent '{instance.name}': {e}")
33
+
34
+
35
+ @receiver(post_delete, sender=AgentDefinition)
36
+ def agent_definition_deleted(sender, instance: AgentDefinition, **kwargs):
37
+ """Handle agent definition deletion."""
38
+ registry = get_registry()
39
+
40
+ # Remove from runtime if exists
41
+ if instance.name in registry.get_runtime_agents():
42
+ del registry._runtime_agents[instance.name]
43
+ registry.orchestrator.unregister_agent(instance.name)
44
+ logger.info(f"Removed runtime agent: {instance.name}")
45
+
46
+
47
+ def setup_signals():
48
+ """Setup signal handlers."""
49
+ # Signals are automatically connected via decorators
50
+ logger.info("Django Orchestrator signals configured")
@@ -0,0 +1,3 @@
1
+ """
2
+ Django management commands for orchestrator.
3
+ """
@@ -0,0 +1,3 @@
1
+ """
2
+ Management commands for Django Orchestrator.
3
+ """