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