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.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/payments/admin/networks_admin.py +12 -1
- django_cfg/apps/payments/admin/payments_admin.py +13 -0
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
- django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
- django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
- django_cfg/apps/payments/config/__init__.py +14 -15
- django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
- django_cfg/apps/payments/config/helpers.py +8 -13
- django_cfg/apps/payments/migrations/0001_initial.py +33 -46
- django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
- django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
- django_cfg/apps/payments/models/payments.py +94 -0
- django_cfg/apps/payments/services/core/base.py +4 -4
- django_cfg/apps/payments/services/core/payment_service.py +265 -38
- django_cfg/apps/payments/services/providers/base.py +209 -3
- django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
- django_cfg/apps/payments/services/providers/models/base.py +25 -2
- django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
- django_cfg/apps/payments/services/providers/registry.py +5 -5
- django_cfg/apps/payments/services/types/requests.py +19 -7
- django_cfg/apps/payments/signals/payment_signals.py +31 -2
- django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
- django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
- django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
- django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
- django_cfg/apps/payments/urls.py +3 -2
- django_cfg/apps/payments/views/api/currencies.py +3 -0
- django_cfg/apps/payments/views/serializers/currencies.py +18 -5
- django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
- django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
- django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
- django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
- django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
- django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
- django_cfg/apps/tasks/tasks/__init__.py +10 -0
- django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
- django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
- django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
- django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
- django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
- django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
- django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
- django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
- django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
- django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
- django_cfg/apps/tasks/urls.py +2 -2
- django_cfg/apps/tasks/urls_admin.py +2 -2
- django_cfg/apps/tasks/utils/__init__.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +356 -0
- django_cfg/apps/tasks/views/__init__.py +16 -0
- django_cfg/apps/tasks/views/api.py +569 -0
- django_cfg/apps/tasks/views/dashboard.py +58 -0
- django_cfg/core/integration/__init__.py +21 -0
- django_cfg/management/commands/rundramatiq_simulator.py +430 -0
- django_cfg/models/constance.py +0 -11
- django_cfg/models/payments.py +137 -3
- django_cfg/modules/django_tasks.py +54 -21
- django_cfg/registry/core.py +4 -9
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -2
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/RECORD +84 -152
- django_cfg/apps/payments/config/constance/__init__.py +0 -22
- django_cfg/apps/payments/config/constance/config_service.py +0 -123
- django_cfg/apps/payments/config/constance/fields.py +0 -69
- django_cfg/apps/payments/config/constance/settings.py +0 -160
- django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
- django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
- django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
- django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
- django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
- django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
- django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
- django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
- django_cfg/apps/tasks/templates/tasks/base.html +0 -96
- django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
- django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
- django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
- django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
- django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
- django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
- django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
- django_cfg/apps/tasks/views.py +0 -461
- django_cfg/management/commands/app_agent_diagnose.py +0 -470
- django_cfg/management/commands/app_agent_generate.py +0 -342
- django_cfg/management/commands/app_agent_info.py +0 -308
- django_cfg/management/commands/auto_generate.py +0 -486
- django_cfg/modules/django_app_agent/__init__.py +0 -87
- django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
- django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
- django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
- django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
- django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
- django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
- django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
- django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
- django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
- django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
- django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
- django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
- django_cfg/modules/django_app_agent/core/__init__.py +0 -33
- django_cfg/modules/django_app_agent/core/config.py +0 -300
- django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
- django_cfg/modules/django_app_agent/models/__init__.py +0 -71
- django_cfg/modules/django_app_agent/models/base.py +0 -283
- django_cfg/modules/django_app_agent/models/context.py +0 -496
- django_cfg/modules/django_app_agent/models/enums.py +0 -481
- django_cfg/modules/django_app_agent/models/requests.py +0 -500
- django_cfg/modules/django_app_agent/models/responses.py +0 -585
- django_cfg/modules/django_app_agent/pytest.ini +0 -6
- django_cfg/modules/django_app_agent/services/__init__.py +0 -42
- django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
- django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
- django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
- django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
- django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
- django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
- django_cfg/modules/django_app_agent/services/base.py +0 -437
- django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
- django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
- django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
- django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
- django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
- django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
- django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
- django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
- django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
- django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
- django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
- django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
- django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
- django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
- django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
- django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
- django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
- django_cfg/modules/django_app_agent/services/report_service.py +0 -332
- django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
- django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
- django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
- django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
- django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
- django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
- django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
- django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
- django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
- django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
- django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
- django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
- django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
- django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
- django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
- django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
- django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
- django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
- django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
- django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
- django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
- django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
- django_cfg/modules/django_app_agent/ui/cli.py +0 -419
- django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
- django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
- django_cfg/modules/django_app_agent/utils/logging.py +0 -360
- django_cfg/modules/django_app_agent/utils/validation.py +0 -417
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,141 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Code Extraction Module for Context Builder.
|
3
|
-
|
4
|
-
This module handles extraction of relevant code samples
|
5
|
-
and examples from existing project files.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import Dict, Optional
|
9
|
-
from pathlib import Path
|
10
|
-
|
11
|
-
from ..base import ServiceDependencies
|
12
|
-
from .models import ContextBuildRequest, ContextResult
|
13
|
-
|
14
|
-
|
15
|
-
class CodeExtractor:
|
16
|
-
"""Handles extraction of code samples for context building."""
|
17
|
-
|
18
|
-
def __init__(self):
|
19
|
-
"""Initialize code extractor."""
|
20
|
-
# Map features to their corresponding files
|
21
|
-
self.feature_files = {
|
22
|
-
"models": "models.py",
|
23
|
-
"views": "views.py",
|
24
|
-
"urls": "urls.py",
|
25
|
-
"admin": "admin.py",
|
26
|
-
"forms": "forms.py",
|
27
|
-
"tests": "tests.py",
|
28
|
-
"serializers": "serializers.py",
|
29
|
-
"viewsets": "viewsets.py",
|
30
|
-
"filters": "filters.py",
|
31
|
-
"pagination": "pagination.py",
|
32
|
-
"tasks": "tasks.py",
|
33
|
-
"signals": "signals.py",
|
34
|
-
"middleware": "middleware.py"
|
35
|
-
}
|
36
|
-
|
37
|
-
async def extract_code_samples(
|
38
|
-
self,
|
39
|
-
request: ContextBuildRequest,
|
40
|
-
result: ContextResult,
|
41
|
-
dependencies: ServiceDependencies
|
42
|
-
) -> None:
|
43
|
-
"""Extract relevant code samples for context."""
|
44
|
-
if not request.generation_request:
|
45
|
-
return
|
46
|
-
|
47
|
-
samples = {}
|
48
|
-
|
49
|
-
# Extract samples for each requested feature
|
50
|
-
for feature in request.generation_request.features:
|
51
|
-
feature_samples = await self._extract_feature_samples(
|
52
|
-
feature.value, request, result, dependencies
|
53
|
-
)
|
54
|
-
if feature_samples:
|
55
|
-
samples[feature.value] = feature_samples
|
56
|
-
|
57
|
-
result.code_samples = samples
|
58
|
-
|
59
|
-
async def _extract_feature_samples(
|
60
|
-
self,
|
61
|
-
feature: str,
|
62
|
-
request: ContextBuildRequest,
|
63
|
-
result: ContextResult,
|
64
|
-
dependencies: ServiceDependencies
|
65
|
-
) -> Optional[str]:
|
66
|
-
"""Extract code samples for a specific feature."""
|
67
|
-
# Find the best example of this feature in existing apps
|
68
|
-
best_sample = None
|
69
|
-
max_complexity = 0
|
70
|
-
|
71
|
-
for app in result.project_context.apps:
|
72
|
-
app_path = Path(app.path)
|
73
|
-
|
74
|
-
filename = self.feature_files.get(feature)
|
75
|
-
if not filename:
|
76
|
-
continue
|
77
|
-
|
78
|
-
file_path = app_path / filename
|
79
|
-
if not file_path.exists():
|
80
|
-
continue
|
81
|
-
|
82
|
-
try:
|
83
|
-
content = file_path.read_text()
|
84
|
-
|
85
|
-
# Simple complexity measure (lines of meaningful code)
|
86
|
-
lines = [line.strip() for line in content.split('\n')]
|
87
|
-
meaningful_lines = [line for line in lines if line and not line.startswith('#')]
|
88
|
-
complexity = len(meaningful_lines)
|
89
|
-
|
90
|
-
if complexity > max_complexity:
|
91
|
-
max_complexity = complexity
|
92
|
-
# Truncate sample if too long
|
93
|
-
if len(content) > 2000:
|
94
|
-
content = content[:2000] + "\n# ... (truncated)"
|
95
|
-
best_sample = content
|
96
|
-
|
97
|
-
except Exception:
|
98
|
-
continue
|
99
|
-
|
100
|
-
return best_sample
|
101
|
-
|
102
|
-
def extract_specific_patterns(
|
103
|
-
self,
|
104
|
-
project_root: Path,
|
105
|
-
pattern_type: str,
|
106
|
-
max_samples: int = 3
|
107
|
-
) -> Dict[str, str]:
|
108
|
-
"""Extract specific code patterns from the project."""
|
109
|
-
samples = {}
|
110
|
-
|
111
|
-
pattern_searches = {
|
112
|
-
"model_definitions": ["models.py"],
|
113
|
-
"view_classes": ["views.py"],
|
114
|
-
"url_patterns": ["urls.py"],
|
115
|
-
"admin_configs": ["admin.py"],
|
116
|
-
"serializer_classes": ["serializers.py"],
|
117
|
-
"test_cases": ["tests.py", "test_*.py"]
|
118
|
-
}
|
119
|
-
|
120
|
-
search_files = pattern_searches.get(pattern_type, [])
|
121
|
-
|
122
|
-
for search_pattern in search_files:
|
123
|
-
for file_path in project_root.rglob(search_pattern):
|
124
|
-
if file_path.is_file():
|
125
|
-
try:
|
126
|
-
content = file_path.read_text()
|
127
|
-
relative_path = file_path.relative_to(project_root)
|
128
|
-
|
129
|
-
# Truncate if too long
|
130
|
-
if len(content) > 1500:
|
131
|
-
content = content[:1500] + "\n# ... (truncated)"
|
132
|
-
|
133
|
-
samples[str(relative_path)] = content
|
134
|
-
|
135
|
-
# Limit number of samples
|
136
|
-
if len(samples) >= max_samples:
|
137
|
-
break
|
138
|
-
except Exception:
|
139
|
-
continue
|
140
|
-
|
141
|
-
return samples
|
@@ -1,276 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Context Generation Module for Context Builder.
|
3
|
-
|
4
|
-
This module handles generation of specific context for different
|
5
|
-
Django features and components.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import List, Dict, Any
|
9
|
-
from pathlib import Path
|
10
|
-
import re
|
11
|
-
|
12
|
-
from ..base import ServiceDependencies
|
13
|
-
from .models import ContextBuildRequest, ContextResult
|
14
|
-
|
15
|
-
|
16
|
-
class ContextGenerator:
|
17
|
-
"""Handles generation of feature-specific context."""
|
18
|
-
|
19
|
-
def __init__(self):
|
20
|
-
"""Initialize context generator."""
|
21
|
-
# Map features to their context building strategies
|
22
|
-
self.context_strategies = {
|
23
|
-
"models": self._build_models_context,
|
24
|
-
"views": self._build_views_context,
|
25
|
-
"urls": self._build_urls_context,
|
26
|
-
"admin": self._build_admin_context,
|
27
|
-
"api": self._build_api_context,
|
28
|
-
"tests": self._build_tests_context,
|
29
|
-
"serializers": self._build_api_context,
|
30
|
-
"viewsets": self._build_api_context,
|
31
|
-
"forms": self._build_forms_context
|
32
|
-
}
|
33
|
-
|
34
|
-
async def build_generation_context(
|
35
|
-
self,
|
36
|
-
request: ContextBuildRequest,
|
37
|
-
result: ContextResult,
|
38
|
-
dependencies: ServiceDependencies
|
39
|
-
) -> None:
|
40
|
-
"""Build context specific to the generation request."""
|
41
|
-
gen_request = request.generation_request
|
42
|
-
if not gen_request:
|
43
|
-
return
|
44
|
-
|
45
|
-
# Build context for each requested feature
|
46
|
-
for feature in gen_request.features:
|
47
|
-
feature_name = feature.value
|
48
|
-
|
49
|
-
if feature_name in self.context_strategies:
|
50
|
-
strategy = self.context_strategies[feature_name]
|
51
|
-
await strategy(request, result, dependencies)
|
52
|
-
|
53
|
-
async def _build_models_context(
|
54
|
-
self,
|
55
|
-
request: ContextBuildRequest,
|
56
|
-
result: ContextResult,
|
57
|
-
dependencies: ServiceDependencies
|
58
|
-
) -> None:
|
59
|
-
"""Build context for models generation."""
|
60
|
-
# Find existing models in the project
|
61
|
-
existing_models = []
|
62
|
-
|
63
|
-
for app in result.project_context.apps:
|
64
|
-
if app.models_count > 0:
|
65
|
-
app_path = Path(app.path)
|
66
|
-
models_file = app_path / "models.py"
|
67
|
-
|
68
|
-
if models_file.exists():
|
69
|
-
try:
|
70
|
-
content = models_file.read_text()
|
71
|
-
# Extract model class names
|
72
|
-
model_classes = re.findall(r'class\s+(\w+)\s*\([^)]*Model[^)]*\):', content)
|
73
|
-
existing_models.extend([(app.name, model) for model in model_classes])
|
74
|
-
except Exception:
|
75
|
-
pass
|
76
|
-
|
77
|
-
# Add to context summary
|
78
|
-
result.context_summary["existing_models"] = existing_models
|
79
|
-
result.context_summary["model_patterns"] = [
|
80
|
-
p for p in result.relevant_patterns
|
81
|
-
if "model" in p.name.lower() or "data" in p.name.lower()
|
82
|
-
]
|
83
|
-
|
84
|
-
async def _build_views_context(
|
85
|
-
self,
|
86
|
-
request: ContextBuildRequest,
|
87
|
-
result: ContextResult,
|
88
|
-
dependencies: ServiceDependencies
|
89
|
-
) -> None:
|
90
|
-
"""Build context for views generation."""
|
91
|
-
# Find existing view patterns
|
92
|
-
view_patterns = []
|
93
|
-
|
94
|
-
for app in result.project_context.apps:
|
95
|
-
if app.views_count > 0:
|
96
|
-
app_path = Path(app.path)
|
97
|
-
views_file = app_path / "views.py"
|
98
|
-
|
99
|
-
if views_file.exists():
|
100
|
-
try:
|
101
|
-
content = views_file.read_text()
|
102
|
-
|
103
|
-
# Detect view types
|
104
|
-
if "class" in content and "View" in content:
|
105
|
-
view_patterns.append("class_based_views")
|
106
|
-
if "def " in content and "request" in content:
|
107
|
-
view_patterns.append("function_based_views")
|
108
|
-
if "async def" in content:
|
109
|
-
view_patterns.append("async_views")
|
110
|
-
|
111
|
-
except Exception:
|
112
|
-
pass
|
113
|
-
|
114
|
-
result.context_summary["view_patterns"] = list(set(view_patterns))
|
115
|
-
|
116
|
-
async def _build_urls_context(
|
117
|
-
self,
|
118
|
-
request: ContextBuildRequest,
|
119
|
-
result: ContextResult,
|
120
|
-
dependencies: ServiceDependencies
|
121
|
-
) -> None:
|
122
|
-
"""Build context for URLs generation."""
|
123
|
-
# Analyze URL patterns in existing apps
|
124
|
-
url_patterns = []
|
125
|
-
|
126
|
-
for app in result.project_context.apps:
|
127
|
-
app_path = Path(app.path)
|
128
|
-
urls_file = app_path / "urls.py"
|
129
|
-
|
130
|
-
if urls_file.exists():
|
131
|
-
try:
|
132
|
-
content = urls_file.read_text()
|
133
|
-
|
134
|
-
# Detect URL pattern styles
|
135
|
-
if "path(" in content:
|
136
|
-
url_patterns.append("django_path")
|
137
|
-
if "re_path(" in content:
|
138
|
-
url_patterns.append("regex_path")
|
139
|
-
if "include(" in content:
|
140
|
-
url_patterns.append("url_include")
|
141
|
-
|
142
|
-
except Exception:
|
143
|
-
pass
|
144
|
-
|
145
|
-
result.context_summary["url_patterns"] = list(set(url_patterns))
|
146
|
-
|
147
|
-
async def _build_admin_context(
|
148
|
-
self,
|
149
|
-
request: ContextBuildRequest,
|
150
|
-
result: ContextResult,
|
151
|
-
dependencies: ServiceDependencies
|
152
|
-
) -> None:
|
153
|
-
"""Build context for admin generation."""
|
154
|
-
# Find admin registration patterns
|
155
|
-
admin_patterns = []
|
156
|
-
|
157
|
-
for app in result.project_context.apps:
|
158
|
-
if app.admin_registered_models > 0:
|
159
|
-
app_path = Path(app.path)
|
160
|
-
admin_file = app_path / "admin.py"
|
161
|
-
|
162
|
-
if admin_file.exists():
|
163
|
-
try:
|
164
|
-
content = admin_file.read_text()
|
165
|
-
|
166
|
-
# Detect admin patterns
|
167
|
-
if "@admin.register" in content:
|
168
|
-
admin_patterns.append("decorator_registration")
|
169
|
-
if "admin.site.register" in content:
|
170
|
-
admin_patterns.append("function_registration")
|
171
|
-
if "ModelAdmin" in content:
|
172
|
-
admin_patterns.append("custom_admin_classes")
|
173
|
-
|
174
|
-
except Exception:
|
175
|
-
pass
|
176
|
-
|
177
|
-
result.context_summary["admin_patterns"] = list(set(admin_patterns))
|
178
|
-
|
179
|
-
async def _build_api_context(
|
180
|
-
self,
|
181
|
-
request: ContextBuildRequest,
|
182
|
-
result: ContextResult,
|
183
|
-
dependencies: ServiceDependencies
|
184
|
-
) -> None:
|
185
|
-
"""Build context for API generation."""
|
186
|
-
# Find API patterns
|
187
|
-
api_patterns = []
|
188
|
-
|
189
|
-
for app in result.project_context.apps:
|
190
|
-
app_path = Path(app.path)
|
191
|
-
|
192
|
-
# Check for DRF patterns
|
193
|
-
for api_file in ["serializers.py", "viewsets.py", "views.py"]:
|
194
|
-
file_path = app_path / api_file
|
195
|
-
if file_path.exists():
|
196
|
-
try:
|
197
|
-
content = file_path.read_text()
|
198
|
-
|
199
|
-
if "rest_framework" in content:
|
200
|
-
api_patterns.append("django_rest_framework")
|
201
|
-
if "Serializer" in content:
|
202
|
-
api_patterns.append("serializers")
|
203
|
-
if "ViewSet" in content:
|
204
|
-
api_patterns.append("viewsets")
|
205
|
-
if "APIView" in content:
|
206
|
-
api_patterns.append("api_views")
|
207
|
-
|
208
|
-
except Exception:
|
209
|
-
pass
|
210
|
-
|
211
|
-
result.context_summary["api_patterns"] = list(set(api_patterns))
|
212
|
-
|
213
|
-
async def _build_tests_context(
|
214
|
-
self,
|
215
|
-
request: ContextBuildRequest,
|
216
|
-
result: ContextResult,
|
217
|
-
dependencies: ServiceDependencies
|
218
|
-
) -> None:
|
219
|
-
"""Build context for tests generation."""
|
220
|
-
# Find testing patterns
|
221
|
-
test_patterns = []
|
222
|
-
|
223
|
-
for app in result.project_context.apps:
|
224
|
-
app_path = Path(app.path)
|
225
|
-
|
226
|
-
# Check for test files
|
227
|
-
test_files = list(app_path.glob("test*.py")) + [app_path / "tests.py"]
|
228
|
-
|
229
|
-
for test_file in test_files:
|
230
|
-
if test_file.exists():
|
231
|
-
try:
|
232
|
-
content = test_file.read_text()
|
233
|
-
|
234
|
-
if "TestCase" in content:
|
235
|
-
test_patterns.append("django_testcase")
|
236
|
-
if "pytest" in content or "def test_" in content:
|
237
|
-
test_patterns.append("pytest")
|
238
|
-
if "Client" in content:
|
239
|
-
test_patterns.append("test_client")
|
240
|
-
if "factory" in content.lower():
|
241
|
-
test_patterns.append("factory_boy")
|
242
|
-
|
243
|
-
except Exception:
|
244
|
-
pass
|
245
|
-
|
246
|
-
result.context_summary["test_patterns"] = list(set(test_patterns))
|
247
|
-
|
248
|
-
async def _build_forms_context(
|
249
|
-
self,
|
250
|
-
request: ContextBuildRequest,
|
251
|
-
result: ContextResult,
|
252
|
-
dependencies: ServiceDependencies
|
253
|
-
) -> None:
|
254
|
-
"""Build context for forms generation."""
|
255
|
-
# Find form patterns
|
256
|
-
form_patterns = []
|
257
|
-
|
258
|
-
for app in result.project_context.apps:
|
259
|
-
app_path = Path(app.path)
|
260
|
-
forms_file = app_path / "forms.py"
|
261
|
-
|
262
|
-
if forms_file.exists():
|
263
|
-
try:
|
264
|
-
content = forms_file.read_text()
|
265
|
-
|
266
|
-
if "ModelForm" in content:
|
267
|
-
form_patterns.append("model_forms")
|
268
|
-
if "Form" in content and "ModelForm" not in content:
|
269
|
-
form_patterns.append("regular_forms")
|
270
|
-
if "widgets" in content:
|
271
|
-
form_patterns.append("custom_widgets")
|
272
|
-
|
273
|
-
except Exception:
|
274
|
-
pass
|
275
|
-
|
276
|
-
result.context_summary["form_patterns"] = list(set(form_patterns))
|
@@ -1,272 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Main Context Builder Service for Django App Agent Module.
|
3
|
-
|
4
|
-
This service builds comprehensive development context for AI agents,
|
5
|
-
coordinating project analysis, pattern identification, and context optimization.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import Dict, Any, List
|
9
|
-
|
10
|
-
from ..base import BaseService, ServiceDependencies
|
11
|
-
from ..project_scanner import ProjectScannerService, ProjectScanRequest
|
12
|
-
from ...models.context import ProjectContext
|
13
|
-
from ...core.exceptions import ValidationError
|
14
|
-
|
15
|
-
from .models import ContextBuildRequest, ContextResult
|
16
|
-
from .pattern_analyzer import PatternAnalyzer
|
17
|
-
from .code_extractor import CodeExtractor
|
18
|
-
from .context_generator import ContextGenerator
|
19
|
-
|
20
|
-
|
21
|
-
class ContextBuilderService(BaseService[ContextBuildRequest, ContextResult]):
|
22
|
-
"""
|
23
|
-
Service for building comprehensive development context for AI agents.
|
24
|
-
|
25
|
-
Capabilities:
|
26
|
-
- Project structure analysis and pattern identification
|
27
|
-
- Code sample extraction and context building
|
28
|
-
- Integration point identification
|
29
|
-
- Context optimization for AI consumption
|
30
|
-
"""
|
31
|
-
|
32
|
-
def __init__(self, config):
|
33
|
-
"""Initialize context builder service."""
|
34
|
-
super().__init__("context_builder", config)
|
35
|
-
|
36
|
-
# Initialize sub-components
|
37
|
-
self.pattern_analyzer = PatternAnalyzer()
|
38
|
-
self.code_extractor = CodeExtractor()
|
39
|
-
self.context_generator = ContextGenerator()
|
40
|
-
|
41
|
-
# Initialize project scanner
|
42
|
-
self.project_scanner = ProjectScannerService(config)
|
43
|
-
|
44
|
-
async def process(
|
45
|
-
self,
|
46
|
-
request: ContextBuildRequest,
|
47
|
-
dependencies: ServiceDependencies
|
48
|
-
) -> ContextResult:
|
49
|
-
"""
|
50
|
-
Process context building request.
|
51
|
-
|
52
|
-
Args:
|
53
|
-
request: Context building request
|
54
|
-
dependencies: Service dependencies for logging and operations
|
55
|
-
|
56
|
-
Returns:
|
57
|
-
ContextResult with comprehensive development context
|
58
|
-
"""
|
59
|
-
try:
|
60
|
-
dependencies.log_operation(
|
61
|
-
f"Building development context for '{request.project_root}'",
|
62
|
-
project_root=str(request.project_root),
|
63
|
-
target_app=request.target_app_name
|
64
|
-
)
|
65
|
-
|
66
|
-
# Initialize result
|
67
|
-
result = ContextResult(
|
68
|
-
project_context=ProjectContext(
|
69
|
-
project_root=str(request.project_root),
|
70
|
-
project_name=request.project_root.name,
|
71
|
-
django_version="Unknown",
|
72
|
-
is_django_cfg_project=False,
|
73
|
-
apps=[],
|
74
|
-
architectural_patterns=[],
|
75
|
-
integration_opportunities=[]
|
76
|
-
)
|
77
|
-
)
|
78
|
-
|
79
|
-
# Scan project structure
|
80
|
-
scan_request = ProjectScanRequest(
|
81
|
-
project_root=request.project_root,
|
82
|
-
analyze_dependencies=True,
|
83
|
-
detect_patterns=True
|
84
|
-
)
|
85
|
-
|
86
|
-
scan_result = await self.project_scanner.process(scan_request, dependencies)
|
87
|
-
result.project_context = scan_result.project_context
|
88
|
-
|
89
|
-
# Identify relevant architectural patterns
|
90
|
-
await self.pattern_analyzer.identify_relevant_patterns(
|
91
|
-
request, scan_result, result, dependencies
|
92
|
-
)
|
93
|
-
|
94
|
-
# Build generation-specific context
|
95
|
-
await self.context_generator.build_generation_context(
|
96
|
-
request, result, dependencies
|
97
|
-
)
|
98
|
-
|
99
|
-
# Extract code samples if requested
|
100
|
-
if request.include_code_samples:
|
101
|
-
await self.code_extractor.extract_code_samples(
|
102
|
-
request, result, dependencies
|
103
|
-
)
|
104
|
-
|
105
|
-
# Identify integration points
|
106
|
-
await self._identify_integration_points(request, result, dependencies)
|
107
|
-
|
108
|
-
# Generate recommendations
|
109
|
-
await self._generate_recommendations(request, result, dependencies)
|
110
|
-
|
111
|
-
# Optimize context size if needed
|
112
|
-
await self._optimize_context_size(request, result, dependencies)
|
113
|
-
|
114
|
-
dependencies.log_operation(
|
115
|
-
"Context building completed successfully",
|
116
|
-
patterns_found=len(result.relevant_patterns),
|
117
|
-
code_samples=len(result.code_samples),
|
118
|
-
recommendations=len(result.recommendations)
|
119
|
-
)
|
120
|
-
|
121
|
-
return result
|
122
|
-
|
123
|
-
except Exception as e:
|
124
|
-
raise ValidationError(
|
125
|
-
f"Failed to build development context: {e}",
|
126
|
-
validation_type="context_building"
|
127
|
-
)
|
128
|
-
|
129
|
-
async def _identify_integration_points(
|
130
|
-
self,
|
131
|
-
request: ContextBuildRequest,
|
132
|
-
result: ContextResult,
|
133
|
-
dependencies: ServiceDependencies
|
134
|
-
) -> None:
|
135
|
-
"""Identify potential integration points with existing code."""
|
136
|
-
integration_points = []
|
137
|
-
|
138
|
-
if not request.generation_request:
|
139
|
-
return
|
140
|
-
|
141
|
-
# Check for potential integrations based on requested features
|
142
|
-
for feature in request.generation_request.features:
|
143
|
-
feature_name = feature.value
|
144
|
-
|
145
|
-
if feature_name == "models":
|
146
|
-
# Look for existing models that could be related
|
147
|
-
for app in result.project_context.apps:
|
148
|
-
if app.models_count > 0:
|
149
|
-
integration_points.append({
|
150
|
-
"type": "model_relationships",
|
151
|
-
"app": app.name,
|
152
|
-
"description": f"Consider relationships with models in {app.name}",
|
153
|
-
"confidence": 0.7
|
154
|
-
})
|
155
|
-
|
156
|
-
elif feature_name == "api":
|
157
|
-
# Look for existing API patterns
|
158
|
-
api_apps = [app for app in result.project_context.apps if "api" in app.name.lower()]
|
159
|
-
for app in api_apps:
|
160
|
-
integration_points.append({
|
161
|
-
"type": "api_integration",
|
162
|
-
"app": app.name,
|
163
|
-
"description": f"Consider API consistency with {app.name}",
|
164
|
-
"confidence": 0.8
|
165
|
-
})
|
166
|
-
|
167
|
-
elif feature_name == "admin":
|
168
|
-
# Look for existing admin customizations
|
169
|
-
admin_apps = [app for app in result.project_context.apps if app.admin_registered_models > 0]
|
170
|
-
for app in admin_apps:
|
171
|
-
integration_points.append({
|
172
|
-
"type": "admin_consistency",
|
173
|
-
"app": app.name,
|
174
|
-
"description": f"Follow admin patterns from {app.name}",
|
175
|
-
"confidence": 0.6
|
176
|
-
})
|
177
|
-
|
178
|
-
result.integration_points = integration_points
|
179
|
-
|
180
|
-
async def _generate_recommendations(
|
181
|
-
self,
|
182
|
-
request: ContextBuildRequest,
|
183
|
-
result: ContextResult,
|
184
|
-
dependencies: ServiceDependencies
|
185
|
-
) -> None:
|
186
|
-
"""Generate development recommendations based on context."""
|
187
|
-
recommendations = []
|
188
|
-
|
189
|
-
# Analyze project patterns for recommendations
|
190
|
-
if result.relevant_patterns:
|
191
|
-
high_confidence_patterns = [p for p in result.relevant_patterns if p.confidence >= 0.8]
|
192
|
-
if high_confidence_patterns:
|
193
|
-
pattern_names = [p.name for p in high_confidence_patterns]
|
194
|
-
recommendations.append(
|
195
|
-
f"Follow established patterns: {', '.join(pattern_names)}"
|
196
|
-
)
|
197
|
-
|
198
|
-
# Check for django-cfg specific recommendations
|
199
|
-
if result.project_context.is_django_cfg_project:
|
200
|
-
recommendations.extend([
|
201
|
-
"Use django-cfg configuration patterns for settings",
|
202
|
-
"Leverage django-cfg modules for better organization",
|
203
|
-
"Consider using BaseCfgModule for configuration management"
|
204
|
-
])
|
205
|
-
|
206
|
-
# Feature-specific recommendations
|
207
|
-
if request.generation_request:
|
208
|
-
for feature in request.generation_request.features:
|
209
|
-
feature_name = feature.value
|
210
|
-
|
211
|
-
if feature_name == "models":
|
212
|
-
recommendations.append("Use proper field types and validation")
|
213
|
-
recommendations.append("Add meaningful __str__ methods")
|
214
|
-
recommendations.append("Consider adding Meta class with ordering")
|
215
|
-
|
216
|
-
elif feature_name == "api":
|
217
|
-
recommendations.append("Use DRF serializers for consistent API responses")
|
218
|
-
recommendations.append("Implement proper pagination")
|
219
|
-
recommendations.append("Add API documentation with drf-spectacular")
|
220
|
-
|
221
|
-
elif feature_name == "tests":
|
222
|
-
recommendations.append("Aim for high test coverage")
|
223
|
-
recommendations.append("Use factory_boy for test data generation")
|
224
|
-
recommendations.append("Test both positive and negative scenarios")
|
225
|
-
|
226
|
-
# Context size recommendations
|
227
|
-
context_size = sum(len(str(v)) for v in result.code_samples.values())
|
228
|
-
if context_size > request.max_context_size:
|
229
|
-
recommendations.append("Consider reducing context size for better AI performance")
|
230
|
-
|
231
|
-
result.recommendations = recommendations
|
232
|
-
|
233
|
-
async def _optimize_context_size(
|
234
|
-
self,
|
235
|
-
request: ContextBuildRequest,
|
236
|
-
result: ContextResult,
|
237
|
-
dependencies: ServiceDependencies
|
238
|
-
) -> None:
|
239
|
-
"""Optimize context size to fit within limits."""
|
240
|
-
# Calculate current context size
|
241
|
-
context_size = 0
|
242
|
-
context_size += len(str(result.project_context))
|
243
|
-
context_size += sum(len(str(p)) for p in result.relevant_patterns)
|
244
|
-
context_size += sum(len(sample) for sample in result.code_samples.values())
|
245
|
-
|
246
|
-
if context_size <= request.max_context_size:
|
247
|
-
return
|
248
|
-
|
249
|
-
dependencies.log_operation(
|
250
|
-
f"Optimizing context size from {context_size} to {request.max_context_size}"
|
251
|
-
)
|
252
|
-
|
253
|
-
# Prioritize and truncate content
|
254
|
-
# 1. Keep most relevant patterns (highest confidence)
|
255
|
-
result.relevant_patterns = sorted(
|
256
|
-
result.relevant_patterns,
|
257
|
-
key=lambda p: p.confidence,
|
258
|
-
reverse=True
|
259
|
-
)[:5] # Keep top 5 patterns
|
260
|
-
|
261
|
-
# 2. Truncate code samples
|
262
|
-
max_sample_size = request.max_context_size // (len(result.code_samples) + 1) if result.code_samples else 1000
|
263
|
-
|
264
|
-
for feature, sample in result.code_samples.items():
|
265
|
-
if len(sample) > max_sample_size:
|
266
|
-
result.code_samples[feature] = sample[:max_sample_size] + "\n# ... (truncated for context)"
|
267
|
-
|
268
|
-
# 3. Limit integration points
|
269
|
-
result.integration_points = result.integration_points[:10]
|
270
|
-
|
271
|
-
# 4. Limit recommendations
|
272
|
-
result.recommendations = result.recommendations[:15]
|