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.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/admin/__init__.py +24 -8
- django_cfg/apps/accounts/admin/activity_admin.py +146 -0
- django_cfg/apps/accounts/admin/filters.py +98 -22
- django_cfg/apps/accounts/admin/group_admin.py +86 -0
- django_cfg/apps/accounts/admin/inlines.py +42 -13
- django_cfg/apps/accounts/admin/otp_admin.py +115 -0
- django_cfg/apps/accounts/admin/registration_admin.py +173 -0
- django_cfg/apps/accounts/admin/resources.py +123 -19
- django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
- django_cfg/apps/accounts/admin/user_admin.py +362 -0
- django_cfg/apps/agents/admin/__init__.py +17 -4
- django_cfg/apps/agents/admin/execution_admin.py +204 -183
- django_cfg/apps/agents/admin/registry_admin.py +230 -255
- django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
- django_cfg/apps/agents/core/__init__.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +221 -0
- django_cfg/apps/agents/core/exceptions.py +14 -0
- django_cfg/apps/agents/core/orchestrator.py +18 -3
- django_cfg/apps/knowbase/admin/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
- django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
- django_cfg/apps/knowbase/admin/document_admin.py +269 -262
- django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
- django_cfg/apps/knowbase/config/settings.py +21 -4
- django_cfg/apps/knowbase/views/chat_views.py +3 -0
- django_cfg/apps/leads/admin/__init__.py +3 -1
- django_cfg/apps/leads/admin/leads_admin.py +235 -35
- django_cfg/apps/maintenance/admin/__init__.py +2 -2
- django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
- django_cfg/apps/maintenance/admin/log_admin.py +143 -61
- django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
- django_cfg/apps/maintenance/admin/site_admin.py +213 -352
- django_cfg/apps/newsletter/admin/__init__.py +29 -2
- django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
- django_cfg/apps/payments/admin/__init__.py +18 -27
- django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
- django_cfg/apps/payments/admin/balance_admin.py +166 -632
- django_cfg/apps/payments/admin/currencies_admin.py +235 -607
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
- django_cfg/apps/payments/admin/filters.py +83 -3
- django_cfg/apps/payments/admin/networks_admin.py +258 -0
- django_cfg/apps/payments/admin/payments_admin.py +171 -461
- django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
- django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +105 -34
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +12 -16
- django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +13 -18
- django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
- django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
- django_cfg/apps/payments/middleware/api_access.py +32 -6
- django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +26 -0
- django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +28 -0
- django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +30 -0
- django_cfg/apps/payments/models/balance.py +12 -0
- django_cfg/apps/payments/models/currencies.py +106 -32
- django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
- django_cfg/apps/payments/services/core/currency_service.py +35 -28
- django_cfg/apps/payments/services/core/payment_service.py +1 -1
- django_cfg/apps/payments/services/providers/__init__.py +3 -0
- django_cfg/apps/payments/services/providers/base.py +95 -39
- django_cfg/apps/payments/services/providers/models/__init__.py +40 -0
- django_cfg/apps/payments/services/providers/models/base.py +122 -0
- django_cfg/apps/payments/services/providers/models/providers.py +87 -0
- django_cfg/apps/payments/services/providers/models/universal.py +48 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
- django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
- django_cfg/apps/payments/services/providers/{nowpayments.py → nowpayments/provider.py} +240 -209
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
- django_cfg/apps/payments/services/providers/registry.py +4 -32
- django_cfg/apps/payments/services/providers/sync_service.py +277 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +23 -5
- django_cfg/apps/payments/static/payments/js/payment-form.js +65 -8
- django_cfg/apps/payments/tasks/__init__.py +39 -0
- django_cfg/apps/payments/tasks/types.py +73 -0
- django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
- django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
- django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
- django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
- django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
- django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
- django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
- django_cfg/apps/payments/urls_admin.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +5 -5
- django_cfg/apps/payments/views/overview/services.py +2 -2
- django_cfg/apps/payments/views/serializers/currencies.py +4 -3
- django_cfg/apps/support/admin/__init__.py +10 -1
- django_cfg/apps/support/admin/support_admin.py +338 -141
- django_cfg/apps/tasks/admin/__init__.py +11 -0
- django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
- django_cfg/apps/urls.py +1 -2
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +10 -5
- django_cfg/core/generation.py +1 -1
- django_cfg/management/commands/__init__.py +13 -1
- django_cfg/management/commands/app_agent_diagnose.py +470 -0
- django_cfg/management/commands/app_agent_generate.py +342 -0
- django_cfg/management/commands/app_agent_info.py +308 -0
- django_cfg/management/commands/migrate_all.py +9 -3
- django_cfg/management/commands/migrator.py +11 -6
- django_cfg/management/commands/rundramatiq.py +3 -2
- django_cfg/middleware/__init__.py +0 -2
- django_cfg/models/api_keys.py +115 -0
- django_cfg/modules/django_admin/__init__.py +64 -0
- django_cfg/modules/django_admin/decorators/__init__.py +13 -0
- django_cfg/modules/django_admin/decorators/actions.py +106 -0
- django_cfg/modules/django_admin/decorators/display.py +106 -0
- django_cfg/modules/django_admin/mixins/__init__.py +14 -0
- django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
- django_cfg/modules/django_admin/models/__init__.py +20 -0
- django_cfg/modules/django_admin/models/action_models.py +33 -0
- django_cfg/modules/django_admin/models/badge_models.py +20 -0
- django_cfg/modules/django_admin/models/base.py +26 -0
- django_cfg/modules/django_admin/models/display_models.py +31 -0
- django_cfg/modules/django_admin/utils/badges.py +159 -0
- django_cfg/modules/django_admin/utils/displays.py +247 -0
- django_cfg/modules/django_app_agent/__init__.py +87 -0
- django_cfg/modules/django_app_agent/agents/__init__.py +40 -0
- django_cfg/modules/django_app_agent/agents/base/__init__.py +24 -0
- django_cfg/modules/django_app_agent/agents/base/agent.py +354 -0
- django_cfg/modules/django_app_agent/agents/base/context.py +236 -0
- django_cfg/modules/django_app_agent/agents/base/executor.py +430 -0
- django_cfg/modules/django_app_agent/agents/generation/__init__.py +12 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +15 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +147 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +99 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +32 -0
- django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +290 -0
- django_cfg/modules/django_app_agent/agents/interfaces.py +376 -0
- django_cfg/modules/django_app_agent/core/__init__.py +33 -0
- django_cfg/modules/django_app_agent/core/config.py +300 -0
- django_cfg/modules/django_app_agent/core/exceptions.py +359 -0
- django_cfg/modules/django_app_agent/models/__init__.py +71 -0
- django_cfg/modules/django_app_agent/models/base.py +283 -0
- django_cfg/modules/django_app_agent/models/context.py +496 -0
- django_cfg/modules/django_app_agent/models/enums.py +481 -0
- django_cfg/modules/django_app_agent/models/requests.py +500 -0
- django_cfg/modules/django_app_agent/models/responses.py +585 -0
- django_cfg/modules/django_app_agent/pytest.ini +6 -0
- django_cfg/modules/django_app_agent/services/__init__.py +42 -0
- django_cfg/modules/django_app_agent/services/app_generator/__init__.py +30 -0
- django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +133 -0
- django_cfg/modules/django_app_agent/services/app_generator/context.py +40 -0
- django_cfg/modules/django_app_agent/services/app_generator/main.py +202 -0
- django_cfg/modules/django_app_agent/services/app_generator/structure.py +316 -0
- django_cfg/modules/django_app_agent/services/app_generator/validation.py +125 -0
- django_cfg/modules/django_app_agent/services/base.py +437 -0
- django_cfg/modules/django_app_agent/services/context_builder/__init__.py +34 -0
- django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +141 -0
- django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +276 -0
- django_cfg/modules/django_app_agent/services/context_builder/main.py +272 -0
- django_cfg/modules/django_app_agent/services/context_builder/models.py +40 -0
- django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +85 -0
- django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +31 -0
- django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +311 -0
- django_cfg/modules/django_app_agent/services/project_scanner/main.py +221 -0
- django_cfg/modules/django_app_agent/services/project_scanner/models.py +59 -0
- django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +94 -0
- django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +28 -0
- django_cfg/modules/django_app_agent/services/questioning_service/main.py +273 -0
- django_cfg/modules/django_app_agent/services/questioning_service/models.py +111 -0
- django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +251 -0
- django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +347 -0
- django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +356 -0
- django_cfg/modules/django_app_agent/services/report_service.py +332 -0
- django_cfg/modules/django_app_agent/services/template_manager/__init__.py +18 -0
- django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +236 -0
- django_cfg/modules/django_app_agent/services/template_manager/main.py +159 -0
- django_cfg/modules/django_app_agent/services/template_manager/models.py +36 -0
- django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +100 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +105 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +31 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +44 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +81 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +107 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +139 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +91 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +195 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +35 -0
- django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +211 -0
- django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +200 -0
- django_cfg/modules/django_app_agent/services/validation_service/__init__.py +25 -0
- django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +333 -0
- django_cfg/modules/django_app_agent/services/validation_service/main.py +242 -0
- django_cfg/modules/django_app_agent/services/validation_service/models.py +66 -0
- django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +352 -0
- django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +272 -0
- django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +203 -0
- django_cfg/modules/django_app_agent/ui/__init__.py +25 -0
- django_cfg/modules/django_app_agent/ui/cli.py +419 -0
- django_cfg/modules/django_app_agent/ui/rich_components.py +622 -0
- django_cfg/modules/django_app_agent/utils/__init__.py +38 -0
- django_cfg/modules/django_app_agent/utils/logging.py +360 -0
- django_cfg/modules/django_app_agent/utils/validation.py +417 -0
- django_cfg/modules/django_currency/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
- django_cfg/modules/django_currency/core/converter.py +12 -12
- django_cfg/modules/django_currency/database/__init__.py +2 -2
- django_cfg/modules/django_currency/database/database_loader.py +93 -42
- django_cfg/modules/django_llm/llm/client.py +10 -2
- django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
- django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
- django_cfg/modules/django_unfold/dashboard.py +14 -13
- django_cfg/modules/django_unfold/models/config.py +1 -1
- django_cfg/registry/core.py +3 -0
- django_cfg/registry/third_party.py +2 -2
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/METADATA +2 -1
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/RECORD +224 -118
- django_cfg/apps/accounts/admin/activity.py +0 -96
- django_cfg/apps/accounts/admin/group.py +0 -17
- django_cfg/apps/accounts/admin/otp.py +0 -59
- django_cfg/apps/accounts/admin/registration_source.py +0 -97
- django_cfg/apps/accounts/admin/twilio_response.py +0 -227
- django_cfg/apps/accounts/admin/user.py +0 -300
- django_cfg/apps/agents/core/agent.py +0 -281
- django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
- django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
- django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
- django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
- django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
- django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
- django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
- django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
- django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
- django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
- django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
- django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
- django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
- django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
- django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
- django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
- django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
- django_cfg/apps/tasks/admin.py +0 -320
- django_cfg/middleware/static_nocache.py +0 -55
- django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
- /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
- /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.5.dist-info → django_cfg-1.3.9.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,496 @@
|
|
1
|
+
"""
|
2
|
+
Context models for Django App Agent Module.
|
3
|
+
|
4
|
+
This module defines context models for:
|
5
|
+
- Project structure analysis
|
6
|
+
- Django app information
|
7
|
+
- Architectural patterns
|
8
|
+
- Infrastructure context
|
9
|
+
"""
|
10
|
+
|
11
|
+
from typing import List, Optional, Dict, Any, Set
|
12
|
+
from pathlib import Path
|
13
|
+
from pydantic import Field, field_validator, computed_field
|
14
|
+
|
15
|
+
from .base import BaseAgentModel, ValidationMixin
|
16
|
+
from .enums import AppType, AppFeature
|
17
|
+
|
18
|
+
|
19
|
+
class ArchitecturalPattern(BaseAgentModel):
|
20
|
+
"""Information about an architectural pattern found in the project."""
|
21
|
+
|
22
|
+
name: str = Field(
|
23
|
+
description="Name of the architectural pattern",
|
24
|
+
min_length=1,
|
25
|
+
max_length=100
|
26
|
+
)
|
27
|
+
|
28
|
+
description: str = Field(
|
29
|
+
description="Description of the pattern and its purpose",
|
30
|
+
min_length=10,
|
31
|
+
max_length=500
|
32
|
+
)
|
33
|
+
|
34
|
+
confidence: float = Field(
|
35
|
+
ge=0.0,
|
36
|
+
le=1.0,
|
37
|
+
description="Confidence level in pattern detection (0-1)"
|
38
|
+
)
|
39
|
+
|
40
|
+
evidence: List[str] = Field(
|
41
|
+
default_factory=list,
|
42
|
+
description="Evidence supporting the presence of this pattern"
|
43
|
+
)
|
44
|
+
|
45
|
+
files_using_pattern: List[str] = Field(
|
46
|
+
default_factory=list,
|
47
|
+
description="Files that implement this pattern"
|
48
|
+
)
|
49
|
+
|
50
|
+
benefits: List[str] = Field(
|
51
|
+
default_factory=list,
|
52
|
+
description="Benefits of using this pattern"
|
53
|
+
)
|
54
|
+
|
55
|
+
implementation_notes: List[str] = Field(
|
56
|
+
default_factory=list,
|
57
|
+
description="Notes on how the pattern is implemented"
|
58
|
+
)
|
59
|
+
|
60
|
+
@computed_field
|
61
|
+
@property
|
62
|
+
def is_high_confidence(self) -> bool:
|
63
|
+
"""Check if this pattern detection has high confidence."""
|
64
|
+
return self.confidence >= 0.8
|
65
|
+
|
66
|
+
@computed_field
|
67
|
+
@property
|
68
|
+
def usage_score(self) -> float:
|
69
|
+
"""Calculate usage score based on evidence and files."""
|
70
|
+
evidence_score = min(1.0, len(self.evidence) / 3.0) # Reduced threshold
|
71
|
+
files_score = min(1.0, len(self.files_using_pattern) / 2.0) # Reduced threshold
|
72
|
+
return (evidence_score + files_score + self.confidence) / 3.0
|
73
|
+
|
74
|
+
|
75
|
+
class DjangoAppInfo(BaseAgentModel, ValidationMixin):
|
76
|
+
"""Information about a Django application in the project."""
|
77
|
+
|
78
|
+
name: str = Field(
|
79
|
+
description="Name of the Django app",
|
80
|
+
min_length=1,
|
81
|
+
max_length=50
|
82
|
+
)
|
83
|
+
|
84
|
+
path: Path = Field(
|
85
|
+
description="Path to the app directory"
|
86
|
+
)
|
87
|
+
|
88
|
+
# App structure information
|
89
|
+
has_models: bool = Field(
|
90
|
+
default=False,
|
91
|
+
description="Whether the app has models"
|
92
|
+
)
|
93
|
+
|
94
|
+
has_views: bool = Field(
|
95
|
+
default=False,
|
96
|
+
description="Whether the app has views"
|
97
|
+
)
|
98
|
+
|
99
|
+
has_admin: bool = Field(
|
100
|
+
default=False,
|
101
|
+
description="Whether the app has admin configuration"
|
102
|
+
)
|
103
|
+
|
104
|
+
has_tests: bool = Field(
|
105
|
+
default=False,
|
106
|
+
description="Whether the app has tests"
|
107
|
+
)
|
108
|
+
|
109
|
+
has_services: bool = Field(
|
110
|
+
default=False,
|
111
|
+
description="Whether the app uses service layer pattern"
|
112
|
+
)
|
113
|
+
|
114
|
+
has_async_views: bool = Field(
|
115
|
+
default=False,
|
116
|
+
description="Whether the app has async views"
|
117
|
+
)
|
118
|
+
|
119
|
+
# Pattern information
|
120
|
+
model_patterns: List[str] = Field(
|
121
|
+
default_factory=list,
|
122
|
+
description="Patterns used in models"
|
123
|
+
)
|
124
|
+
|
125
|
+
view_patterns: List[str] = Field(
|
126
|
+
default_factory=list,
|
127
|
+
description="Patterns used in views"
|
128
|
+
)
|
129
|
+
|
130
|
+
service_patterns: List[str] = Field(
|
131
|
+
default_factory=list,
|
132
|
+
description="Patterns used in services"
|
133
|
+
)
|
134
|
+
|
135
|
+
test_patterns: List[str] = Field(
|
136
|
+
default_factory=list,
|
137
|
+
description="Patterns used in tests"
|
138
|
+
)
|
139
|
+
|
140
|
+
# Metrics
|
141
|
+
dependencies: List[str] = Field(
|
142
|
+
default_factory=list,
|
143
|
+
description="External dependencies used by this app"
|
144
|
+
)
|
145
|
+
|
146
|
+
lines_of_code: int = Field(
|
147
|
+
ge=0,
|
148
|
+
default=0,
|
149
|
+
description="Total lines of code in the app"
|
150
|
+
)
|
151
|
+
|
152
|
+
complexity_score: float = Field(
|
153
|
+
ge=0.0,
|
154
|
+
le=10.0,
|
155
|
+
default=5.0,
|
156
|
+
description="Complexity score of the app (0-10)"
|
157
|
+
)
|
158
|
+
|
159
|
+
quality_score: float = Field(
|
160
|
+
ge=0.0,
|
161
|
+
le=10.0,
|
162
|
+
default=7.0,
|
163
|
+
description="Quality score of the app (0-10)"
|
164
|
+
)
|
165
|
+
|
166
|
+
@field_validator('name')
|
167
|
+
@classmethod
|
168
|
+
def validate_app_name(cls, v: str) -> str:
|
169
|
+
"""Validate Django app name."""
|
170
|
+
from ..utils.validation import validate_app_name
|
171
|
+
return validate_app_name(v, check_reserved=False)
|
172
|
+
|
173
|
+
@computed_field
|
174
|
+
@property
|
175
|
+
def features_implemented(self) -> Set[AppFeature]:
|
176
|
+
"""Get set of features implemented by this app."""
|
177
|
+
features = set()
|
178
|
+
|
179
|
+
if self.has_models:
|
180
|
+
features.add(AppFeature.MODELS)
|
181
|
+
if self.has_views:
|
182
|
+
features.add(AppFeature.VIEWS)
|
183
|
+
if self.has_admin:
|
184
|
+
features.add(AppFeature.ADMIN)
|
185
|
+
if self.has_tests:
|
186
|
+
features.add(AppFeature.TESTS)
|
187
|
+
|
188
|
+
return features
|
189
|
+
|
190
|
+
@computed_field
|
191
|
+
@property
|
192
|
+
def all_patterns(self) -> Set[str]:
|
193
|
+
"""Get all patterns used in this app."""
|
194
|
+
all_patterns = set()
|
195
|
+
all_patterns.update(self.model_patterns)
|
196
|
+
all_patterns.update(self.view_patterns)
|
197
|
+
all_patterns.update(self.service_patterns)
|
198
|
+
all_patterns.update(self.test_patterns)
|
199
|
+
return all_patterns
|
200
|
+
|
201
|
+
@computed_field
|
202
|
+
@property
|
203
|
+
def is_well_structured(self) -> bool:
|
204
|
+
"""Check if app follows good structure practices."""
|
205
|
+
return (
|
206
|
+
self.has_models and
|
207
|
+
self.has_views and
|
208
|
+
self.has_tests and
|
209
|
+
self.quality_score >= 7.0
|
210
|
+
)
|
211
|
+
|
212
|
+
def get_integration_compatibility(self, other_app: "DjangoAppInfo") -> float:
|
213
|
+
"""Calculate compatibility score with another app."""
|
214
|
+
# Compare patterns
|
215
|
+
common_patterns = self.all_patterns & other_app.all_patterns
|
216
|
+
total_patterns = self.all_patterns | other_app.all_patterns
|
217
|
+
|
218
|
+
if not total_patterns:
|
219
|
+
return 0.5 # Neutral if no patterns
|
220
|
+
|
221
|
+
pattern_similarity = len(common_patterns) / len(total_patterns)
|
222
|
+
|
223
|
+
# Compare dependencies
|
224
|
+
common_deps = set(self.dependencies) & set(other_app.dependencies)
|
225
|
+
total_deps = set(self.dependencies) | set(other_app.dependencies)
|
226
|
+
|
227
|
+
if total_deps:
|
228
|
+
dep_similarity = len(common_deps) / len(total_deps)
|
229
|
+
else:
|
230
|
+
dep_similarity = 1.0 # Perfect if no dependencies
|
231
|
+
|
232
|
+
# Weighted average
|
233
|
+
return (pattern_similarity * 0.7 + dep_similarity * 0.3)
|
234
|
+
|
235
|
+
|
236
|
+
class ProjectContext(BaseAgentModel):
|
237
|
+
"""Context information about the Django project."""
|
238
|
+
|
239
|
+
project_path: Path = Field(
|
240
|
+
description="Path to the Django project root"
|
241
|
+
)
|
242
|
+
|
243
|
+
project_type: str = Field(
|
244
|
+
default="django",
|
245
|
+
description="Type of Django project (django, django_cfg)"
|
246
|
+
)
|
247
|
+
|
248
|
+
# Project structure
|
249
|
+
django_apps: List[DjangoAppInfo] = Field(
|
250
|
+
default_factory=list,
|
251
|
+
description="Information about Django apps in the project"
|
252
|
+
)
|
253
|
+
|
254
|
+
# Architectural information
|
255
|
+
architectural_patterns: List[str] = Field(
|
256
|
+
default_factory=list,
|
257
|
+
description="Architectural patterns used across the project"
|
258
|
+
)
|
259
|
+
|
260
|
+
security_features: List[str] = Field(
|
261
|
+
default_factory=list,
|
262
|
+
description="Security features implemented in the project"
|
263
|
+
)
|
264
|
+
|
265
|
+
performance_features: List[str] = Field(
|
266
|
+
default_factory=list,
|
267
|
+
description="Performance optimization features"
|
268
|
+
)
|
269
|
+
|
270
|
+
testing_patterns: List[str] = Field(
|
271
|
+
default_factory=list,
|
272
|
+
description="Testing patterns and frameworks used"
|
273
|
+
)
|
274
|
+
|
275
|
+
# Quality metrics
|
276
|
+
documentation_level: str = Field(
|
277
|
+
default="basic",
|
278
|
+
description="Level of documentation (basic, good, comprehensive)"
|
279
|
+
)
|
280
|
+
|
281
|
+
code_quality_score: float = Field(
|
282
|
+
ge=0.0,
|
283
|
+
le=10.0,
|
284
|
+
default=7.0,
|
285
|
+
description="Overall code quality score"
|
286
|
+
)
|
287
|
+
|
288
|
+
type_safety_percentage: float = Field(
|
289
|
+
ge=0.0,
|
290
|
+
le=100.0,
|
291
|
+
default=70.0,
|
292
|
+
description="Percentage of code that is type-safe"
|
293
|
+
)
|
294
|
+
|
295
|
+
@field_validator('project_path')
|
296
|
+
@classmethod
|
297
|
+
def validate_project_path(cls, v: Path) -> Path:
|
298
|
+
"""Validate project path exists."""
|
299
|
+
from ..utils.validation import validate_file_path
|
300
|
+
return validate_file_path(v, must_exist=True, must_be_dir=True)
|
301
|
+
|
302
|
+
@computed_field
|
303
|
+
@property
|
304
|
+
def total_apps_count(self) -> int:
|
305
|
+
"""Get total number of Django apps."""
|
306
|
+
return len(self.django_apps)
|
307
|
+
|
308
|
+
@computed_field
|
309
|
+
@property
|
310
|
+
def apps_with_tests_count(self) -> int:
|
311
|
+
"""Get number of apps with tests."""
|
312
|
+
return sum(1 for app in self.django_apps if app.has_tests)
|
313
|
+
|
314
|
+
@computed_field
|
315
|
+
@property
|
316
|
+
def test_coverage_percentage(self) -> float:
|
317
|
+
"""Calculate test coverage percentage."""
|
318
|
+
if not self.django_apps:
|
319
|
+
return 0.0
|
320
|
+
return (self.apps_with_tests_count / self.total_apps_count) * 100
|
321
|
+
|
322
|
+
@computed_field
|
323
|
+
@property
|
324
|
+
def common_patterns(self) -> Set[str]:
|
325
|
+
"""Get patterns that are common across multiple apps."""
|
326
|
+
if len(self.django_apps) < 2:
|
327
|
+
return set()
|
328
|
+
|
329
|
+
pattern_counts: Dict[str, int] = {}
|
330
|
+
for app in self.django_apps:
|
331
|
+
for pattern in app.all_patterns:
|
332
|
+
pattern_counts[pattern] = pattern_counts.get(pattern, 0) + 1
|
333
|
+
|
334
|
+
# Patterns used in at least 50% of apps
|
335
|
+
threshold = max(1, len(self.django_apps) // 2)
|
336
|
+
return {pattern for pattern, count in pattern_counts.items() if count >= threshold}
|
337
|
+
|
338
|
+
def get_app_by_name(self, name: str) -> Optional[DjangoAppInfo]:
|
339
|
+
"""Get app information by name."""
|
340
|
+
for app in self.django_apps:
|
341
|
+
if app.name == name:
|
342
|
+
return app
|
343
|
+
return None
|
344
|
+
|
345
|
+
def get_apps_using_pattern(self, pattern: str) -> List[DjangoAppInfo]:
|
346
|
+
"""Get apps that use a specific pattern."""
|
347
|
+
return [app for app in self.django_apps if pattern in app.all_patterns]
|
348
|
+
|
349
|
+
def get_recommended_patterns_for_new_app(self) -> List[str]:
|
350
|
+
"""Get recommended patterns for a new app based on existing patterns."""
|
351
|
+
# Prioritize common patterns
|
352
|
+
common = list(self.common_patterns)
|
353
|
+
|
354
|
+
# Add project-level architectural patterns
|
355
|
+
project_patterns = [p for p in self.architectural_patterns if p not in common]
|
356
|
+
|
357
|
+
return common + project_patterns
|
358
|
+
|
359
|
+
def analyze_integration_opportunities(self, app_name: str) -> Dict[str, Any]:
|
360
|
+
"""Analyze integration opportunities for a new app."""
|
361
|
+
similar_apps = []
|
362
|
+
potential_dependencies = set()
|
363
|
+
|
364
|
+
# Find apps with similar patterns
|
365
|
+
for app in self.django_apps:
|
366
|
+
if len(app.all_patterns) > 0:
|
367
|
+
similar_apps.append({
|
368
|
+
"name": app.name,
|
369
|
+
"similarity_score": len(app.all_patterns & self.common_patterns) / len(app.all_patterns),
|
370
|
+
"patterns": list(app.all_patterns)
|
371
|
+
})
|
372
|
+
|
373
|
+
# Sort by similarity
|
374
|
+
similar_apps.sort(key=lambda x: x["similarity_score"], reverse=True)
|
375
|
+
|
376
|
+
# Identify potential dependencies
|
377
|
+
for app in self.django_apps:
|
378
|
+
if app.has_models and "user" in app.name.lower():
|
379
|
+
potential_dependencies.add(f"{app.name}.models")
|
380
|
+
|
381
|
+
return {
|
382
|
+
"similar_apps": similar_apps[:3], # Top 3 similar apps
|
383
|
+
"potential_dependencies": list(potential_dependencies),
|
384
|
+
"recommended_patterns": self.get_recommended_patterns_for_new_app(),
|
385
|
+
"integration_complexity": "low" if len(similar_apps) > 0 else "medium"
|
386
|
+
}
|
387
|
+
|
388
|
+
|
389
|
+
class InfrastructureContext(BaseAgentModel):
|
390
|
+
"""Infrastructure context for code generation."""
|
391
|
+
|
392
|
+
project_context: ProjectContext = Field(
|
393
|
+
description="Project-level context information"
|
394
|
+
)
|
395
|
+
|
396
|
+
target_app_type: AppType = Field(
|
397
|
+
description="Type of app being generated"
|
398
|
+
)
|
399
|
+
|
400
|
+
integration_targets: List[str] = Field(
|
401
|
+
default_factory=list,
|
402
|
+
description="Apps to integrate with"
|
403
|
+
)
|
404
|
+
|
405
|
+
# Generation constraints
|
406
|
+
must_follow_patterns: List[str] = Field(
|
407
|
+
default_factory=list,
|
408
|
+
description="Patterns that must be followed"
|
409
|
+
)
|
410
|
+
|
411
|
+
avoid_patterns: List[str] = Field(
|
412
|
+
default_factory=list,
|
413
|
+
description="Patterns to avoid"
|
414
|
+
)
|
415
|
+
|
416
|
+
# Quality requirements
|
417
|
+
minimum_quality_score: float = Field(
|
418
|
+
ge=0.0,
|
419
|
+
le=10.0,
|
420
|
+
default=8.0,
|
421
|
+
description="Minimum required quality score"
|
422
|
+
)
|
423
|
+
|
424
|
+
require_type_safety: bool = Field(
|
425
|
+
default=True,
|
426
|
+
description="Whether type safety is required"
|
427
|
+
)
|
428
|
+
|
429
|
+
require_tests: bool = Field(
|
430
|
+
default=True,
|
431
|
+
description="Whether tests are required"
|
432
|
+
)
|
433
|
+
|
434
|
+
# Infrastructure preferences
|
435
|
+
preferred_async_style: str = Field(
|
436
|
+
default="async_await",
|
437
|
+
description="Preferred async programming style"
|
438
|
+
)
|
439
|
+
|
440
|
+
database_preferences: List[str] = Field(
|
441
|
+
default_factory=list,
|
442
|
+
description="Database-related preferences"
|
443
|
+
)
|
444
|
+
|
445
|
+
@computed_field
|
446
|
+
@property
|
447
|
+
def effective_patterns(self) -> List[str]:
|
448
|
+
"""Get effective patterns after applying constraints."""
|
449
|
+
# Start with project patterns
|
450
|
+
base_patterns = self.project_context.get_recommended_patterns_for_new_app()
|
451
|
+
|
452
|
+
# Add must-follow patterns
|
453
|
+
effective = list(set(base_patterns + self.must_follow_patterns))
|
454
|
+
|
455
|
+
# Remove avoided patterns
|
456
|
+
effective = [p for p in effective if p not in self.avoid_patterns]
|
457
|
+
|
458
|
+
return effective
|
459
|
+
|
460
|
+
@computed_field
|
461
|
+
@property
|
462
|
+
def integration_complexity(self) -> str:
|
463
|
+
"""Assess integration complexity."""
|
464
|
+
if not self.integration_targets:
|
465
|
+
return "none"
|
466
|
+
|
467
|
+
if len(self.integration_targets) == 1:
|
468
|
+
return "simple"
|
469
|
+
elif len(self.integration_targets) <= 3:
|
470
|
+
return "moderate"
|
471
|
+
else:
|
472
|
+
return "complex"
|
473
|
+
|
474
|
+
def get_integration_requirements(self) -> Dict[str, Any]:
|
475
|
+
"""Get specific integration requirements."""
|
476
|
+
requirements = {
|
477
|
+
"imports_needed": [],
|
478
|
+
"model_relationships": [],
|
479
|
+
"service_dependencies": [],
|
480
|
+
"url_integrations": []
|
481
|
+
}
|
482
|
+
|
483
|
+
for target_app_name in self.integration_targets:
|
484
|
+
target_app = self.project_context.get_app_by_name(target_app_name)
|
485
|
+
if target_app:
|
486
|
+
if target_app.has_models:
|
487
|
+
requirements["imports_needed"].append(f"{target_app_name}.models")
|
488
|
+
|
489
|
+
if target_app.has_services:
|
490
|
+
requirements["service_dependencies"].append(f"{target_app_name}.services")
|
491
|
+
|
492
|
+
# Check for user model integration
|
493
|
+
if "user" in target_app_name.lower():
|
494
|
+
requirements["model_relationships"].append("User foreign key relationships")
|
495
|
+
|
496
|
+
return requirements
|