django-cfg 1.3.9__py3-none-any.whl → 1.3.13__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/inlines.py +11 -5
- 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.13.dist-info}/METADATA +2 -2
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/RECORD +85 -153
- 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.13.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,125 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Validation Module for Django App Agent Generation.
|
3
|
-
|
4
|
-
This module handles validation of generation requirements,
|
5
|
-
feature compatibility, and generated code quality.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import List, Dict, Any
|
9
|
-
from pathlib import Path
|
10
|
-
|
11
|
-
from ..base import ServiceDependencies
|
12
|
-
from ...core.exceptions import ValidationError, FileSystemError
|
13
|
-
from ...models.responses import ValidationIssue, QualityMetrics
|
14
|
-
from ...models.enums import ValidationSeverity
|
15
|
-
from .context import GenerationContext
|
16
|
-
|
17
|
-
|
18
|
-
class GenerationValidator:
|
19
|
-
"""Handles validation during application generation process."""
|
20
|
-
|
21
|
-
async def validate_generation_requirements(
|
22
|
-
self,
|
23
|
-
context: GenerationContext,
|
24
|
-
dependencies: ServiceDependencies
|
25
|
-
) -> None:
|
26
|
-
"""Validate that generation can proceed."""
|
27
|
-
# Check if app directory already exists
|
28
|
-
if context.app_directory.exists():
|
29
|
-
raise ValidationError(
|
30
|
-
f"Application directory already exists: {context.app_directory}",
|
31
|
-
validation_type="directory_exists"
|
32
|
-
)
|
33
|
-
|
34
|
-
# Check if target directory is writable
|
35
|
-
if not context.target_directory.exists():
|
36
|
-
try:
|
37
|
-
context.target_directory.mkdir(parents=True, exist_ok=True)
|
38
|
-
except Exception as e:
|
39
|
-
raise FileSystemError(
|
40
|
-
f"Cannot create target directory: {e}",
|
41
|
-
file_path=str(context.target_directory),
|
42
|
-
operation="create_directory"
|
43
|
-
)
|
44
|
-
|
45
|
-
# Validate feature compatibility
|
46
|
-
await self.validate_feature_compatibility(context, dependencies)
|
47
|
-
|
48
|
-
async def validate_feature_compatibility(
|
49
|
-
self,
|
50
|
-
context: GenerationContext,
|
51
|
-
dependencies: ServiceDependencies
|
52
|
-
) -> None:
|
53
|
-
"""Validate that requested features are compatible."""
|
54
|
-
request = context.request
|
55
|
-
|
56
|
-
# Check app type compatibility
|
57
|
-
for feature in request.features:
|
58
|
-
if not request.app_type.supports_feature(feature):
|
59
|
-
raise ValidationError(
|
60
|
-
f"Feature {feature.value} is not supported by app type {request.app_type.value}",
|
61
|
-
validation_type="feature_compatibility"
|
62
|
-
)
|
63
|
-
|
64
|
-
# Check complexity compatibility
|
65
|
-
recommended_features = request.complexity.get_recommended_features()
|
66
|
-
missing_recommended = recommended_features - set(request.features)
|
67
|
-
|
68
|
-
if missing_recommended:
|
69
|
-
dependencies.logger.warning(
|
70
|
-
f"Missing recommended features for {request.complexity.value} complexity",
|
71
|
-
missing_features=[f.value for f in missing_recommended]
|
72
|
-
)
|
73
|
-
|
74
|
-
async def validate_generated_code(
|
75
|
-
self,
|
76
|
-
context: GenerationContext,
|
77
|
-
dependencies: ServiceDependencies
|
78
|
-
) -> QualityMetrics:
|
79
|
-
"""Validate generated code quality and return metrics."""
|
80
|
-
dependencies.log_operation("Validating generated code quality")
|
81
|
-
|
82
|
-
validation_issues = []
|
83
|
-
total_files = len(context.generated_files)
|
84
|
-
valid_files = 0
|
85
|
-
|
86
|
-
for generated_file in context.generated_files:
|
87
|
-
try:
|
88
|
-
# Basic syntax validation for Python files
|
89
|
-
if generated_file.file_type == "python":
|
90
|
-
compile(generated_file.content, generated_file.path, 'exec')
|
91
|
-
valid_files += 1
|
92
|
-
else:
|
93
|
-
valid_files += 1 # Non-Python files are considered valid for now
|
94
|
-
|
95
|
-
except SyntaxError as e:
|
96
|
-
validation_issues.append(ValidationIssue(
|
97
|
-
file_path=generated_file.path,
|
98
|
-
line_number=e.lineno or 1,
|
99
|
-
severity=ValidationSeverity.ERROR,
|
100
|
-
message=f"Syntax error: {e.msg}",
|
101
|
-
rule_id="syntax_error"
|
102
|
-
))
|
103
|
-
|
104
|
-
# Calculate quality metrics
|
105
|
-
syntax_score = (valid_files / total_files * 100) if total_files > 0 else 100
|
106
|
-
|
107
|
-
# Store validation results in context
|
108
|
-
context.validation_results.update({
|
109
|
-
"total_files": total_files,
|
110
|
-
"valid_files": valid_files,
|
111
|
-
"validation_issues": [issue.model_dump() for issue in validation_issues],
|
112
|
-
"syntax_score": syntax_score
|
113
|
-
})
|
114
|
-
|
115
|
-
return QualityMetrics(
|
116
|
-
overall_score=min(10.0, syntax_score * 0.8), # Weighted average
|
117
|
-
type_safety_score=8.5, # Placeholder - would need actual type checking
|
118
|
-
pattern_consistency=9.0, # Placeholder - would need pattern analysis
|
119
|
-
code_complexity=7.5, # Placeholder - would need complexity analysis
|
120
|
-
test_coverage=0.0, # No tests generated yet
|
121
|
-
documentation_coverage=60.0, # Basic docstrings (percentage)
|
122
|
-
performance_score=8.0, # Placeholder
|
123
|
-
security_score=8.5, # Placeholder
|
124
|
-
maintainability_score=min(10.0, syntax_score * 0.9)
|
125
|
-
)
|
@@ -1,437 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Base service classes for Django App Agent Module.
|
3
|
-
|
4
|
-
This module provides the foundation for all business logic services,
|
5
|
-
including common patterns for dependency injection, error handling,
|
6
|
-
logging, and async operations.
|
7
|
-
"""
|
8
|
-
|
9
|
-
from typing import TypeVar, Generic, Optional, Dict, Any, List, Union
|
10
|
-
from abc import ABC, abstractmethod
|
11
|
-
from datetime import datetime, timezone
|
12
|
-
from pathlib import Path
|
13
|
-
import asyncio
|
14
|
-
import uuid
|
15
|
-
|
16
|
-
from pydantic import BaseModel, Field, ConfigDict
|
17
|
-
|
18
|
-
from ..core.config import AgentConfig
|
19
|
-
from ..core.exceptions import DjangoAppAgentError, ValidationError
|
20
|
-
from ..utils.logging import StructuredLogger, get_logger
|
21
|
-
|
22
|
-
# Type variables for generic service operations
|
23
|
-
InputT = TypeVar('InputT')
|
24
|
-
OutputT = TypeVar('OutputT')
|
25
|
-
|
26
|
-
|
27
|
-
class ServiceError(DjangoAppAgentError):
|
28
|
-
"""Base exception for service layer errors."""
|
29
|
-
|
30
|
-
def __init__(
|
31
|
-
self,
|
32
|
-
message: str,
|
33
|
-
service_name: str,
|
34
|
-
operation: str,
|
35
|
-
details: Optional[Dict[str, Any]] = None
|
36
|
-
):
|
37
|
-
super().__init__(message, details)
|
38
|
-
self.service_name = service_name
|
39
|
-
self.operation = operation
|
40
|
-
|
41
|
-
|
42
|
-
class ServiceResult(BaseModel, Generic[OutputT]):
|
43
|
-
"""Standard result wrapper for service operations."""
|
44
|
-
|
45
|
-
model_config = ConfigDict(
|
46
|
-
extra='forbid',
|
47
|
-
validate_assignment=True,
|
48
|
-
arbitrary_types_allowed=True
|
49
|
-
)
|
50
|
-
|
51
|
-
# Result metadata
|
52
|
-
operation_id: str = Field(description="Unique operation identifier")
|
53
|
-
service_name: str = Field(description="Name of the service that produced this result")
|
54
|
-
operation_name: str = Field(description="Name of the operation performed")
|
55
|
-
|
56
|
-
# Execution information
|
57
|
-
success: bool = Field(description="Whether the operation was successful")
|
58
|
-
start_time: datetime = Field(description="Operation start time")
|
59
|
-
end_time: Optional[datetime] = Field(default=None, description="Operation end time")
|
60
|
-
|
61
|
-
# Result data
|
62
|
-
data: Optional[OutputT] = Field(default=None, description="Operation result data")
|
63
|
-
error: Optional[str] = Field(default=None, description="Error message if failed")
|
64
|
-
|
65
|
-
# Performance metrics
|
66
|
-
execution_time_seconds: float = Field(default=0.0, description="Total execution time")
|
67
|
-
memory_usage_mb: Optional[float] = Field(default=None, description="Peak memory usage")
|
68
|
-
|
69
|
-
# Context information
|
70
|
-
metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
71
|
-
warnings: List[str] = Field(default_factory=list, description="Operation warnings")
|
72
|
-
|
73
|
-
@property
|
74
|
-
def is_successful(self) -> bool:
|
75
|
-
"""Check if operation was successful."""
|
76
|
-
return self.success and self.error is None
|
77
|
-
|
78
|
-
@property
|
79
|
-
def is_failed(self) -> bool:
|
80
|
-
"""Check if operation failed."""
|
81
|
-
return not self.success or self.error is not None
|
82
|
-
|
83
|
-
def mark_completed(self, data: Optional[OutputT] = None) -> None:
|
84
|
-
"""Mark operation as successfully completed."""
|
85
|
-
self.end_time = datetime.now(timezone.utc)
|
86
|
-
self.execution_time_seconds = (self.end_time - self.start_time).total_seconds()
|
87
|
-
self.success = True
|
88
|
-
if data is not None:
|
89
|
-
self.data = data
|
90
|
-
|
91
|
-
def mark_failed(self, error: str, details: Optional[Dict[str, Any]] = None) -> None:
|
92
|
-
"""Mark operation as failed."""
|
93
|
-
self.end_time = datetime.now(timezone.utc)
|
94
|
-
self.execution_time_seconds = (self.end_time - self.start_time).total_seconds()
|
95
|
-
self.success = False
|
96
|
-
self.error = error
|
97
|
-
if details:
|
98
|
-
self.metadata.update(details)
|
99
|
-
|
100
|
-
def add_warning(self, warning: str) -> None:
|
101
|
-
"""Add a warning to the result."""
|
102
|
-
self.warnings.append(warning)
|
103
|
-
|
104
|
-
def get_summary(self) -> Dict[str, Any]:
|
105
|
-
"""Get operation summary."""
|
106
|
-
return {
|
107
|
-
"operation_id": self.operation_id,
|
108
|
-
"service_name": self.service_name,
|
109
|
-
"operation_name": self.operation_name,
|
110
|
-
"success": self.success,
|
111
|
-
"execution_time_seconds": self.execution_time_seconds,
|
112
|
-
"has_data": self.data is not None,
|
113
|
-
"has_error": self.error is not None,
|
114
|
-
"warnings_count": len(self.warnings),
|
115
|
-
"metadata_keys": list(self.metadata.keys())
|
116
|
-
}
|
117
|
-
|
118
|
-
|
119
|
-
class ServiceDependencies(BaseModel):
|
120
|
-
"""Dependencies for service operations."""
|
121
|
-
|
122
|
-
model_config = ConfigDict(
|
123
|
-
extra='forbid',
|
124
|
-
validate_assignment=True,
|
125
|
-
arbitrary_types_allowed=True
|
126
|
-
)
|
127
|
-
|
128
|
-
config: AgentConfig = Field(description="Agent configuration")
|
129
|
-
logger: StructuredLogger = Field(description="Structured logger instance")
|
130
|
-
operation_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique operation ID")
|
131
|
-
project_root: Optional[Path] = Field(default=None, description="Project root directory")
|
132
|
-
output_directory: Optional[Path] = Field(default=None, description="Output directory")
|
133
|
-
context_data: Dict[str, Any] = Field(default_factory=dict, description="Additional context data")
|
134
|
-
|
135
|
-
def get_project_path(self) -> Path:
|
136
|
-
"""Get project root path."""
|
137
|
-
return self.project_root or Path.cwd()
|
138
|
-
|
139
|
-
def get_output_path(self) -> Path:
|
140
|
-
"""Get output directory path."""
|
141
|
-
return self.output_directory or self.get_project_path()
|
142
|
-
|
143
|
-
def log_operation(self, message: str, **kwargs: Any) -> None:
|
144
|
-
"""Log operation with context."""
|
145
|
-
self.logger.info(
|
146
|
-
message,
|
147
|
-
operation_id=self.operation_id,
|
148
|
-
**kwargs
|
149
|
-
)
|
150
|
-
|
151
|
-
def log_error(self, message: str, error: Exception, **kwargs: Any) -> None:
|
152
|
-
"""Log error with context."""
|
153
|
-
self.logger.error(
|
154
|
-
message,
|
155
|
-
operation_id=self.operation_id,
|
156
|
-
error=str(error),
|
157
|
-
error_type=type(error).__name__,
|
158
|
-
**kwargs
|
159
|
-
)
|
160
|
-
|
161
|
-
|
162
|
-
class BaseService(ABC, Generic[InputT, OutputT]):
|
163
|
-
"""
|
164
|
-
Abstract base class for all services in the Django App Agent module.
|
165
|
-
|
166
|
-
Provides common functionality for:
|
167
|
-
- Dependency injection and configuration
|
168
|
-
- Structured logging and error handling
|
169
|
-
- Operation tracking and metrics
|
170
|
-
- Async operation support
|
171
|
-
- Type safety with generics
|
172
|
-
"""
|
173
|
-
|
174
|
-
def __init__(self, service_name: str, config: AgentConfig):
|
175
|
-
"""Initialize base service.
|
176
|
-
|
177
|
-
Args:
|
178
|
-
service_name: Name of the service for logging and identification
|
179
|
-
config: Agent configuration
|
180
|
-
"""
|
181
|
-
self.service_name = service_name
|
182
|
-
self.config = config
|
183
|
-
self.logger = get_logger(f"services.{service_name}")
|
184
|
-
self._active_operations: Dict[str, ServiceResult] = {}
|
185
|
-
|
186
|
-
def create_dependencies(
|
187
|
-
self,
|
188
|
-
operation_id: Optional[str] = None,
|
189
|
-
project_root: Optional[Path] = None,
|
190
|
-
output_directory: Optional[Path] = None,
|
191
|
-
**context_data: Any
|
192
|
-
) -> ServiceDependencies:
|
193
|
-
"""Create service dependencies for an operation.
|
194
|
-
|
195
|
-
Args:
|
196
|
-
operation_id: Optional operation ID
|
197
|
-
project_root: Optional project root directory
|
198
|
-
output_directory: Optional output directory
|
199
|
-
**context_data: Additional context data
|
200
|
-
|
201
|
-
Returns:
|
202
|
-
ServiceDependencies instance
|
203
|
-
"""
|
204
|
-
return ServiceDependencies(
|
205
|
-
config=self.config,
|
206
|
-
logger=self.logger,
|
207
|
-
operation_id=operation_id or str(uuid.uuid4()),
|
208
|
-
project_root=project_root,
|
209
|
-
output_directory=output_directory,
|
210
|
-
context_data=context_data
|
211
|
-
)
|
212
|
-
|
213
|
-
def create_result(
|
214
|
-
self,
|
215
|
-
operation_name: str,
|
216
|
-
operation_id: Optional[str] = None
|
217
|
-
) -> ServiceResult[OutputT]:
|
218
|
-
"""Create a new service result.
|
219
|
-
|
220
|
-
Args:
|
221
|
-
operation_name: Name of the operation
|
222
|
-
operation_id: Optional operation ID
|
223
|
-
|
224
|
-
Returns:
|
225
|
-
ServiceResult instance
|
226
|
-
"""
|
227
|
-
op_id = operation_id or str(uuid.uuid4())
|
228
|
-
result = ServiceResult[OutputT](
|
229
|
-
operation_id=op_id,
|
230
|
-
service_name=self.service_name,
|
231
|
-
operation_name=operation_name,
|
232
|
-
success=False,
|
233
|
-
start_time=datetime.now(timezone.utc)
|
234
|
-
)
|
235
|
-
|
236
|
-
# Track active operation
|
237
|
-
self._active_operations[op_id] = result
|
238
|
-
|
239
|
-
return result
|
240
|
-
|
241
|
-
def complete_operation(self, result: ServiceResult[OutputT]) -> None:
|
242
|
-
"""Complete an operation and remove from active tracking.
|
243
|
-
|
244
|
-
Args:
|
245
|
-
result: The completed service result
|
246
|
-
"""
|
247
|
-
# Remove from active operations
|
248
|
-
self._active_operations.pop(result.operation_id, None)
|
249
|
-
|
250
|
-
# Log completion
|
251
|
-
self.logger.info(
|
252
|
-
f"Operation {result.operation_name} completed",
|
253
|
-
operation_id=result.operation_id,
|
254
|
-
success=result.success,
|
255
|
-
execution_time_seconds=result.execution_time_seconds,
|
256
|
-
has_warnings=len(result.warnings) > 0
|
257
|
-
)
|
258
|
-
|
259
|
-
async def execute_with_result(
|
260
|
-
self,
|
261
|
-
operation_name: str,
|
262
|
-
operation_func: callable,
|
263
|
-
dependencies: ServiceDependencies,
|
264
|
-
*args: Any,
|
265
|
-
**kwargs: Any
|
266
|
-
) -> ServiceResult[OutputT]:
|
267
|
-
"""Execute an operation with automatic result tracking.
|
268
|
-
|
269
|
-
Args:
|
270
|
-
operation_name: Name of the operation
|
271
|
-
operation_func: Function to execute
|
272
|
-
dependencies: Service dependencies
|
273
|
-
*args: Positional arguments for operation_func
|
274
|
-
**kwargs: Keyword arguments for operation_func
|
275
|
-
|
276
|
-
Returns:
|
277
|
-
ServiceResult with operation outcome
|
278
|
-
"""
|
279
|
-
result = self.create_result(operation_name, dependencies.operation_id)
|
280
|
-
|
281
|
-
try:
|
282
|
-
# Execute operation
|
283
|
-
if asyncio.iscoroutinefunction(operation_func):
|
284
|
-
data = await operation_func(dependencies, *args, **kwargs)
|
285
|
-
else:
|
286
|
-
data = operation_func(dependencies, *args, **kwargs)
|
287
|
-
|
288
|
-
# Mark as completed
|
289
|
-
result.mark_completed(data)
|
290
|
-
|
291
|
-
except Exception as e:
|
292
|
-
# Mark as failed
|
293
|
-
error_msg = f"Operation {operation_name} failed: {e}"
|
294
|
-
result.mark_failed(error_msg, {"exception_type": type(e).__name__})
|
295
|
-
|
296
|
-
# Log error
|
297
|
-
dependencies.log_error(error_msg, e)
|
298
|
-
|
299
|
-
# Re-raise if it's a service error, otherwise wrap it
|
300
|
-
if isinstance(e, ServiceError):
|
301
|
-
raise
|
302
|
-
else:
|
303
|
-
raise ServiceError(
|
304
|
-
error_msg,
|
305
|
-
service_name=self.service_name,
|
306
|
-
operation=operation_name,
|
307
|
-
cause=e
|
308
|
-
) from e
|
309
|
-
|
310
|
-
finally:
|
311
|
-
# Complete operation tracking
|
312
|
-
self.complete_operation(result)
|
313
|
-
|
314
|
-
return result
|
315
|
-
|
316
|
-
@abstractmethod
|
317
|
-
async def process(self, input_data: InputT, dependencies: ServiceDependencies) -> OutputT:
|
318
|
-
"""
|
319
|
-
Process input data and return output.
|
320
|
-
|
321
|
-
This is the main method that subclasses must implement.
|
322
|
-
|
323
|
-
Args:
|
324
|
-
input_data: Input data for processing
|
325
|
-
dependencies: Service dependencies
|
326
|
-
|
327
|
-
Returns:
|
328
|
-
Processed output data
|
329
|
-
"""
|
330
|
-
pass
|
331
|
-
|
332
|
-
async def run(
|
333
|
-
self,
|
334
|
-
input_data: InputT,
|
335
|
-
operation_id: Optional[str] = None,
|
336
|
-
project_root: Optional[Path] = None,
|
337
|
-
output_directory: Optional[Path] = None,
|
338
|
-
**context_data: Any
|
339
|
-
) -> ServiceResult[OutputT]:
|
340
|
-
"""
|
341
|
-
Run the service with input data and return a result.
|
342
|
-
|
343
|
-
Args:
|
344
|
-
input_data: Input data for processing
|
345
|
-
operation_id: Optional operation ID
|
346
|
-
project_root: Optional project root directory
|
347
|
-
output_directory: Optional output directory
|
348
|
-
**context_data: Additional context data
|
349
|
-
|
350
|
-
Returns:
|
351
|
-
ServiceResult with operation outcome
|
352
|
-
"""
|
353
|
-
# Create dependencies
|
354
|
-
dependencies = self.create_dependencies(
|
355
|
-
operation_id=operation_id,
|
356
|
-
project_root=project_root,
|
357
|
-
output_directory=output_directory,
|
358
|
-
**context_data
|
359
|
-
)
|
360
|
-
|
361
|
-
# Execute with result tracking
|
362
|
-
return await self.execute_with_result(
|
363
|
-
"process",
|
364
|
-
self.process,
|
365
|
-
dependencies,
|
366
|
-
input_data
|
367
|
-
)
|
368
|
-
|
369
|
-
def get_active_operations(self) -> Dict[str, ServiceResult]:
|
370
|
-
"""Get currently active operations."""
|
371
|
-
return self._active_operations.copy()
|
372
|
-
|
373
|
-
def get_service_status(self) -> Dict[str, Any]:
|
374
|
-
"""Get service status information."""
|
375
|
-
return {
|
376
|
-
"service_name": self.service_name,
|
377
|
-
"active_operations_count": len(self._active_operations),
|
378
|
-
"active_operation_ids": list(self._active_operations.keys()),
|
379
|
-
"config_loaded": self.config is not None,
|
380
|
-
"logger_configured": self.logger is not None
|
381
|
-
}
|
382
|
-
|
383
|
-
def validate_input(self, input_data: InputT) -> None:
|
384
|
-
"""
|
385
|
-
Validate input data before processing.
|
386
|
-
|
387
|
-
Override this method to add custom validation logic.
|
388
|
-
|
389
|
-
Args:
|
390
|
-
input_data: Input data to validate
|
391
|
-
|
392
|
-
Raises:
|
393
|
-
ValidationError: If input data is invalid
|
394
|
-
"""
|
395
|
-
if input_data is None:
|
396
|
-
raise ValidationError(
|
397
|
-
"Input data cannot be None",
|
398
|
-
validation_type="input_validation"
|
399
|
-
)
|
400
|
-
|
401
|
-
def __repr__(self) -> str:
|
402
|
-
"""String representation of the service."""
|
403
|
-
return f"{self.__class__.__name__}(service_name='{self.service_name}')"
|
404
|
-
|
405
|
-
|
406
|
-
def create_service_dependencies(
|
407
|
-
config: AgentConfig,
|
408
|
-
service_name: str,
|
409
|
-
operation_id: Optional[str] = None,
|
410
|
-
project_root: Optional[Path] = None,
|
411
|
-
output_directory: Optional[Path] = None,
|
412
|
-
**context_data: Any
|
413
|
-
) -> ServiceDependencies:
|
414
|
-
"""
|
415
|
-
Factory function to create service dependencies.
|
416
|
-
|
417
|
-
Args:
|
418
|
-
config: Agent configuration
|
419
|
-
service_name: Name of the service
|
420
|
-
operation_id: Optional operation ID
|
421
|
-
project_root: Optional project root directory
|
422
|
-
output_directory: Optional output directory
|
423
|
-
**context_data: Additional context data
|
424
|
-
|
425
|
-
Returns:
|
426
|
-
ServiceDependencies instance
|
427
|
-
"""
|
428
|
-
logger = get_logger(f"services.{service_name}")
|
429
|
-
|
430
|
-
return ServiceDependencies(
|
431
|
-
config=config,
|
432
|
-
logger=logger,
|
433
|
-
operation_id=operation_id or str(uuid.uuid4()),
|
434
|
-
project_root=project_root,
|
435
|
-
output_directory=output_directory,
|
436
|
-
context_data=context_data
|
437
|
-
)
|
@@ -1,34 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Context Builder Module for Django App Agent.
|
3
|
-
|
4
|
-
This module provides comprehensive context building capabilities
|
5
|
-
for AI agents, including project analysis, pattern identification,
|
6
|
-
and intelligent context optimization.
|
7
|
-
|
8
|
-
Components:
|
9
|
-
- models: Data models for requests and results
|
10
|
-
- pattern_analyzer: Architectural pattern analysis
|
11
|
-
- code_extractor: Code sample extraction
|
12
|
-
- context_generator: Feature-specific context generation
|
13
|
-
- main: Main orchestration service
|
14
|
-
"""
|
15
|
-
|
16
|
-
from .main import ContextBuilderService
|
17
|
-
from .models import ContextBuildRequest, ContextResult
|
18
|
-
from .pattern_analyzer import PatternAnalyzer
|
19
|
-
from .code_extractor import CodeExtractor
|
20
|
-
from .context_generator import ContextGenerator
|
21
|
-
|
22
|
-
__all__ = [
|
23
|
-
# Main service
|
24
|
-
"ContextBuilderService",
|
25
|
-
|
26
|
-
# Data models
|
27
|
-
"ContextBuildRequest",
|
28
|
-
"ContextResult",
|
29
|
-
|
30
|
-
# Core components
|
31
|
-
"PatternAnalyzer",
|
32
|
-
"CodeExtractor",
|
33
|
-
"ContextGenerator",
|
34
|
-
]
|