django-cfg 1.3.9__py3-none-any.whl β†’ 1.3.11__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 (187) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  3. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  4. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  5. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  13. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  14. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  15. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  16. django_cfg/apps/payments/config/__init__.py +14 -15
  17. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  18. django_cfg/apps/payments/config/helpers.py +8 -13
  19. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  20. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  21. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  22. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  23. django_cfg/apps/payments/models/payments.py +94 -0
  24. django_cfg/apps/payments/services/core/base.py +4 -4
  25. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  26. django_cfg/apps/payments/services/providers/base.py +209 -3
  27. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  28. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  29. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  31. django_cfg/apps/payments/services/providers/registry.py +5 -5
  32. django_cfg/apps/payments/services/types/requests.py +19 -7
  33. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  34. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  35. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  36. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  37. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  38. django_cfg/apps/payments/urls.py +3 -2
  39. django_cfg/apps/payments/views/api/currencies.py +3 -0
  40. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  41. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  42. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  43. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  44. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  45. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  47. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  52. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  53. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  54. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  55. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html β†’ overview_content.html} +30 -11
  56. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  57. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  58. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  59. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  60. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  61. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  62. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  63. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  66. django_cfg/apps/tasks/urls.py +2 -2
  67. django_cfg/apps/tasks/urls_admin.py +2 -2
  68. django_cfg/apps/tasks/utils/__init__.py +1 -0
  69. django_cfg/apps/tasks/utils/simulator.py +356 -0
  70. django_cfg/apps/tasks/views/__init__.py +16 -0
  71. django_cfg/apps/tasks/views/api.py +569 -0
  72. django_cfg/apps/tasks/views/dashboard.py +58 -0
  73. django_cfg/core/integration/__init__.py +21 -0
  74. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  75. django_cfg/models/constance.py +0 -11
  76. django_cfg/models/payments.py +137 -3
  77. django_cfg/modules/django_tasks.py +54 -21
  78. django_cfg/registry/core.py +4 -9
  79. django_cfg/template_archive/django_sample.zip +0 -0
  80. {django_cfg-1.3.9.dist-info β†’ django_cfg-1.3.11.dist-info}/METADATA +2 -2
  81. {django_cfg-1.3.9.dist-info β†’ django_cfg-1.3.11.dist-info}/RECORD +84 -152
  82. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  83. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  84. django_cfg/apps/payments/config/constance/fields.py +0 -69
  85. django_cfg/apps/payments/config/constance/settings.py +0 -160
  86. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  87. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  88. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  89. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  90. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  91. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  92. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  93. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  94. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  95. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  96. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  97. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  98. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  99. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  100. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  101. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  102. django_cfg/apps/tasks/views.py +0 -461
  103. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  104. django_cfg/management/commands/app_agent_generate.py +0 -342
  105. django_cfg/management/commands/app_agent_info.py +0 -308
  106. django_cfg/management/commands/auto_generate.py +0 -486
  107. django_cfg/modules/django_app_agent/__init__.py +0 -87
  108. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  109. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  110. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  111. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  112. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  113. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  114. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  119. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  120. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  121. django_cfg/modules/django_app_agent/core/config.py +0 -300
  122. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  123. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  124. django_cfg/modules/django_app_agent/models/base.py +0 -283
  125. django_cfg/modules/django_app_agent/models/context.py +0 -496
  126. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  127. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  128. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  129. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  130. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  131. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  132. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  133. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  134. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  135. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  136. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  137. django_cfg/modules/django_app_agent/services/base.py +0 -437
  138. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  139. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  140. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  141. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  142. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  143. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  144. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  145. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  146. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  147. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  148. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  149. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  150. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  151. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  152. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  153. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  154. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  155. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  156. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  157. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  158. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  159. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  160. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  161. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  171. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  172. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  173. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  174. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  175. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  176. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  177. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  178. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  179. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  180. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  181. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  182. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  183. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  184. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  185. {django_cfg-1.3.9.dist-info β†’ django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  186. {django_cfg-1.3.9.dist-info β†’ django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  187. {django_cfg-1.3.9.dist-info β†’ django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,430 +0,0 @@
1
- """
2
- Agent execution management for Django App Agent Module.
3
-
4
- This module provides execution management and orchestration for AI agents,
5
- including result handling, error management, and performance tracking.
6
- """
7
-
8
- from typing import TypeVar, Generic, Optional, Dict, Any, List, Union, Callable, Awaitable
9
- from dataclasses import dataclass, field
10
- from datetime import datetime, timezone
11
- from enum import Enum
12
- import asyncio
13
-
14
- from pydantic import BaseModel, Field, ConfigDict
15
-
16
- from ...core.config import AgentConfig
17
- from ...core.exceptions import AgentExecutionError, ValidationError
18
- from ...models.base import TimestampedModel
19
- from ...utils.logging import StructuredLogger, get_logger
20
- from .context import AgentDependencies, AgentContext
21
- from .agent import DjangoAgent
22
-
23
- # Type variables
24
- OutputT = TypeVar('OutputT')
25
- DepsT = TypeVar('DepsT', bound=AgentDependencies)
26
-
27
-
28
- class ExecutionStatus(str, Enum):
29
- """Status of agent execution."""
30
- PENDING = "pending"
31
- RUNNING = "running"
32
- COMPLETED = "completed"
33
- FAILED = "failed"
34
- CANCELLED = "cancelled"
35
-
36
-
37
- class ExecutionResult(BaseModel, Generic[OutputT]):
38
- """Result of agent execution."""
39
-
40
- model_config = ConfigDict(
41
- extra='forbid',
42
- validate_assignment=True,
43
- arbitrary_types_allowed=True
44
- )
45
-
46
- # Execution metadata
47
- execution_id: str = Field(description="Unique execution identifier")
48
- agent_name: str = Field(description="Name of the agent that was executed")
49
- status: ExecutionStatus = Field(description="Execution status")
50
-
51
- # Timing information
52
- start_time: datetime = Field(description="Execution start time")
53
- end_time: Optional[datetime] = Field(default=None, description="Execution end time")
54
-
55
- # Results
56
- output: Optional[OutputT] = Field(default=None, description="Agent output")
57
- error: Optional[str] = Field(default=None, description="Error message if failed")
58
-
59
- # Performance metrics
60
- execution_time_seconds: float = Field(default=0.0, description="Total execution time")
61
- token_usage: Dict[str, int] = Field(default_factory=dict, description="Token usage by provider")
62
- api_calls_count: int = Field(default=0, description="Number of API calls made")
63
-
64
- # Context information
65
- correlation_id: str = Field(description="Correlation ID for tracing")
66
- operation_name: str = Field(description="Name of the operation")
67
-
68
- @property
69
- def is_successful(self) -> bool:
70
- """Check if execution was successful."""
71
- return self.status == ExecutionStatus.COMPLETED and self.output is not None
72
-
73
- @property
74
- def is_failed(self) -> bool:
75
- """Check if execution failed."""
76
- return self.status == ExecutionStatus.FAILED
77
-
78
- def get_summary(self) -> Dict[str, Any]:
79
- """Get execution summary."""
80
- return {
81
- "execution_id": self.execution_id,
82
- "agent_name": self.agent_name,
83
- "status": self.status.value,
84
- "is_successful": self.is_successful,
85
- "execution_time_seconds": self.execution_time_seconds,
86
- "total_tokens": sum(self.token_usage.values()),
87
- "api_calls": self.api_calls_count,
88
- "has_output": self.output is not None,
89
- "has_error": self.error is not None,
90
- }
91
-
92
-
93
- @dataclass
94
- class ExecutionPlan:
95
- """Plan for executing multiple agents in sequence or parallel."""
96
-
97
- name: str
98
- agents: List[DjangoAgent] = field(default_factory=list)
99
- dependencies: Dict[str, List[str]] = field(default_factory=dict)
100
- parallel_groups: List[List[str]] = field(default_factory=list)
101
- timeout_seconds: float = 300.0
102
-
103
- def add_agent(self, agent: DjangoAgent, depends_on: Optional[List[str]] = None) -> None:
104
- """Add agent to execution plan."""
105
- self.agents.append(agent)
106
- if depends_on:
107
- self.dependencies[agent.agent_name] = depends_on
108
-
109
- def add_parallel_group(self, agent_names: List[str]) -> None:
110
- """Add group of agents that can run in parallel."""
111
- self.parallel_groups.append(agent_names)
112
-
113
- def validate(self) -> List[str]:
114
- """Validate execution plan."""
115
- errors = []
116
- agent_names = {agent.agent_name for agent in self.agents}
117
-
118
- # Check dependencies reference existing agents
119
- for agent_name, deps in self.dependencies.items():
120
- if agent_name not in agent_names:
121
- errors.append(f"Agent '{agent_name}' in dependencies not found in plan")
122
-
123
- for dep in deps:
124
- if dep not in agent_names:
125
- errors.append(f"Dependency '{dep}' for '{agent_name}' not found in plan")
126
-
127
- # Check parallel groups reference existing agents
128
- for group in self.parallel_groups:
129
- for agent_name in group:
130
- if agent_name not in agent_names:
131
- errors.append(f"Agent '{agent_name}' in parallel group not found in plan")
132
-
133
- return errors
134
-
135
-
136
- class AgentExecutor:
137
- """Executor for managing and running Django App Agent AI agents."""
138
-
139
- def __init__(self, config: AgentConfig):
140
- """Initialize agent executor.
141
-
142
- Args:
143
- config: Agent configuration
144
- """
145
- self.config = config
146
- self.logger = get_logger("agent_executor")
147
- self._active_executions: Dict[str, ExecutionResult] = {}
148
-
149
- async def execute_single(
150
- self,
151
- agent: DjangoAgent[DepsT, OutputT],
152
- prompt: str,
153
- deps: DepsT,
154
- execution_id: Optional[str] = None,
155
- timeout_seconds: Optional[float] = None
156
- ) -> ExecutionResult[OutputT]:
157
- """Execute a single agent.
158
-
159
- Args:
160
- agent: Agent to execute
161
- prompt: Input prompt
162
- deps: Agent dependencies
163
- execution_id: Optional execution ID
164
- timeout_seconds: Optional timeout override
165
-
166
- Returns:
167
- Execution result
168
- """
169
- import uuid
170
-
171
- if execution_id is None:
172
- execution_id = str(uuid.uuid4())
173
-
174
- start_time = datetime.now(timezone.utc)
175
-
176
- # Create execution result
177
- result = ExecutionResult[OutputT](
178
- execution_id=execution_id,
179
- agent_name=agent.agent_name,
180
- status=ExecutionStatus.PENDING,
181
- start_time=start_time,
182
- correlation_id=deps.correlation_id,
183
- operation_name=deps.operation_name
184
- )
185
-
186
- # Track active execution
187
- self._active_executions[execution_id] = result
188
-
189
- try:
190
- # Update status to running
191
- result.status = ExecutionStatus.RUNNING
192
-
193
- # Create execution context
194
- context = AgentContext()
195
-
196
- # Determine timeout
197
- timeout = timeout_seconds or 300.0
198
-
199
- self.logger.info(
200
- f"Starting execution of agent {agent.agent_name}",
201
- execution_id=execution_id,
202
- agent_name=agent.agent_name,
203
- timeout_seconds=timeout
204
- )
205
-
206
- # Execute agent with timeout
207
- output = await asyncio.wait_for(
208
- agent.run(prompt, deps, context),
209
- timeout=timeout
210
- )
211
-
212
- # Update result with success
213
- end_time = datetime.now(timezone.utc)
214
- result.status = ExecutionStatus.COMPLETED
215
- result.output = output
216
- result.end_time = end_time
217
- result.execution_time_seconds = (end_time - start_time).total_seconds()
218
- result.token_usage = context.token_usage.copy()
219
- result.api_calls_count = context.api_calls_count
220
-
221
- self.logger.info(
222
- f"Completed execution of agent {agent.agent_name}",
223
- execution_id=execution_id,
224
- execution_time_seconds=result.execution_time_seconds,
225
- success=True
226
- )
227
-
228
- return result
229
-
230
- except asyncio.TimeoutError:
231
- error_msg = f"Agent {agent.agent_name} execution timed out after {timeout} seconds"
232
- result.status = ExecutionStatus.FAILED
233
- result.error = error_msg
234
- result.end_time = datetime.now(timezone.utc)
235
- result.execution_time_seconds = (result.end_time - start_time).total_seconds()
236
-
237
- self.logger.error(
238
- error_msg,
239
- execution_id=execution_id,
240
- agent_name=agent.agent_name,
241
- timeout_seconds=timeout
242
- )
243
-
244
- return result
245
-
246
- except Exception as e:
247
- error_msg = f"Agent {agent.agent_name} execution failed: {e}"
248
- result.status = ExecutionStatus.FAILED
249
- result.error = error_msg
250
- result.end_time = datetime.now(timezone.utc)
251
- result.execution_time_seconds = (result.end_time - start_time).total_seconds()
252
-
253
- self.logger.error(
254
- error_msg,
255
- execution_id=execution_id,
256
- agent_name=agent.agent_name,
257
- error=str(e),
258
- error_type=type(e).__name__
259
- )
260
-
261
- return result
262
-
263
- finally:
264
- # Remove from active executions
265
- self._active_executions.pop(execution_id, None)
266
-
267
- async def execute_plan(
268
- self,
269
- plan: ExecutionPlan,
270
- prompt: str,
271
- deps: AgentDependencies,
272
- execution_id: Optional[str] = None
273
- ) -> Dict[str, ExecutionResult]:
274
- """Execute multiple agents according to a plan.
275
-
276
- Args:
277
- plan: Execution plan
278
- prompt: Input prompt for all agents
279
- deps: Base dependencies (will be copied for each agent)
280
- execution_id: Optional execution ID
281
-
282
- Returns:
283
- Dictionary mapping agent names to execution results
284
- """
285
- import uuid
286
-
287
- if execution_id is None:
288
- execution_id = str(uuid.uuid4())
289
-
290
- # Validate plan
291
- validation_errors = plan.validate()
292
- if validation_errors:
293
- raise ValidationError(
294
- f"Invalid execution plan: {'; '.join(validation_errors)}",
295
- validation_type="execution_plan"
296
- )
297
-
298
- self.logger.info(
299
- f"Starting execution plan '{plan.name}'",
300
- execution_id=execution_id,
301
- agents_count=len(plan.agents),
302
- parallel_groups=len(plan.parallel_groups)
303
- )
304
-
305
- results: Dict[str, ExecutionResult] = {}
306
- agent_map = {agent.agent_name: agent for agent in plan.agents}
307
-
308
- try:
309
- # Execute agents in dependency order
310
- executed = set()
311
-
312
- while len(executed) < len(plan.agents):
313
- # Find agents ready to execute (dependencies satisfied)
314
- ready_agents = []
315
-
316
- for agent in plan.agents:
317
- if agent.agent_name in executed:
318
- continue
319
-
320
- # Check if dependencies are satisfied
321
- agent_deps = plan.dependencies.get(agent.agent_name, [])
322
- if all(dep in executed for dep in agent_deps):
323
- ready_agents.append(agent)
324
-
325
- if not ready_agents:
326
- # Check for circular dependencies
327
- remaining = [a.agent_name for a in plan.agents if a.agent_name not in executed]
328
- raise AgentExecutionError(
329
- f"Circular dependency detected or no agents ready to execute. Remaining: {remaining}",
330
- agent_name="executor",
331
- agent_operation="execute_plan"
332
- )
333
-
334
- # Execute ready agents (potentially in parallel)
335
- tasks = []
336
- for agent in ready_agents:
337
- # Create agent-specific dependencies
338
- agent_deps = AgentDependencies(
339
- config=deps.config,
340
- logger=deps.logger,
341
- project_context=deps.project_context,
342
- infrastructure_context=deps.infrastructure_context,
343
- correlation_id=f"{execution_id}_{agent.agent_name}",
344
- operation_name=f"{deps.operation_name}_{agent.agent_name}",
345
- project_root=deps.project_root,
346
- output_directory=deps.output_directory,
347
- execution_metadata=deps.execution_metadata.copy()
348
- )
349
-
350
- task = self.execute_single(
351
- agent,
352
- prompt,
353
- agent_deps,
354
- f"{execution_id}_{agent.agent_name}",
355
- plan.timeout_seconds
356
- )
357
- tasks.append((agent.agent_name, task))
358
-
359
- # Wait for all ready agents to complete
360
- for agent_name, task in tasks:
361
- result = await task
362
- results[agent_name] = result
363
- executed.add(agent_name)
364
-
365
- if not result.is_successful:
366
- self.logger.warning(
367
- f"Agent {agent_name} failed in execution plan",
368
- execution_id=execution_id,
369
- error=result.error
370
- )
371
-
372
- self.logger.info(
373
- f"Completed execution plan '{plan.name}'",
374
- execution_id=execution_id,
375
- successful_agents=sum(1 for r in results.values() if r.is_successful),
376
- failed_agents=sum(1 for r in results.values() if r.is_failed)
377
- )
378
-
379
- return results
380
-
381
- except Exception as e:
382
- self.logger.error(
383
- f"Execution plan '{plan.name}' failed",
384
- execution_id=execution_id,
385
- error=str(e),
386
- error_type=type(e).__name__
387
- )
388
- raise
389
-
390
- def get_active_executions(self) -> Dict[str, ExecutionResult]:
391
- """Get currently active executions."""
392
- return self._active_executions.copy()
393
-
394
- def cancel_execution(self, execution_id: str) -> bool:
395
- """Cancel an active execution.
396
-
397
- Args:
398
- execution_id: ID of execution to cancel
399
-
400
- Returns:
401
- True if execution was cancelled, False if not found
402
- """
403
- if execution_id in self._active_executions:
404
- result = self._active_executions[execution_id]
405
- result.status = ExecutionStatus.CANCELLED
406
- result.end_time = datetime.now(timezone.utc)
407
- result.execution_time_seconds = (result.end_time - result.start_time).total_seconds()
408
-
409
- self.logger.info(
410
- f"Cancelled execution {execution_id}",
411
- execution_id=execution_id,
412
- agent_name=result.agent_name
413
- )
414
-
415
- return True
416
-
417
- return False
418
-
419
- def get_execution_summary(self) -> Dict[str, Any]:
420
- """Get summary of executor state."""
421
- active = self.get_active_executions()
422
-
423
- return {
424
- "active_executions_count": len(active),
425
- "active_agents": [r.agent_name for r in active.values()],
426
- "executor_config": {
427
- "debug_mode": self.config.debug_mode,
428
- "log_level": self.config.log_level.value,
429
- }
430
- }
@@ -1,12 +0,0 @@
1
- """
2
- Code Generation Agents for Django App Agent Module.
3
-
4
- This module contains AI agents responsible for generating Django application code
5
- using Pydantic AI framework.
6
- """
7
-
8
- from .app_generator import AppGeneratorAgent
9
-
10
- __all__ = [
11
- "AppGeneratorAgent",
12
- ]
@@ -1,15 +0,0 @@
1
- """
2
- Django Application Generator Agent Package.
3
-
4
- This package contains the decomposed components of the AI agent
5
- responsible for generating Django applications with intelligent code generation.
6
- """
7
-
8
- from .main import AppGeneratorAgent
9
- from .models import FileGenerationRequest, GeneratedFileResponse
10
-
11
- __all__ = [
12
- 'AppGeneratorAgent',
13
- 'FileGenerationRequest',
14
- 'GeneratedFileResponse'
15
- ]
@@ -1,147 +0,0 @@
1
- """
2
- Configuration validation for the App Generator Agent.
3
-
4
- This module handles API key validation and model configuration
5
- using django-cfg integration.
6
- """
7
-
8
- import os
9
- from typing import Optional
10
-
11
- from pydantic_ai.models.openai import OpenAIModel
12
-
13
- from ....core.config import AgentConfig, AIProvider
14
- from ....core.exceptions import ConfigurationError
15
-
16
-
17
- class ConfigValidator:
18
- """Validates and configures API keys and AI models."""
19
-
20
- def __init__(self):
21
- """Initialize the config validator."""
22
- self.model: Optional[OpenAIModel] = None
23
-
24
- def validate_and_configure(self, config) -> OpenAIModel:
25
- """
26
- Validate API keys and configure AI model.
27
-
28
- Args:
29
- config: Configuration object (AgentConfig or other)
30
-
31
- Returns:
32
- Configured OpenAI model
33
-
34
- Raises:
35
- ConfigurationError: If no valid API keys found
36
- """
37
- try:
38
- # Get configuration from django-cfg
39
- print(f"πŸ” Debug config type: {type(config)}")
40
- print(f"πŸ” Debug config: {config}")
41
-
42
- if isinstance(config, AgentConfig):
43
- # Use provided AgentConfig
44
- agent_config = config
45
- print("βœ… Using provided AgentConfig")
46
- else:
47
- # Load from django-cfg
48
- print("πŸ”„ Loading from django-cfg...")
49
- agent_config = AgentConfig.from_django_cfg()
50
- print(f"βœ… Loaded AgentConfig: {type(agent_config)}")
51
-
52
- print(f"πŸ” AgentConfig attributes: {dir(agent_config)}")
53
-
54
- # Get API keys from configuration
55
- openai_key = self._get_api_key(agent_config, AIProvider.OPENAI)
56
- openrouter_key = self._get_api_key(agent_config, AIProvider.OPENROUTER)
57
-
58
- print(f"πŸ” API keys via get_api_key: OpenAI={bool(openai_key)}, OpenRouter={bool(openrouter_key)}")
59
-
60
- # Fallback to direct access
61
- if not openai_key and not openrouter_key:
62
- openai_key, openrouter_key = self._get_keys_direct_access(agent_config)
63
-
64
- # Debug: Print what we found
65
- print(f"πŸ” Final API Keys from django-cfg:")
66
- print(f" OpenAI: {'βœ… Found' if openai_key else '❌ Missing'}")
67
- print(f" OpenRouter: {'βœ… Found' if openrouter_key else '❌ Missing'}")
68
-
69
- if not openai_key and not openrouter_key:
70
- raise ConfigurationError(
71
- "❌ AI Agent Configuration Error: No API keys found in django-cfg!\n\n"
72
- "πŸ”‘ Required: Either OpenAI or OpenRouter API key must be configured.\n\n"
73
- "πŸ“ How to fix in django-cfg config:\n"
74
- " api_keys:\n"
75
- " openai: 'your-openai-key'\n"
76
- " openrouter: 'your-openrouter-key'\n\n"
77
- "πŸš€ Without API keys, AI agents cannot generate intelligent code!\n"
78
- " You'll only get basic template-based generation.",
79
- config_key="api_keys"
80
- )
81
-
82
- # Configure and return the model
83
- return self._configure_model(openai_key, openrouter_key)
84
-
85
- except Exception as e:
86
- print(f"❌ Error loading API keys from django-cfg: {e}")
87
- raise ConfigurationError(
88
- f"Failed to load API keys from django-cfg configuration: {e}\n\n"
89
- "πŸ”§ Make sure django-cfg is properly configured with API keys.",
90
- config_key="api_keys",
91
- cause=e
92
- )
93
-
94
- def _get_api_key(self, agent_config: AgentConfig, provider: AIProvider) -> Optional[str]:
95
- """Get API key for specific provider."""
96
- if hasattr(agent_config, 'get_api_key'):
97
- return agent_config.get_api_key(provider)
98
- return None
99
-
100
- def _get_keys_direct_access(self, agent_config: AgentConfig) -> tuple[Optional[str], Optional[str]]:
101
- """Get API keys via direct access as fallback."""
102
- openai_key = None
103
- openrouter_key = None
104
-
105
- print("πŸ”„ Trying direct access to api_keys...")
106
- if hasattr(agent_config, 'api_keys') and agent_config.api_keys:
107
- print(f"πŸ” api_keys type: {type(agent_config.api_keys)}")
108
- print(f"πŸ” api_keys content: {agent_config.api_keys}")
109
-
110
- if hasattr(agent_config.api_keys, 'get'):
111
- openai_key = agent_config.api_keys.get('openai', '')
112
- openrouter_key = agent_config.api_keys.get('openrouter', '')
113
- else:
114
- openai_key = getattr(agent_config.api_keys, 'openai', '')
115
- openrouter_key = getattr(agent_config.api_keys, 'openrouter', '')
116
-
117
- print(f"πŸ” Direct access results: OpenAI={bool(openai_key)}, OpenRouter={bool(openrouter_key)}")
118
-
119
- return openai_key, openrouter_key
120
-
121
- def _configure_model(self, openai_key: Optional[str], openrouter_key: Optional[str]) -> OpenAIModel:
122
- """Configure AI model with available API key."""
123
- if openrouter_key:
124
- print("πŸš€ Using OpenRouter API via django-cfg")
125
- print(f"πŸ” OpenRouter key length: {len(openrouter_key)}")
126
- print(f"πŸ” OpenRouter key prefix: {openrouter_key[:20]}...")
127
-
128
- # Set environment variables for OpenRouter
129
- os.environ['OPENAI_API_KEY'] = openrouter_key
130
- os.environ['OPENAI_BASE_URL'] = 'https://openrouter.ai/api/v1'
131
- # OpenRouter Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ
132
- os.environ['OPENAI_DEFAULT_HEADERS'] = '{"HTTP-Referer": "https://djangocfg.com", "X-Title": "Django CFG App Agent"}'
133
-
134
- self.model = OpenAIModel('gpt-4o-mini')
135
-
136
- elif openai_key:
137
- print("πŸš€ Using OpenAI API via django-cfg")
138
-
139
- # Set environment variable for OpenAI
140
- os.environ['OPENAI_API_KEY'] = openai_key
141
- # Remove base URL for standard OpenAI
142
- if 'OPENAI_BASE_URL' in os.environ:
143
- del os.environ['OPENAI_BASE_URL']
144
-
145
- self.model = OpenAIModel('gpt-4o-mini')
146
-
147
- return self.model