django-cfg 1.3.7__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/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.7.dist-info → django_cfg-1.3.9.dist-info}/METADATA +2 -1
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.9.dist-info}/RECORD +223 -117
- 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.7.dist-info → django_cfg-1.3.9.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.9.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.7.dist-info → django_cfg-1.3.9.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,500 @@
|
|
1
|
+
"""
|
2
|
+
Request models for Django App Agent Module.
|
3
|
+
|
4
|
+
This module defines all request models with:
|
5
|
+
- Complete Pydantic 2 validation
|
6
|
+
- Type-safe field definitions
|
7
|
+
- Business logic validation
|
8
|
+
- Clear documentation
|
9
|
+
"""
|
10
|
+
|
11
|
+
from typing import List, Optional, Dict, Any, Set
|
12
|
+
from pathlib import Path
|
13
|
+
from pydantic import Field, field_validator, model_validator
|
14
|
+
|
15
|
+
from .base import BaseAgentModel, ValidationMixin
|
16
|
+
from .enums import AppFeature, AppComplexity, AppType, QuestionType, ImpactLevel
|
17
|
+
from ..utils.validation import validate_app_name, validate_description
|
18
|
+
|
19
|
+
|
20
|
+
class AppGenerationRequest(BaseAgentModel, ValidationMixin):
|
21
|
+
"""Request for generating a Django application."""
|
22
|
+
|
23
|
+
# Core application details
|
24
|
+
app_name: str = Field(
|
25
|
+
description="Name of the Django application to generate",
|
26
|
+
min_length=2,
|
27
|
+
max_length=50,
|
28
|
+
pattern=r'^[a-z][a-z0-9_]*$'
|
29
|
+
)
|
30
|
+
|
31
|
+
description: str = Field(
|
32
|
+
description="Detailed description of the application purpose and functionality",
|
33
|
+
min_length=10,
|
34
|
+
max_length=500
|
35
|
+
)
|
36
|
+
|
37
|
+
# Application configuration
|
38
|
+
app_type: AppType = Field(
|
39
|
+
default=AppType.DJANGO_CFG,
|
40
|
+
description="Type of Django application to generate"
|
41
|
+
)
|
42
|
+
|
43
|
+
features: List[AppFeature] = Field(
|
44
|
+
default_factory=list,
|
45
|
+
description="List of features to include in the generated application"
|
46
|
+
)
|
47
|
+
|
48
|
+
complexity: AppComplexity = Field(
|
49
|
+
default=AppComplexity.MODERATE,
|
50
|
+
description="Complexity level of the application"
|
51
|
+
)
|
52
|
+
|
53
|
+
# Generation options
|
54
|
+
enable_questioning: bool = Field(
|
55
|
+
default=True,
|
56
|
+
description="Whether to enable intelligent questioning system"
|
57
|
+
)
|
58
|
+
|
59
|
+
max_questions: int = Field(
|
60
|
+
default=20,
|
61
|
+
ge=0,
|
62
|
+
le=50,
|
63
|
+
description="Maximum number of questions to ask during generation"
|
64
|
+
)
|
65
|
+
|
66
|
+
questioning_timeout_minutes: int = Field(
|
67
|
+
default=15,
|
68
|
+
ge=1,
|
69
|
+
le=60,
|
70
|
+
description="Timeout for questioning session in minutes"
|
71
|
+
)
|
72
|
+
|
73
|
+
# Quality requirements
|
74
|
+
quality_threshold: float = Field(
|
75
|
+
default=8.0,
|
76
|
+
ge=0.0,
|
77
|
+
le=10.0,
|
78
|
+
description="Minimum quality score required for generated code"
|
79
|
+
)
|
80
|
+
|
81
|
+
# Integration options
|
82
|
+
target_apps: List[str] = Field(
|
83
|
+
default_factory=list,
|
84
|
+
description="Existing apps to analyze for integration patterns"
|
85
|
+
)
|
86
|
+
|
87
|
+
exclude_patterns: List[str] = Field(
|
88
|
+
default_factory=list,
|
89
|
+
description="Patterns to exclude from generation"
|
90
|
+
)
|
91
|
+
|
92
|
+
# Output configuration
|
93
|
+
output_directory: Optional[Path] = Field(
|
94
|
+
default=None,
|
95
|
+
description="Custom output directory for generated files"
|
96
|
+
)
|
97
|
+
|
98
|
+
# Advanced options
|
99
|
+
custom_requirements: Dict[str, Any] = Field(
|
100
|
+
default_factory=dict,
|
101
|
+
description="Custom requirements and constraints"
|
102
|
+
)
|
103
|
+
|
104
|
+
# UI options
|
105
|
+
rich_interface: bool = Field(
|
106
|
+
default=True,
|
107
|
+
description="Enable Rich CLI interface with progress bars"
|
108
|
+
)
|
109
|
+
|
110
|
+
verbose_output: bool = Field(
|
111
|
+
default=False,
|
112
|
+
description="Enable verbose output during generation"
|
113
|
+
)
|
114
|
+
|
115
|
+
@field_validator('app_name')
|
116
|
+
@classmethod
|
117
|
+
def validate_app_name_field(cls, v: str) -> str:
|
118
|
+
"""Validate application name using utility function."""
|
119
|
+
return validate_app_name(v, check_reserved=True)
|
120
|
+
|
121
|
+
@field_validator('description')
|
122
|
+
@classmethod
|
123
|
+
def validate_description_field(cls, v: str) -> str:
|
124
|
+
"""Validate application description."""
|
125
|
+
return validate_description(v, min_length=10, max_length=500)
|
126
|
+
|
127
|
+
@field_validator('features')
|
128
|
+
@classmethod
|
129
|
+
def validate_features_list(cls, v: List[AppFeature]) -> List[AppFeature]:
|
130
|
+
"""Validate and deduplicate features list."""
|
131
|
+
if not v:
|
132
|
+
return []
|
133
|
+
|
134
|
+
# Convert strings to enums if needed
|
135
|
+
enum_features = []
|
136
|
+
for feature in v:
|
137
|
+
if isinstance(feature, str):
|
138
|
+
enum_features.append(AppFeature(feature))
|
139
|
+
else:
|
140
|
+
enum_features.append(feature)
|
141
|
+
|
142
|
+
# Remove duplicates while preserving order
|
143
|
+
seen = set()
|
144
|
+
unique_features = []
|
145
|
+
for feature in enum_features:
|
146
|
+
if feature not in seen:
|
147
|
+
seen.add(feature)
|
148
|
+
unique_features.append(feature)
|
149
|
+
|
150
|
+
return unique_features
|
151
|
+
|
152
|
+
@field_validator('complexity')
|
153
|
+
@classmethod
|
154
|
+
def validate_complexity_enum(cls, v) -> AppComplexity:
|
155
|
+
"""Ensure complexity is proper enum."""
|
156
|
+
if isinstance(v, str):
|
157
|
+
return AppComplexity(v)
|
158
|
+
return v
|
159
|
+
|
160
|
+
@field_validator('app_type')
|
161
|
+
@classmethod
|
162
|
+
def validate_app_type_enum(cls, v) -> AppType:
|
163
|
+
"""Ensure app_type is proper enum."""
|
164
|
+
if isinstance(v, str):
|
165
|
+
return AppType(v)
|
166
|
+
return v
|
167
|
+
|
168
|
+
@field_validator('target_apps')
|
169
|
+
@classmethod
|
170
|
+
def validate_target_apps(cls, v: List[str]) -> List[str]:
|
171
|
+
"""Validate target apps list."""
|
172
|
+
if not v:
|
173
|
+
return []
|
174
|
+
|
175
|
+
validated_apps = []
|
176
|
+
for app_name in v:
|
177
|
+
try:
|
178
|
+
validated_name = validate_app_name(app_name, check_reserved=False)
|
179
|
+
validated_apps.append(validated_name)
|
180
|
+
except Exception:
|
181
|
+
# Skip invalid app names
|
182
|
+
continue
|
183
|
+
|
184
|
+
return validated_apps
|
185
|
+
|
186
|
+
@model_validator(mode='after')
|
187
|
+
def validate_consistency(self) -> 'AppGenerationRequest':
|
188
|
+
"""Validate consistency between fields."""
|
189
|
+
# Note: Pydantic 2 handles enum conversion automatically,
|
190
|
+
# so we don't need to manually convert them here
|
191
|
+
|
192
|
+
# Auto-populate features based on complexity if not specified
|
193
|
+
if not self.features:
|
194
|
+
self.features = list(self.complexity.get_recommended_features())
|
195
|
+
|
196
|
+
# Validate feature dependencies
|
197
|
+
all_features = set(self.features)
|
198
|
+
for feature in self.features:
|
199
|
+
dependencies = feature.get_dependencies()
|
200
|
+
missing_deps = dependencies - all_features
|
201
|
+
if missing_deps:
|
202
|
+
# Add missing dependencies
|
203
|
+
self.features.extend(list(missing_deps))
|
204
|
+
|
205
|
+
# Adjust max_questions based on complexity
|
206
|
+
if self.max_questions > self.complexity.get_max_questions():
|
207
|
+
self.max_questions = self.complexity.get_max_questions()
|
208
|
+
|
209
|
+
# Validate app type supports all requested features
|
210
|
+
unsupported_features = []
|
211
|
+
for feature in self.features:
|
212
|
+
if not self.app_type.supports_feature(feature):
|
213
|
+
unsupported_features.append(feature)
|
214
|
+
|
215
|
+
if unsupported_features:
|
216
|
+
raise ValueError(
|
217
|
+
f"App type {self.app_type} does not support features: {unsupported_features}"
|
218
|
+
)
|
219
|
+
|
220
|
+
return self
|
221
|
+
|
222
|
+
def get_estimated_time_minutes(self) -> int:
|
223
|
+
"""Get estimated generation time in minutes."""
|
224
|
+
base_time = self.complexity.get_estimated_time_minutes()
|
225
|
+
|
226
|
+
# Add time for additional features
|
227
|
+
feature_multiplier = len(self.features) / len(self.complexity.get_recommended_features())
|
228
|
+
adjusted_time = int(base_time * max(1.0, feature_multiplier))
|
229
|
+
|
230
|
+
# Add questioning time if enabled
|
231
|
+
if self.enable_questioning:
|
232
|
+
adjusted_time += min(self.questioning_timeout_minutes, 10)
|
233
|
+
|
234
|
+
return adjusted_time
|
235
|
+
|
236
|
+
def get_feature_set(self) -> Set[AppFeature]:
|
237
|
+
"""Get set of features for easy lookup."""
|
238
|
+
return set(self.features)
|
239
|
+
|
240
|
+
def has_feature(self, feature: AppFeature) -> bool:
|
241
|
+
"""Check if a specific feature is requested."""
|
242
|
+
return feature in self.get_feature_set()
|
243
|
+
|
244
|
+
|
245
|
+
class QuestioningRequest(BaseAgentModel):
|
246
|
+
"""Request for conducting an intelligent questioning session."""
|
247
|
+
|
248
|
+
user_intent: str = Field(
|
249
|
+
description="User's stated intent or goal for the application",
|
250
|
+
min_length=5,
|
251
|
+
max_length=200
|
252
|
+
)
|
253
|
+
|
254
|
+
project_path: Path = Field(
|
255
|
+
description="Path to the Django project for context analysis"
|
256
|
+
)
|
257
|
+
|
258
|
+
app_generation_request: AppGenerationRequest = Field(
|
259
|
+
description="Associated app generation request"
|
260
|
+
)
|
261
|
+
|
262
|
+
max_questions: int = Field(
|
263
|
+
default=20,
|
264
|
+
ge=1,
|
265
|
+
le=50,
|
266
|
+
description="Maximum number of questions to ask"
|
267
|
+
)
|
268
|
+
|
269
|
+
timeout_minutes: int = Field(
|
270
|
+
default=15,
|
271
|
+
ge=1,
|
272
|
+
le=60,
|
273
|
+
description="Maximum time for questioning session"
|
274
|
+
)
|
275
|
+
|
276
|
+
focus_areas: List[str] = Field(
|
277
|
+
default_factory=list,
|
278
|
+
description="Specific areas to focus questions on"
|
279
|
+
)
|
280
|
+
|
281
|
+
skip_basic_questions: bool = Field(
|
282
|
+
default=False,
|
283
|
+
description="Skip basic questions and focus on advanced topics"
|
284
|
+
)
|
285
|
+
|
286
|
+
@field_validator('project_path')
|
287
|
+
@classmethod
|
288
|
+
def validate_project_path(cls, v: Path) -> Path:
|
289
|
+
"""Validate that project path exists and is a directory."""
|
290
|
+
from ..utils.validation import validate_file_path
|
291
|
+
|
292
|
+
return validate_file_path(
|
293
|
+
v,
|
294
|
+
must_exist=True,
|
295
|
+
must_be_dir=True
|
296
|
+
)
|
297
|
+
|
298
|
+
|
299
|
+
class DiagnosticRequest(BaseAgentModel):
|
300
|
+
"""Request for diagnosing problems in Django applications."""
|
301
|
+
|
302
|
+
project_path: Path = Field(
|
303
|
+
description="Path to the Django project to diagnose"
|
304
|
+
)
|
305
|
+
|
306
|
+
app_name: Optional[str] = Field(
|
307
|
+
default=None,
|
308
|
+
description="Specific app to focus diagnosis on"
|
309
|
+
)
|
310
|
+
|
311
|
+
problem_description: str = Field(
|
312
|
+
description="Description of the problem or issue",
|
313
|
+
min_length=10,
|
314
|
+
max_length=1000
|
315
|
+
)
|
316
|
+
|
317
|
+
error_messages: List[str] = Field(
|
318
|
+
default_factory=list,
|
319
|
+
description="Any error messages encountered"
|
320
|
+
)
|
321
|
+
|
322
|
+
symptoms: List[str] = Field(
|
323
|
+
default_factory=list,
|
324
|
+
description="Observed symptoms of the problem"
|
325
|
+
)
|
326
|
+
|
327
|
+
recent_changes: List[str] = Field(
|
328
|
+
default_factory=list,
|
329
|
+
description="Recent changes that might be related"
|
330
|
+
)
|
331
|
+
|
332
|
+
urgency_level: ImpactLevel = Field(
|
333
|
+
default=ImpactLevel.MEDIUM,
|
334
|
+
description="Urgency level of the problem"
|
335
|
+
)
|
336
|
+
|
337
|
+
include_suggestions: bool = Field(
|
338
|
+
default=True,
|
339
|
+
description="Whether to include solution suggestions"
|
340
|
+
)
|
341
|
+
|
342
|
+
max_suggestions: int = Field(
|
343
|
+
default=5,
|
344
|
+
ge=1,
|
345
|
+
le=20,
|
346
|
+
description="Maximum number of solution suggestions"
|
347
|
+
)
|
348
|
+
|
349
|
+
@field_validator('project_path')
|
350
|
+
@classmethod
|
351
|
+
def validate_project_path(cls, v: Path) -> Path:
|
352
|
+
"""Validate that project path exists."""
|
353
|
+
from ..utils.validation import validate_file_path
|
354
|
+
|
355
|
+
return validate_file_path(
|
356
|
+
v,
|
357
|
+
must_exist=True,
|
358
|
+
must_be_dir=True
|
359
|
+
)
|
360
|
+
|
361
|
+
@field_validator('app_name')
|
362
|
+
@classmethod
|
363
|
+
def validate_app_name_field(cls, v: Optional[str]) -> Optional[str]:
|
364
|
+
"""Validate app name if provided."""
|
365
|
+
if v is None:
|
366
|
+
return v
|
367
|
+
|
368
|
+
return validate_app_name(v, check_reserved=False)
|
369
|
+
|
370
|
+
@field_validator('problem_description')
|
371
|
+
@classmethod
|
372
|
+
def validate_problem_description(cls, v: str) -> str:
|
373
|
+
"""Validate problem description."""
|
374
|
+
return validate_description(v, min_length=10, max_length=1000)
|
375
|
+
|
376
|
+
|
377
|
+
class ContextualQuestion(BaseAgentModel):
|
378
|
+
"""A contextual question generated by the intelligent questioning system."""
|
379
|
+
|
380
|
+
id: str = Field(description="Unique question identifier")
|
381
|
+
|
382
|
+
text: str = Field(
|
383
|
+
description="The question text to display to the user",
|
384
|
+
min_length=10,
|
385
|
+
max_length=500
|
386
|
+
)
|
387
|
+
|
388
|
+
question_type: QuestionType = Field(
|
389
|
+
description="Type of question (yes/no, multiple choice, etc.)"
|
390
|
+
)
|
391
|
+
|
392
|
+
impact_level: ImpactLevel = Field(
|
393
|
+
description="Impact level of this question on the final result"
|
394
|
+
)
|
395
|
+
|
396
|
+
context_evidence: List[str] = Field(
|
397
|
+
default_factory=list,
|
398
|
+
description="Evidence from codebase that prompted this question"
|
399
|
+
)
|
400
|
+
|
401
|
+
options: Optional[List[str]] = Field(
|
402
|
+
default=None,
|
403
|
+
description="Available options for multiple choice questions"
|
404
|
+
)
|
405
|
+
|
406
|
+
default_answer: Optional[str] = Field(
|
407
|
+
default=None,
|
408
|
+
description="Default answer if user skips"
|
409
|
+
)
|
410
|
+
|
411
|
+
architectural_implications: List[str] = Field(
|
412
|
+
default_factory=list,
|
413
|
+
description="How the answer affects architectural decisions"
|
414
|
+
)
|
415
|
+
|
416
|
+
@field_validator('question_type')
|
417
|
+
@classmethod
|
418
|
+
def validate_question_type_enum(cls, v) -> QuestionType:
|
419
|
+
"""Ensure question_type is proper enum."""
|
420
|
+
if isinstance(v, str):
|
421
|
+
return QuestionType(v)
|
422
|
+
return v
|
423
|
+
|
424
|
+
@field_validator('impact_level')
|
425
|
+
@classmethod
|
426
|
+
def validate_impact_level_enum(cls, v) -> ImpactLevel:
|
427
|
+
"""Ensure impact_level is proper enum."""
|
428
|
+
if isinstance(v, str):
|
429
|
+
return ImpactLevel(v)
|
430
|
+
return v
|
431
|
+
|
432
|
+
@model_validator(mode='after')
|
433
|
+
def validate_question_consistency(self) -> 'ContextualQuestion':
|
434
|
+
"""Validate question consistency."""
|
435
|
+
# Note: Pydantic 2 handles enum conversion automatically
|
436
|
+
|
437
|
+
# Questions requiring options must have them
|
438
|
+
if self.question_type.requires_options() and not self.options:
|
439
|
+
raise ValueError(f"Question type {self.question_type} requires options")
|
440
|
+
|
441
|
+
# Validate default answer is in options if provided
|
442
|
+
if self.default_answer and self.options:
|
443
|
+
if self.default_answer not in self.options:
|
444
|
+
raise ValueError("Default answer must be one of the provided options")
|
445
|
+
|
446
|
+
return self
|
447
|
+
|
448
|
+
|
449
|
+
class QuestionResponse(BaseAgentModel):
|
450
|
+
"""Response to a contextual question."""
|
451
|
+
|
452
|
+
question_id: str = Field(description="ID of the question being answered")
|
453
|
+
|
454
|
+
answer: str = Field(
|
455
|
+
description="User's answer to the question",
|
456
|
+
min_length=1,
|
457
|
+
max_length=1000
|
458
|
+
)
|
459
|
+
|
460
|
+
confidence: float = Field(
|
461
|
+
default=1.0,
|
462
|
+
ge=0.0,
|
463
|
+
le=1.0,
|
464
|
+
description="User's confidence in their answer (0-1)"
|
465
|
+
)
|
466
|
+
|
467
|
+
notes: Optional[str] = Field(
|
468
|
+
default=None,
|
469
|
+
max_length=500,
|
470
|
+
description="Additional notes or context from user"
|
471
|
+
)
|
472
|
+
|
473
|
+
|
474
|
+
class TemplateRequest(BaseAgentModel):
|
475
|
+
"""Request for template rendering."""
|
476
|
+
|
477
|
+
template_name: str = Field(
|
478
|
+
description="Name of the template to render",
|
479
|
+
min_length=1,
|
480
|
+
max_length=100
|
481
|
+
)
|
482
|
+
|
483
|
+
app_type: AppType = Field(
|
484
|
+
description="Type of Django application"
|
485
|
+
)
|
486
|
+
|
487
|
+
features: List[AppFeature] = Field(
|
488
|
+
default_factory=list,
|
489
|
+
description="List of features to include in template"
|
490
|
+
)
|
491
|
+
|
492
|
+
variables: Dict[str, Any] = Field(
|
493
|
+
default_factory=dict,
|
494
|
+
description="Template variables for rendering"
|
495
|
+
)
|
496
|
+
|
497
|
+
custom_templates: Dict[str, str] = Field(
|
498
|
+
default_factory=dict,
|
499
|
+
description="Custom template overrides"
|
500
|
+
)
|