django-cfg 1.3.5__py3-none-any.whl → 1.3.9__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 (252) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/__init__.py +24 -8
  3. django_cfg/apps/accounts/admin/activity_admin.py +146 -0
  4. django_cfg/apps/accounts/admin/filters.py +98 -22
  5. django_cfg/apps/accounts/admin/group_admin.py +86 -0
  6. django_cfg/apps/accounts/admin/inlines.py +42 -13
  7. django_cfg/apps/accounts/admin/otp_admin.py +115 -0
  8. django_cfg/apps/accounts/admin/registration_admin.py +173 -0
  9. django_cfg/apps/accounts/admin/resources.py +123 -19
  10. django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
  11. django_cfg/apps/accounts/admin/user_admin.py +362 -0
  12. django_cfg/apps/agents/admin/__init__.py +17 -4
  13. django_cfg/apps/agents/admin/execution_admin.py +204 -183
  14. django_cfg/apps/agents/admin/registry_admin.py +230 -255
  15. django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
  16. django_cfg/apps/agents/core/__init__.py +1 -1
  17. django_cfg/apps/agents/core/django_agent.py +221 -0
  18. django_cfg/apps/agents/core/exceptions.py +14 -0
  19. django_cfg/apps/agents/core/orchestrator.py +18 -3
  20. django_cfg/apps/knowbase/admin/__init__.py +1 -1
  21. django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
  22. django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
  23. django_cfg/apps/knowbase/admin/document_admin.py +269 -262
  24. django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
  25. django_cfg/apps/knowbase/config/settings.py +21 -4
  26. django_cfg/apps/knowbase/views/chat_views.py +3 -0
  27. django_cfg/apps/leads/admin/__init__.py +3 -1
  28. django_cfg/apps/leads/admin/leads_admin.py +235 -35
  29. django_cfg/apps/maintenance/admin/__init__.py +2 -2
  30. django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
  31. django_cfg/apps/maintenance/admin/log_admin.py +143 -61
  32. django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
  33. django_cfg/apps/maintenance/admin/site_admin.py +213 -352
  34. django_cfg/apps/newsletter/admin/__init__.py +29 -2
  35. django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
  36. django_cfg/apps/payments/admin/__init__.py +18 -27
  37. django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
  38. django_cfg/apps/payments/admin/balance_admin.py +166 -632
  39. django_cfg/apps/payments/admin/currencies_admin.py +235 -607
  40. django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
  41. django_cfg/apps/payments/admin/filters.py +83 -3
  42. django_cfg/apps/payments/admin/networks_admin.py +258 -0
  43. django_cfg/apps/payments/admin/payments_admin.py +171 -461
  44. django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
  45. django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
  46. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +105 -34
  47. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +12 -16
  48. django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
  49. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +13 -18
  50. django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
  51. django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
  52. django_cfg/apps/payments/middleware/api_access.py +32 -6
  53. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +26 -0
  54. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +28 -0
  55. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +30 -0
  56. django_cfg/apps/payments/models/balance.py +12 -0
  57. django_cfg/apps/payments/models/currencies.py +106 -32
  58. django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
  59. django_cfg/apps/payments/services/core/currency_service.py +35 -28
  60. django_cfg/apps/payments/services/core/payment_service.py +1 -1
  61. django_cfg/apps/payments/services/providers/__init__.py +3 -0
  62. django_cfg/apps/payments/services/providers/base.py +95 -39
  63. django_cfg/apps/payments/services/providers/models/__init__.py +40 -0
  64. django_cfg/apps/payments/services/providers/models/base.py +122 -0
  65. django_cfg/apps/payments/services/providers/models/providers.py +87 -0
  66. django_cfg/apps/payments/services/providers/models/universal.py +48 -0
  67. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
  68. django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
  69. django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
  70. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
  71. django_cfg/apps/payments/services/providers/{nowpayments.py → nowpayments/provider.py} +240 -209
  72. django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
  73. django_cfg/apps/payments/services/providers/registry.py +4 -32
  74. django_cfg/apps/payments/services/providers/sync_service.py +277 -0
  75. django_cfg/apps/payments/static/payments/js/api-client.js +23 -5
  76. django_cfg/apps/payments/static/payments/js/payment-form.js +65 -8
  77. django_cfg/apps/payments/tasks/__init__.py +39 -0
  78. django_cfg/apps/payments/tasks/types.py +73 -0
  79. django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
  80. django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
  81. django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
  82. django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
  83. django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
  84. django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
  85. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
  86. django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
  87. django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
  88. django_cfg/apps/payments/urls_admin.py +1 -1
  89. django_cfg/apps/payments/views/api/currencies.py +5 -5
  90. django_cfg/apps/payments/views/overview/services.py +2 -2
  91. django_cfg/apps/payments/views/serializers/currencies.py +4 -3
  92. django_cfg/apps/support/admin/__init__.py +10 -1
  93. django_cfg/apps/support/admin/support_admin.py +338 -141
  94. django_cfg/apps/tasks/admin/__init__.py +11 -0
  95. django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
  96. django_cfg/apps/urls.py +1 -2
  97. django_cfg/config.py +1 -1
  98. django_cfg/core/config.py +10 -5
  99. django_cfg/core/generation.py +1 -1
  100. django_cfg/management/commands/__init__.py +13 -1
  101. django_cfg/management/commands/app_agent_diagnose.py +470 -0
  102. django_cfg/management/commands/app_agent_generate.py +342 -0
  103. django_cfg/management/commands/app_agent_info.py +308 -0
  104. django_cfg/management/commands/migrate_all.py +9 -3
  105. django_cfg/management/commands/migrator.py +11 -6
  106. django_cfg/management/commands/rundramatiq.py +3 -2
  107. django_cfg/middleware/__init__.py +0 -2
  108. django_cfg/models/api_keys.py +115 -0
  109. django_cfg/modules/django_admin/__init__.py +64 -0
  110. django_cfg/modules/django_admin/decorators/__init__.py +13 -0
  111. django_cfg/modules/django_admin/decorators/actions.py +106 -0
  112. django_cfg/modules/django_admin/decorators/display.py +106 -0
  113. django_cfg/modules/django_admin/mixins/__init__.py +14 -0
  114. django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
  115. django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
  116. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
  117. django_cfg/modules/django_admin/models/__init__.py +20 -0
  118. django_cfg/modules/django_admin/models/action_models.py +33 -0
  119. django_cfg/modules/django_admin/models/badge_models.py +20 -0
  120. django_cfg/modules/django_admin/models/base.py +26 -0
  121. django_cfg/modules/django_admin/models/display_models.py +31 -0
  122. django_cfg/modules/django_admin/utils/badges.py +159 -0
  123. django_cfg/modules/django_admin/utils/displays.py +247 -0
  124. django_cfg/modules/django_app_agent/__init__.py +87 -0
  125. django_cfg/modules/django_app_agent/agents/__init__.py +40 -0
  126. django_cfg/modules/django_app_agent/agents/base/__init__.py +24 -0
  127. django_cfg/modules/django_app_agent/agents/base/agent.py +354 -0
  128. django_cfg/modules/django_app_agent/agents/base/context.py +236 -0
  129. django_cfg/modules/django_app_agent/agents/base/executor.py +430 -0
  130. django_cfg/modules/django_app_agent/agents/generation/__init__.py +12 -0
  131. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +15 -0
  132. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +147 -0
  133. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +99 -0
  134. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +32 -0
  135. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +290 -0
  136. django_cfg/modules/django_app_agent/agents/interfaces.py +376 -0
  137. django_cfg/modules/django_app_agent/core/__init__.py +33 -0
  138. django_cfg/modules/django_app_agent/core/config.py +300 -0
  139. django_cfg/modules/django_app_agent/core/exceptions.py +359 -0
  140. django_cfg/modules/django_app_agent/models/__init__.py +71 -0
  141. django_cfg/modules/django_app_agent/models/base.py +283 -0
  142. django_cfg/modules/django_app_agent/models/context.py +496 -0
  143. django_cfg/modules/django_app_agent/models/enums.py +481 -0
  144. django_cfg/modules/django_app_agent/models/requests.py +500 -0
  145. django_cfg/modules/django_app_agent/models/responses.py +585 -0
  146. django_cfg/modules/django_app_agent/pytest.ini +6 -0
  147. django_cfg/modules/django_app_agent/services/__init__.py +42 -0
  148. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +30 -0
  149. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +133 -0
  150. django_cfg/modules/django_app_agent/services/app_generator/context.py +40 -0
  151. django_cfg/modules/django_app_agent/services/app_generator/main.py +202 -0
  152. django_cfg/modules/django_app_agent/services/app_generator/structure.py +316 -0
  153. django_cfg/modules/django_app_agent/services/app_generator/validation.py +125 -0
  154. django_cfg/modules/django_app_agent/services/base.py +437 -0
  155. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +34 -0
  156. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +141 -0
  157. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +276 -0
  158. django_cfg/modules/django_app_agent/services/context_builder/main.py +272 -0
  159. django_cfg/modules/django_app_agent/services/context_builder/models.py +40 -0
  160. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +85 -0
  161. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +31 -0
  162. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +311 -0
  163. django_cfg/modules/django_app_agent/services/project_scanner/main.py +221 -0
  164. django_cfg/modules/django_app_agent/services/project_scanner/models.py +59 -0
  165. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +94 -0
  166. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +28 -0
  167. django_cfg/modules/django_app_agent/services/questioning_service/main.py +273 -0
  168. django_cfg/modules/django_app_agent/services/questioning_service/models.py +111 -0
  169. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +251 -0
  170. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +347 -0
  171. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +356 -0
  172. django_cfg/modules/django_app_agent/services/report_service.py +332 -0
  173. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +18 -0
  174. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +236 -0
  175. django_cfg/modules/django_app_agent/services/template_manager/main.py +159 -0
  176. django_cfg/modules/django_app_agent/services/template_manager/models.py +36 -0
  177. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +100 -0
  178. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +105 -0
  179. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +31 -0
  180. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +44 -0
  181. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +81 -0
  182. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +107 -0
  183. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +139 -0
  184. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +91 -0
  185. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +195 -0
  186. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +35 -0
  187. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +211 -0
  188. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +200 -0
  189. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +25 -0
  190. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +333 -0
  191. django_cfg/modules/django_app_agent/services/validation_service/main.py +242 -0
  192. django_cfg/modules/django_app_agent/services/validation_service/models.py +66 -0
  193. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +352 -0
  194. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +272 -0
  195. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +203 -0
  196. django_cfg/modules/django_app_agent/ui/__init__.py +25 -0
  197. django_cfg/modules/django_app_agent/ui/cli.py +419 -0
  198. django_cfg/modules/django_app_agent/ui/rich_components.py +622 -0
  199. django_cfg/modules/django_app_agent/utils/__init__.py +38 -0
  200. django_cfg/modules/django_app_agent/utils/logging.py +360 -0
  201. django_cfg/modules/django_app_agent/utils/validation.py +417 -0
  202. django_cfg/modules/django_currency/__init__.py +2 -2
  203. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  204. django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
  205. django_cfg/modules/django_currency/core/converter.py +12 -12
  206. django_cfg/modules/django_currency/database/__init__.py +2 -2
  207. django_cfg/modules/django_currency/database/database_loader.py +93 -42
  208. django_cfg/modules/django_llm/llm/client.py +10 -2
  209. django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
  210. django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
  211. django_cfg/modules/django_unfold/dashboard.py +14 -13
  212. django_cfg/modules/django_unfold/models/config.py +1 -1
  213. django_cfg/registry/core.py +3 -0
  214. django_cfg/registry/third_party.py +2 -2
  215. django_cfg/template_archive/django_sample.zip +0 -0
  216. {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/METADATA +2 -1
  217. {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/RECORD +224 -118
  218. django_cfg/apps/accounts/admin/activity.py +0 -96
  219. django_cfg/apps/accounts/admin/group.py +0 -17
  220. django_cfg/apps/accounts/admin/otp.py +0 -59
  221. django_cfg/apps/accounts/admin/registration_source.py +0 -97
  222. django_cfg/apps/accounts/admin/twilio_response.py +0 -227
  223. django_cfg/apps/accounts/admin/user.py +0 -300
  224. django_cfg/apps/agents/core/agent.py +0 -281
  225. django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
  226. django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
  227. django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
  228. django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
  229. django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
  230. django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
  231. django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
  232. django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
  233. django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
  234. django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
  235. django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
  236. django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
  237. django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
  238. django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
  239. django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
  240. django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
  241. django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
  242. django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
  243. django_cfg/apps/tasks/admin.py +0 -320
  244. django_cfg/middleware/static_nocache.py +0 -55
  245. django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
  246. /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
  247. /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
  248. /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
  249. /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
  250. {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/WHEEL +0 -0
  251. {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/entry_points.txt +0 -0
  252. {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,59 @@
1
+ """
2
+ Data Models for Project Scanner Service.
3
+
4
+ This module contains Pydantic models for project scanning
5
+ requests, results, and related data structures.
6
+ """
7
+
8
+ from typing import List, Dict, Any
9
+ from pathlib import Path
10
+
11
+ from pydantic import BaseModel, Field, ConfigDict
12
+
13
+ from ...models.context import ProjectContext, DjangoAppInfo, ArchitecturalPattern
14
+ from ...core.exceptions import ValidationError
15
+
16
+
17
+ class ProjectScanRequest(BaseModel):
18
+ """Request for project scanning operation."""
19
+
20
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
21
+
22
+ project_root: Path = Field(description="Root directory of the project to scan")
23
+ scan_depth: int = Field(default=3, ge=1, le=10, description="Maximum directory depth to scan")
24
+ include_patterns: List[str] = Field(
25
+ default_factory=lambda: ["*.py", "*.md", "*.txt", "*.yml", "*.yaml", "*.json"],
26
+ description="File patterns to include in scanning"
27
+ )
28
+ exclude_patterns: List[str] = Field(
29
+ default_factory=lambda: ["__pycache__", "*.pyc", ".git", "node_modules", "venv", ".env"],
30
+ description="File/directory patterns to exclude from scanning"
31
+ )
32
+ analyze_dependencies: bool = Field(default=True, description="Whether to analyze dependencies")
33
+ detect_patterns: bool = Field(default=True, description="Whether to detect architectural patterns")
34
+
35
+ def model_post_init(self, __context: Any) -> None:
36
+ """Validate project root exists."""
37
+ if not self.project_root.exists():
38
+ raise ValidationError(
39
+ f"Project root directory does not exist: {self.project_root}",
40
+ validation_type="project_path"
41
+ )
42
+ if not self.project_root.is_dir():
43
+ raise ValidationError(
44
+ f"Project root is not a directory: {self.project_root}",
45
+ validation_type="project_path"
46
+ )
47
+
48
+
49
+ class ScanResult(BaseModel):
50
+ """Result of project scanning operation."""
51
+
52
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
53
+
54
+ project_context: ProjectContext = Field(description="Comprehensive project context")
55
+ discovered_apps: List[DjangoAppInfo] = Field(default_factory=list, description="Discovered Django applications")
56
+ architectural_patterns: List[ArchitecturalPattern] = Field(default_factory=list, description="Detected architectural patterns")
57
+ file_summary: Dict[str, Any] = Field(default_factory=dict, description="File structure summary")
58
+ dependency_graph: Dict[str, List[str]] = Field(default_factory=dict, description="Application dependency graph")
59
+ scan_statistics: Dict[str, int] = Field(default_factory=dict, description="Scanning statistics")
@@ -0,0 +1,94 @@
1
+ """
2
+ Architectural Pattern Detection Module for Project Scanner.
3
+
4
+ This module handles detection of architectural patterns and
5
+ conventions within Django/django-cfg projects.
6
+ """
7
+
8
+ from typing import List, Dict, Any
9
+ from pathlib import Path
10
+
11
+ from ...models.context import ArchitecturalPattern
12
+ from ..base import ServiceDependencies
13
+ from .models import ProjectScanRequest, ScanResult
14
+
15
+
16
+ class PatternDetectionEngine:
17
+ """Handles detection of architectural patterns in projects."""
18
+
19
+ def __init__(self):
20
+ """Initialize pattern detection engine."""
21
+ # Architectural pattern indicators
22
+ self.pattern_indicators = {
23
+ "mvc_pattern": ["models.py", "views.py", "templates/"],
24
+ "api_pattern": ["serializers.py", "viewsets.py", "api/"],
25
+ "service_layer": ["services/", "services.py"],
26
+ "repository_pattern": ["repositories/", "repository.py"],
27
+ "factory_pattern": ["factories/", "factory.py"],
28
+ "command_pattern": ["management/commands/", "commands/"],
29
+ "observer_pattern": ["signals.py", "observers/"],
30
+ "middleware_pattern": ["middleware.py", "middleware/"],
31
+ "django_cfg_pattern": ["config.py", "cfg_config.py", "modules/"],
32
+ "rest_api": ["rest_framework", "serializers.py", "viewsets.py"],
33
+ "graphql_api": ["graphene", "schema.py", "graphql/"],
34
+ "celery_tasks": ["tasks.py", "celery.py", "workers/"],
35
+ "testing_pattern": ["tests/", "test_*.py", "conftest.py"],
36
+ "documentation": ["docs/", "README.md", "*.rst"],
37
+ "containerization": ["Dockerfile", "docker-compose.yml", ".dockerignore"],
38
+ "ci_cd": [".github/", ".gitlab-ci.yml", "Jenkinsfile"],
39
+ }
40
+
41
+ async def detect_patterns(
42
+ self,
43
+ request: ProjectScanRequest,
44
+ result: ScanResult,
45
+ dependencies: ServiceDependencies
46
+ ) -> None:
47
+ """Detect architectural patterns in the project."""
48
+ try:
49
+ patterns = []
50
+
51
+ for pattern_name, indicators in self.pattern_indicators.items():
52
+ evidence = []
53
+ files_using_pattern = []
54
+
55
+ for indicator in indicators:
56
+ # Search for pattern indicators
57
+ if indicator.endswith("/"):
58
+ # Directory pattern
59
+ for path in request.project_root.rglob(indicator.rstrip("/")):
60
+ if path.is_dir():
61
+ evidence.append(f"Directory: {path.relative_to(request.project_root)}")
62
+ # Find files in this directory
63
+ for file in path.rglob("*.py"):
64
+ files_using_pattern.append(str(file.relative_to(request.project_root)))
65
+ else:
66
+ # File pattern
67
+ for path in request.project_root.rglob(indicator):
68
+ if path.is_file():
69
+ evidence.append(f"File: {path.relative_to(request.project_root)}")
70
+ files_using_pattern.append(str(path.relative_to(request.project_root)))
71
+
72
+ if evidence:
73
+ # Calculate confidence based on evidence strength
74
+ confidence = min(1.0, len(evidence) / 3.0) # Max confidence with 3+ pieces of evidence
75
+
76
+ pattern = ArchitecturalPattern(
77
+ name=pattern_name,
78
+ description=f"Detected {pattern_name.replace('_', ' ')} pattern",
79
+ confidence=confidence,
80
+ evidence=evidence[:10], # Limit evidence list
81
+ files_using_pattern=files_using_pattern[:20] # Limit file list
82
+ )
83
+ patterns.append(pattern)
84
+
85
+ result.architectural_patterns = patterns
86
+
87
+ except Exception as e:
88
+ dependencies.log_error("Failed to detect patterns", e)
89
+
90
+ def detect_django_version(self, apps: List[Any]) -> str:
91
+ """Detect Django version from project structure."""
92
+ # This is a placeholder - would need actual implementation
93
+ # based on Django features used in the codebase
94
+ return "5.0+" # Default assumption for modern projects
@@ -0,0 +1,28 @@
1
+ """
2
+ Intelligent Questioning Service for Django App Agent Module.
3
+
4
+ This package orchestrates the intelligent questioning process by coordinating
5
+ with specialized AI agents to generate context-aware questions based on
6
+ project analysis and user requirements.
7
+ """
8
+
9
+ from .main import QuestioningService
10
+ from .models import (
11
+ QuestioningRequest, QuestioningResult, QuestioningSession,
12
+ ContextualQuestion, QuestionResponse
13
+ )
14
+ from .question_generator import QuestionGenerator
15
+ from .response_processor import ResponseProcessor
16
+ from .session_manager import SessionManager
17
+
18
+ __all__ = [
19
+ "QuestioningService",
20
+ "QuestioningRequest",
21
+ "QuestioningResult",
22
+ "QuestioningSession",
23
+ "ContextualQuestion",
24
+ "QuestionResponse",
25
+ "QuestionGenerator",
26
+ "ResponseProcessor",
27
+ "SessionManager",
28
+ ]
@@ -0,0 +1,273 @@
1
+ """
2
+ Main Intelligent Questioning Service for Django App Agent Module.
3
+
4
+ This service orchestrates the intelligent questioning process by coordinating
5
+ with specialized AI agents to generate context-aware questions based on
6
+ project analysis and user requirements.
7
+ """
8
+
9
+ from typing import List, Dict, Any, Optional
10
+ from pathlib import Path
11
+
12
+ from pydantic import BaseModel, Field
13
+
14
+ from ...core.config import AgentConfig
15
+ from ...models.context import ProjectContext
16
+ from ..base import BaseService, ServiceDependencies
17
+ from ..context_builder import ContextBuilderService, ContextBuildRequest
18
+ from .models import QuestioningRequest, QuestioningResult, QuestioningSession, ContextualQuestion
19
+ from .question_generator import QuestionGenerator
20
+ from .response_processor import ResponseProcessor
21
+ from .session_manager import SessionManager
22
+
23
+
24
+ class QuestioningService(BaseService[QuestioningRequest, QuestioningResult]):
25
+ """
26
+ Intelligent questioning service for context-aware requirement gathering.
27
+
28
+ This service:
29
+ 1. Analyzes project context and user intent
30
+ 2. Generates targeted questions using AI agents
31
+ 3. Manages interactive questioning sessions
32
+ 4. Processes responses to refine generation requests
33
+ 5. Provides insights and recommendations
34
+ """
35
+
36
+ def __init__(self, config: AgentConfig):
37
+ """Initialize questioning service."""
38
+ super().__init__("questioning", config)
39
+ self.config = config
40
+
41
+ # Initialize components
42
+ self.context_builder = ContextBuilderService(config)
43
+ self.question_generator = QuestionGenerator(config=config)
44
+ self.response_processor = ResponseProcessor(config=config)
45
+ self.session_manager = SessionManager(config=config)
46
+
47
+ async def process(
48
+ self,
49
+ request: QuestioningRequest,
50
+ dependencies: ServiceDependencies
51
+ ) -> QuestioningResult:
52
+ """
53
+ Process intelligent questioning request.
54
+
55
+ Args:
56
+ request: Questioning request with user intent and project info
57
+ dependencies: Service dependencies
58
+
59
+ Returns:
60
+ QuestioningResult with session and refined request
61
+ """
62
+ dependencies.log_operation(
63
+ "Starting intelligent questioning process",
64
+ user_intent=request.user_intent,
65
+ project_root=str(request.project_root),
66
+ max_questions=request.max_questions
67
+ )
68
+
69
+ try:
70
+ # 1. Build comprehensive project context
71
+ project_context = await self._build_project_context(request, dependencies)
72
+
73
+ # 2. Generate context-aware questions using AI agents
74
+ questions = await self.question_generator.generate_questions(
75
+ request, project_context, dependencies
76
+ )
77
+
78
+ # 3. Create questioning session
79
+ session = await self.session_manager.create_session(
80
+ request, questions, project_context, dependencies
81
+ )
82
+
83
+ # 4. For this implementation, we'll simulate the questioning process
84
+ # In a real implementation, this would be interactive
85
+ simulated_session = await self._simulate_questioning_process(
86
+ session, dependencies
87
+ )
88
+
89
+ # 5. Process responses and build refined request
90
+ refined_request = await self.response_processor.process_responses(
91
+ simulated_session, dependencies
92
+ )
93
+
94
+ # 6. Gather AI insights
95
+ insights = await self.session_manager.gather_agent_insights(
96
+ simulated_session, dependencies
97
+ )
98
+
99
+ # 7. Calculate confidence score
100
+ confidence_score = self.session_manager.calculate_confidence_score(simulated_session)
101
+
102
+ # 8. Generate recommendations
103
+ recommendations = self._generate_recommendations(simulated_session, insights)
104
+
105
+ result = QuestioningResult(
106
+ session=simulated_session,
107
+ refined_request=refined_request,
108
+ confidence_score=confidence_score,
109
+ insights=insights,
110
+ recommendations=recommendations
111
+ )
112
+
113
+ dependencies.log_operation(
114
+ "Questioning process completed",
115
+ session_id=simulated_session.session_id,
116
+ confidence_score=confidence_score,
117
+ refined_app_name=refined_request.app_name,
118
+ features_count=len(refined_request.features)
119
+ )
120
+
121
+ return result
122
+
123
+ except Exception as e:
124
+ dependencies.log_error("Questioning process failed", e)
125
+ raise
126
+
127
+ async def _build_project_context(
128
+ self,
129
+ request: QuestioningRequest,
130
+ dependencies: ServiceDependencies
131
+ ) -> ProjectContext:
132
+ """Build comprehensive project context for question generation."""
133
+ dependencies.log_operation("Building project context for questioning")
134
+
135
+ # Create context build request
136
+ context_request = ContextBuildRequest(
137
+ project_root=request.project_root,
138
+ target_app_name=None, # We don't have an app name yet
139
+ generation_request=request.generation_request,
140
+ include_code_samples=True,
141
+ max_context_size=30000, # Smaller context for questioning
142
+ focus_areas=request.focus_areas
143
+ )
144
+
145
+ # Build context using context builder service
146
+ context_result = await self.context_builder.process(context_request, dependencies)
147
+
148
+ return context_result.project_context
149
+
150
+ async def _simulate_questioning_process(
151
+ self,
152
+ session: QuestioningSession,
153
+ dependencies: ServiceDependencies
154
+ ) -> QuestioningSession:
155
+ """
156
+ Simulate the questioning process for demonstration.
157
+
158
+ In a real implementation, this would be replaced by actual
159
+ user interaction through the UI.
160
+ """
161
+ dependencies.log_operation(
162
+ "Simulating questioning process",
163
+ session_id=session.session_id,
164
+ questions_count=len(session.questions)
165
+ )
166
+
167
+ # Simulate responses based on question types and user intent
168
+ for question in session.questions[:min(5, len(session.questions))]: # Limit to 5 questions for demo
169
+ simulated_answer = self._generate_simulated_answer(question, session.user_intent)
170
+ confidence = self._calculate_simulated_confidence(question, simulated_answer)
171
+
172
+ # Add response to session
173
+ await self.session_manager.add_response(
174
+ session.session_id,
175
+ question.id,
176
+ simulated_answer,
177
+ confidence,
178
+ dependencies
179
+ )
180
+
181
+ # Mark session as completed
182
+ await self.session_manager.complete_session(session.session_id, dependencies)
183
+
184
+ return session
185
+
186
+ def _generate_simulated_answer(
187
+ self,
188
+ question: ContextualQuestion,
189
+ user_intent: str
190
+ ) -> str:
191
+ """Generate simulated answer based on question and user intent."""
192
+ intent_lower = user_intent.lower()
193
+ question_lower = question.text.lower()
194
+
195
+ # Generate contextual answers based on question type
196
+ if question.question_type == "yes_no":
197
+ # Determine yes/no based on question content and user intent
198
+ if any(word in question_lower for word in ["auth", "login", "user"]):
199
+ return "yes" if any(word in intent_lower for word in ["user", "auth", "login"]) else "no"
200
+ elif any(word in question_lower for word in ["api", "integration"]):
201
+ return "yes" if any(word in intent_lower for word in ["api", "integration", "external"]) else "no"
202
+ elif any(word in question_lower for word in ["admin", "management"]):
203
+ return "yes" if any(word in intent_lower for word in ["admin", "manage", "dashboard"]) else "no"
204
+ else:
205
+ return "yes" # Default to yes for other questions
206
+
207
+ elif question.question_type == "choice" and question.options:
208
+ # Select most relevant option based on user intent
209
+ for option in question.options:
210
+ if any(word in option.lower() for word in intent_lower.split()):
211
+ return option
212
+ return question.options[0] # Default to first option
213
+
214
+ else: # text question
215
+ # Generate contextual text response
216
+ if "purpose" in question_lower:
217
+ return f"Application for {user_intent}"
218
+ elif "data" in question_lower:
219
+ return "Business data and user information"
220
+ elif "users" in question_lower:
221
+ return "Small to medium team (10-50 users)"
222
+ else:
223
+ return f"Based on the requirement: {user_intent}"
224
+
225
+ def _calculate_simulated_confidence(
226
+ self,
227
+ question: ContextualQuestion,
228
+ answer: str
229
+ ) -> float:
230
+ """Calculate simulated confidence score."""
231
+ # Higher confidence for specific answers, lower for generic ones
232
+ if question.question_type == "yes_no":
233
+ return 0.9
234
+ elif question.question_type == "choice":
235
+ return 0.8
236
+ elif len(answer) > 20: # Detailed text answer
237
+ return 0.7
238
+ else:
239
+ return 0.6
240
+
241
+ def _generate_recommendations(
242
+ self,
243
+ session: QuestioningSession,
244
+ insights: Dict[str, Any]
245
+ ) -> List[str]:
246
+ """Generate development recommendations based on session and insights."""
247
+ recommendations = []
248
+
249
+ # Add recommendations from insights
250
+ if "recommendations" in insights:
251
+ recommendations.extend(insights["recommendations"])
252
+
253
+ # Add confidence-based recommendations
254
+ confidence_score = self.session_manager.calculate_confidence_score(session)
255
+
256
+ if confidence_score > 0.8:
257
+ recommendations.append("High confidence in requirements - proceed with development")
258
+ elif confidence_score > 0.6:
259
+ recommendations.append("Moderate confidence - consider prototype or MVP approach")
260
+ else:
261
+ recommendations.append("Low confidence - additional requirement gathering recommended")
262
+
263
+ # Add architectural recommendations based on patterns
264
+ if insights.get("pattern_detection", {}).get("api_focused"):
265
+ recommendations.append("Consider API-first architecture with comprehensive serializers")
266
+
267
+ if insights.get("pattern_detection", {}).get("user_centric"):
268
+ recommendations.append("Implement robust authentication and user management features")
269
+
270
+ if insights.get("pattern_detection", {}).get("data_intensive"):
271
+ recommendations.append("Focus on efficient data models and database optimization")
272
+
273
+ return recommendations[:5] # Limit to top 5 recommendations
@@ -0,0 +1,111 @@
1
+ """
2
+ Data Models for Intelligent Questioning Service.
3
+
4
+ This module defines the data structures used by the questioning service
5
+ for managing context-aware question generation and user interactions.
6
+ """
7
+
8
+ from typing import List, Dict, Any, Optional
9
+ from pathlib import Path
10
+ from datetime import datetime, timezone
11
+
12
+ from pydantic import BaseModel, Field, ConfigDict
13
+
14
+ from ...models.requests import AppGenerationRequest
15
+ from ...models.context import ProjectContext
16
+
17
+
18
+ class QuestioningRequest(BaseModel):
19
+ """Request for intelligent questioning session."""
20
+
21
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
22
+
23
+ user_intent: str = Field(description="User's stated intent or requirement")
24
+ project_root: Path = Field(description="Root directory of the project")
25
+ generation_request: Optional[AppGenerationRequest] = Field(default=None, description="Initial generation request")
26
+ max_questions: int = Field(default=20, ge=1, le=30, description="Maximum number of questions to ask")
27
+ focus_areas: List[str] = Field(default_factory=list, description="Areas to focus questioning on")
28
+
29
+
30
+ class ContextualQuestion(BaseModel):
31
+ """Represents a context-aware question generated by AI agents."""
32
+
33
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
34
+
35
+ id: str = Field(description="Unique question identifier")
36
+ text: str = Field(description="The question text")
37
+ question_type: str = Field(description="Type of question (yes_no, choice, text, etc.)")
38
+ priority: int = Field(ge=1, le=10, description="Question priority (1=highest, 10=lowest)")
39
+ impact_level: str = Field(description="Impact level (low, medium, high, critical)")
40
+
41
+ # Context information
42
+ context_evidence: List[str] = Field(default_factory=list, description="Evidence from project analysis")
43
+ architectural_implications: List[str] = Field(default_factory=list, description="Architectural implications")
44
+
45
+ # Question options (for choice questions)
46
+ options: Optional[List[str]] = Field(default=None, description="Available options for choice questions")
47
+ default_value: Optional[str] = Field(default=None, description="Default/suggested value")
48
+
49
+ # Metadata
50
+ generated_by: str = Field(description="AI agent that generated this question")
51
+ generation_reasoning: str = Field(description="Reasoning behind question generation")
52
+
53
+
54
+ class QuestionResponse(BaseModel):
55
+ """User's response to a contextual question."""
56
+
57
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
58
+
59
+ question_id: str = Field(description="ID of the question being answered")
60
+ answer: str = Field(description="User's answer")
61
+ confidence: float = Field(ge=0.0, le=1.0, description="User's confidence in their answer")
62
+ timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
63
+
64
+
65
+ class QuestioningSession(BaseModel):
66
+ """Represents an active questioning session."""
67
+
68
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
69
+
70
+ session_id: str = Field(description="Unique session identifier")
71
+ questions: List[ContextualQuestion] = Field(description="Generated questions")
72
+ responses: List[QuestionResponse] = Field(default_factory=list, description="User responses")
73
+ project_context: ProjectContext = Field(description="Project analysis context")
74
+
75
+ # Session metadata
76
+ created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
77
+ completed_at: Optional[datetime] = Field(default=None)
78
+ user_intent: str = Field(description="Original user intent")
79
+
80
+ # Progress tracking
81
+ current_question_index: int = Field(default=0, description="Index of current question")
82
+ is_completed: bool = Field(default=False, description="Whether session is completed")
83
+
84
+ @property
85
+ def completion_percentage(self) -> float:
86
+ """Calculate completion percentage."""
87
+ if not self.questions:
88
+ return 0.0
89
+ return len(self.responses) / len(self.questions) * 100
90
+
91
+ @property
92
+ def answered_questions(self) -> int:
93
+ """Count of answered questions."""
94
+ return len(self.responses)
95
+
96
+ @property
97
+ def remaining_questions(self) -> int:
98
+ """Count of remaining questions."""
99
+ return len(self.questions) - len(self.responses)
100
+
101
+
102
+ class QuestioningResult(BaseModel):
103
+ """Result of intelligent questioning process."""
104
+
105
+ model_config = ConfigDict(extra='forbid', validate_assignment=True)
106
+
107
+ session: QuestioningSession = Field(description="Completed questioning session")
108
+ refined_request: AppGenerationRequest = Field(description="Refined generation request based on answers")
109
+ confidence_score: float = Field(ge=0.0, le=1.0, description="Confidence in the refined request")
110
+ insights: Dict[str, Any] = Field(default_factory=dict, description="AI-generated insights from responses")
111
+ recommendations: List[str] = Field(default_factory=list, description="Development recommendations")