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.
- 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 +444 -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 +79 -17
- 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.0.dist-info}/METADATA +83 -86
- django_cfg-1.2.0.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.0.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
- {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")
|