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,356 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Session Manager for Intelligent Questioning Service.
|
3
|
-
|
4
|
-
This module manages questioning sessions, including creation,
|
5
|
-
progress tracking, and completion handling.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import List, Dict, Any, Optional
|
9
|
-
import uuid
|
10
|
-
from datetime import datetime, timezone
|
11
|
-
|
12
|
-
from pydantic import BaseModel, Field
|
13
|
-
|
14
|
-
from ...core.config import AgentConfig
|
15
|
-
from ...models.context import ProjectContext
|
16
|
-
from ..base import ServiceDependencies
|
17
|
-
from .models import (
|
18
|
-
QuestioningRequest, QuestioningSession, ContextualQuestion,
|
19
|
-
QuestionResponse, QuestioningResult
|
20
|
-
)
|
21
|
-
|
22
|
-
|
23
|
-
class SessionManager(BaseModel):
|
24
|
-
"""Manages questioning sessions and their lifecycle."""
|
25
|
-
|
26
|
-
config: AgentConfig = Field(description="Agent configuration")
|
27
|
-
|
28
|
-
# Session storage (in production, this would be a database)
|
29
|
-
active_sessions: Dict[str, QuestioningSession] = Field(
|
30
|
-
default_factory=dict,
|
31
|
-
description="Active questioning sessions"
|
32
|
-
)
|
33
|
-
|
34
|
-
async def create_session(
|
35
|
-
self,
|
36
|
-
request: QuestioningRequest,
|
37
|
-
questions: List[ContextualQuestion],
|
38
|
-
project_context: ProjectContext,
|
39
|
-
dependencies: ServiceDependencies
|
40
|
-
) -> QuestioningSession:
|
41
|
-
"""Create a new questioning session."""
|
42
|
-
session_id = str(uuid.uuid4())
|
43
|
-
|
44
|
-
session = QuestioningSession(
|
45
|
-
session_id=session_id,
|
46
|
-
questions=questions,
|
47
|
-
project_context=project_context,
|
48
|
-
user_intent=request.user_intent,
|
49
|
-
created_at=datetime.now(timezone.utc)
|
50
|
-
)
|
51
|
-
|
52
|
-
# Store session
|
53
|
-
self.active_sessions[session_id] = session
|
54
|
-
|
55
|
-
dependencies.log_operation(
|
56
|
-
"Questioning session created",
|
57
|
-
session_id=session_id,
|
58
|
-
questions_count=len(questions),
|
59
|
-
user_intent=request.user_intent
|
60
|
-
)
|
61
|
-
|
62
|
-
return session
|
63
|
-
|
64
|
-
async def add_response(
|
65
|
-
self,
|
66
|
-
session_id: str,
|
67
|
-
question_id: str,
|
68
|
-
answer: str,
|
69
|
-
confidence: float,
|
70
|
-
dependencies: ServiceDependencies
|
71
|
-
) -> Optional[QuestioningSession]:
|
72
|
-
"""Add a response to an existing session."""
|
73
|
-
session = self.active_sessions.get(session_id)
|
74
|
-
if not session:
|
75
|
-
dependencies.log_error(f"Session not found: {session_id}")
|
76
|
-
return None
|
77
|
-
|
78
|
-
# Validate question exists
|
79
|
-
question = self._find_question_by_id(session.questions, question_id)
|
80
|
-
if not question:
|
81
|
-
dependencies.log_error(f"Question not found: {question_id}")
|
82
|
-
return None
|
83
|
-
|
84
|
-
# Create response
|
85
|
-
response = QuestionResponse(
|
86
|
-
question_id=question_id,
|
87
|
-
answer=answer,
|
88
|
-
confidence=confidence,
|
89
|
-
timestamp=datetime.now(timezone.utc)
|
90
|
-
)
|
91
|
-
|
92
|
-
# Add to session
|
93
|
-
session.responses.append(response)
|
94
|
-
session.current_question_index = len(session.responses)
|
95
|
-
|
96
|
-
# Check if session is completed
|
97
|
-
if len(session.responses) >= len(session.questions):
|
98
|
-
session.is_completed = True
|
99
|
-
session.completed_at = datetime.now(timezone.utc)
|
100
|
-
|
101
|
-
dependencies.log_operation(
|
102
|
-
"Response added to session",
|
103
|
-
session_id=session_id,
|
104
|
-
question_id=question_id,
|
105
|
-
completion_percentage=session.completion_percentage,
|
106
|
-
is_completed=session.is_completed
|
107
|
-
)
|
108
|
-
|
109
|
-
return session
|
110
|
-
|
111
|
-
async def get_session(
|
112
|
-
self,
|
113
|
-
session_id: str,
|
114
|
-
dependencies: ServiceDependencies
|
115
|
-
) -> Optional[QuestioningSession]:
|
116
|
-
"""Get an existing session."""
|
117
|
-
session = self.active_sessions.get(session_id)
|
118
|
-
|
119
|
-
if not session:
|
120
|
-
dependencies.log_error(f"Session not found: {session_id}")
|
121
|
-
|
122
|
-
return session
|
123
|
-
|
124
|
-
async def get_next_question(
|
125
|
-
self,
|
126
|
-
session_id: str,
|
127
|
-
dependencies: ServiceDependencies
|
128
|
-
) -> Optional[ContextualQuestion]:
|
129
|
-
"""Get the next unanswered question in a session."""
|
130
|
-
session = self.active_sessions.get(session_id)
|
131
|
-
if not session:
|
132
|
-
return None
|
133
|
-
|
134
|
-
if session.is_completed:
|
135
|
-
return None
|
136
|
-
|
137
|
-
# Find next unanswered question
|
138
|
-
answered_question_ids = {r.question_id for r in session.responses}
|
139
|
-
|
140
|
-
for question in session.questions:
|
141
|
-
if question.id not in answered_question_ids:
|
142
|
-
return question
|
143
|
-
|
144
|
-
return None
|
145
|
-
|
146
|
-
async def complete_session(
|
147
|
-
self,
|
148
|
-
session_id: str,
|
149
|
-
dependencies: ServiceDependencies
|
150
|
-
) -> Optional[QuestioningSession]:
|
151
|
-
"""Mark a session as completed."""
|
152
|
-
session = self.active_sessions.get(session_id)
|
153
|
-
if not session:
|
154
|
-
return None
|
155
|
-
|
156
|
-
session.is_completed = True
|
157
|
-
session.completed_at = datetime.now(timezone.utc)
|
158
|
-
|
159
|
-
dependencies.log_operation(
|
160
|
-
"Session completed",
|
161
|
-
session_id=session_id,
|
162
|
-
total_responses=len(session.responses),
|
163
|
-
completion_percentage=session.completion_percentage
|
164
|
-
)
|
165
|
-
|
166
|
-
return session
|
167
|
-
|
168
|
-
async def cleanup_session(
|
169
|
-
self,
|
170
|
-
session_id: str,
|
171
|
-
dependencies: ServiceDependencies
|
172
|
-
) -> bool:
|
173
|
-
"""Remove a session from active sessions."""
|
174
|
-
if session_id in self.active_sessions:
|
175
|
-
del self.active_sessions[session_id]
|
176
|
-
dependencies.log_operation(f"Session cleaned up: {session_id}")
|
177
|
-
return True
|
178
|
-
|
179
|
-
return False
|
180
|
-
|
181
|
-
def calculate_confidence_score(
|
182
|
-
self,
|
183
|
-
session: QuestioningSession
|
184
|
-
) -> float:
|
185
|
-
"""Calculate overall confidence score for a session."""
|
186
|
-
if not session.responses:
|
187
|
-
return 0.0
|
188
|
-
|
189
|
-
# Weight confidence by question impact
|
190
|
-
impact_weights = {"critical": 1.0, "high": 0.8, "medium": 0.6, "low": 0.4}
|
191
|
-
|
192
|
-
weighted_confidence = 0.0
|
193
|
-
total_weight = 0.0
|
194
|
-
|
195
|
-
for response in session.responses:
|
196
|
-
question = self._find_question_by_id(session.questions, response.question_id)
|
197
|
-
if question:
|
198
|
-
weight = impact_weights.get(question.impact_level, 0.6)
|
199
|
-
weighted_confidence += response.confidence * weight
|
200
|
-
total_weight += weight
|
201
|
-
|
202
|
-
return weighted_confidence / total_weight if total_weight > 0 else 0.0
|
203
|
-
|
204
|
-
async def gather_agent_insights(
|
205
|
-
self,
|
206
|
-
session: QuestioningSession,
|
207
|
-
dependencies: ServiceDependencies
|
208
|
-
) -> Dict[str, Any]:
|
209
|
-
"""Gather insights from AI agents based on session responses."""
|
210
|
-
insights = {
|
211
|
-
"response_analysis": {},
|
212
|
-
"pattern_detection": {},
|
213
|
-
"recommendations": [],
|
214
|
-
"confidence_assessment": {}
|
215
|
-
}
|
216
|
-
|
217
|
-
try:
|
218
|
-
# Analyze response patterns
|
219
|
-
insights["response_analysis"] = self._analyze_response_patterns(session)
|
220
|
-
|
221
|
-
# Detect architectural patterns
|
222
|
-
insights["pattern_detection"] = self._detect_architectural_patterns(session)
|
223
|
-
|
224
|
-
# Generate recommendations
|
225
|
-
insights["recommendations"] = self._generate_recommendations(session)
|
226
|
-
|
227
|
-
# Assess confidence
|
228
|
-
insights["confidence_assessment"] = {
|
229
|
-
"overall_confidence": self.calculate_confidence_score(session),
|
230
|
-
"low_confidence_areas": self._identify_low_confidence_areas(session),
|
231
|
-
"high_confidence_areas": self._identify_high_confidence_areas(session)
|
232
|
-
}
|
233
|
-
|
234
|
-
except Exception as e:
|
235
|
-
dependencies.log_error("Failed to gather agent insights", e)
|
236
|
-
|
237
|
-
return insights
|
238
|
-
|
239
|
-
def _find_question_by_id(
|
240
|
-
self,
|
241
|
-
questions: List[ContextualQuestion],
|
242
|
-
question_id: str
|
243
|
-
) -> Optional[ContextualQuestion]:
|
244
|
-
"""Find question by ID."""
|
245
|
-
for question in questions:
|
246
|
-
if question.id == question_id:
|
247
|
-
return question
|
248
|
-
return None
|
249
|
-
|
250
|
-
def _analyze_response_patterns(
|
251
|
-
self,
|
252
|
-
session: QuestioningSession
|
253
|
-
) -> Dict[str, Any]:
|
254
|
-
"""Analyze patterns in user responses."""
|
255
|
-
patterns = {
|
256
|
-
"response_length_avg": 0.0,
|
257
|
-
"confidence_avg": 0.0,
|
258
|
-
"yes_no_ratio": 0.0,
|
259
|
-
"detailed_responses": 0
|
260
|
-
}
|
261
|
-
|
262
|
-
if not session.responses:
|
263
|
-
return patterns
|
264
|
-
|
265
|
-
# Calculate averages
|
266
|
-
total_length = sum(len(r.answer) for r in session.responses)
|
267
|
-
total_confidence = sum(r.confidence for r in session.responses)
|
268
|
-
|
269
|
-
patterns["response_length_avg"] = total_length / len(session.responses)
|
270
|
-
patterns["confidence_avg"] = total_confidence / len(session.responses)
|
271
|
-
|
272
|
-
# Count yes/no responses
|
273
|
-
yes_no_count = sum(
|
274
|
-
1 for r in session.responses
|
275
|
-
if r.answer.lower() in ["yes", "no", "y", "n", "true", "false"]
|
276
|
-
)
|
277
|
-
patterns["yes_no_ratio"] = yes_no_count / len(session.responses)
|
278
|
-
|
279
|
-
# Count detailed responses (>20 characters)
|
280
|
-
patterns["detailed_responses"] = sum(
|
281
|
-
1 for r in session.responses if len(r.answer) > 20
|
282
|
-
)
|
283
|
-
|
284
|
-
return patterns
|
285
|
-
|
286
|
-
def _detect_architectural_patterns(
|
287
|
-
self,
|
288
|
-
session: QuestioningSession
|
289
|
-
) -> Dict[str, Any]:
|
290
|
-
"""Detect architectural patterns from responses."""
|
291
|
-
patterns = {
|
292
|
-
"api_focused": False,
|
293
|
-
"admin_heavy": False,
|
294
|
-
"user_centric": False,
|
295
|
-
"data_intensive": False
|
296
|
-
}
|
297
|
-
|
298
|
-
# Analyze responses for architectural indicators
|
299
|
-
all_answers = " ".join(r.answer.lower() for r in session.responses)
|
300
|
-
|
301
|
-
patterns["api_focused"] = "api" in all_answers or "integration" in all_answers
|
302
|
-
patterns["admin_heavy"] = "admin" in all_answers or "management" in all_answers
|
303
|
-
patterns["user_centric"] = "user" in all_answers or "authentication" in all_answers
|
304
|
-
patterns["data_intensive"] = "data" in all_answers or "database" in all_answers
|
305
|
-
|
306
|
-
return patterns
|
307
|
-
|
308
|
-
def _generate_recommendations(
|
309
|
-
self,
|
310
|
-
session: QuestioningSession
|
311
|
-
) -> List[str]:
|
312
|
-
"""Generate development recommendations based on responses."""
|
313
|
-
recommendations = []
|
314
|
-
|
315
|
-
# Analyze confidence levels
|
316
|
-
avg_confidence = sum(r.confidence for r in session.responses) / len(session.responses) if session.responses else 0
|
317
|
-
|
318
|
-
if avg_confidence < 0.7:
|
319
|
-
recommendations.append("Consider additional planning phase due to low confidence in requirements")
|
320
|
-
|
321
|
-
# Analyze response patterns
|
322
|
-
detailed_count = sum(1 for r in session.responses if len(r.answer) > 50)
|
323
|
-
if detailed_count > len(session.responses) * 0.7:
|
324
|
-
recommendations.append("User provided detailed requirements - consider iterative development approach")
|
325
|
-
|
326
|
-
return recommendations
|
327
|
-
|
328
|
-
def _identify_low_confidence_areas(
|
329
|
-
self,
|
330
|
-
session: QuestioningSession
|
331
|
-
) -> List[str]:
|
332
|
-
"""Identify areas where user expressed low confidence."""
|
333
|
-
low_confidence_areas = []
|
334
|
-
|
335
|
-
for response in session.responses:
|
336
|
-
if response.confidence < 0.6:
|
337
|
-
question = self._find_question_by_id(session.questions, response.question_id)
|
338
|
-
if question:
|
339
|
-
low_confidence_areas.append(question.text)
|
340
|
-
|
341
|
-
return low_confidence_areas
|
342
|
-
|
343
|
-
def _identify_high_confidence_areas(
|
344
|
-
self,
|
345
|
-
session: QuestioningSession
|
346
|
-
) -> List[str]:
|
347
|
-
"""Identify areas where user expressed high confidence."""
|
348
|
-
high_confidence_areas = []
|
349
|
-
|
350
|
-
for response in session.responses:
|
351
|
-
if response.confidence > 0.8:
|
352
|
-
question = self._find_question_by_id(session.questions, response.question_id)
|
353
|
-
if question:
|
354
|
-
high_confidence_areas.append(question.text)
|
355
|
-
|
356
|
-
return high_confidence_areas
|
@@ -1,332 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Report Service for Django App Agent Module.
|
3
|
-
|
4
|
-
This service generates comprehensive reports for application generation
|
5
|
-
processes, including detailed logs, metrics, and documentation.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from typing import List, Dict, Any, Optional
|
9
|
-
from pathlib import Path
|
10
|
-
from datetime import datetime, timezone
|
11
|
-
import json
|
12
|
-
|
13
|
-
from pydantic import BaseModel, Field, ConfigDict
|
14
|
-
|
15
|
-
from .base import BaseService, ServiceDependencies
|
16
|
-
from ..models.responses import AppGenerationResult, QualityMetrics, GeneratedFile
|
17
|
-
from ..core.exceptions import FileSystemError
|
18
|
-
|
19
|
-
|
20
|
-
class ReportRequest(BaseModel):
|
21
|
-
"""Request for report generation."""
|
22
|
-
|
23
|
-
model_config = ConfigDict(extra='forbid', validate_assignment=True)
|
24
|
-
|
25
|
-
generation_result: AppGenerationResult = Field(description="Application generation result")
|
26
|
-
report_formats: List[str] = Field(
|
27
|
-
default_factory=lambda: ["markdown", "json"],
|
28
|
-
description="Report formats to generate"
|
29
|
-
)
|
30
|
-
include_code_samples: bool = Field(default=True, description="Whether to include code samples")
|
31
|
-
include_metrics: bool = Field(default=True, description="Whether to include quality metrics")
|
32
|
-
output_directory: Optional[Path] = Field(default=None, description="Custom output directory")
|
33
|
-
|
34
|
-
|
35
|
-
class ReportResult(BaseModel):
|
36
|
-
"""Result of report generation."""
|
37
|
-
|
38
|
-
model_config = ConfigDict(extra='forbid', validate_assignment=True)
|
39
|
-
|
40
|
-
generated_reports: List[str] = Field(description="Paths to generated report files")
|
41
|
-
report_summary: Dict[str, Any] = Field(description="Summary of the report generation")
|
42
|
-
total_size_bytes: int = Field(default=0, description="Total size of generated reports")
|
43
|
-
|
44
|
-
|
45
|
-
class ReportService(BaseService[ReportRequest, ReportResult]):
|
46
|
-
"""
|
47
|
-
Service for generating comprehensive reports of application generation processes.
|
48
|
-
|
49
|
-
Provides:
|
50
|
-
- Markdown reports with detailed information
|
51
|
-
- JSON reports for programmatic access
|
52
|
-
- Code sample inclusion
|
53
|
-
- Quality metrics visualization
|
54
|
-
- Process documentation
|
55
|
-
"""
|
56
|
-
|
57
|
-
def __init__(self, config):
|
58
|
-
"""Initialize report service."""
|
59
|
-
super().__init__("report", config)
|
60
|
-
|
61
|
-
async def process(
|
62
|
-
self,
|
63
|
-
request: ReportRequest,
|
64
|
-
dependencies: ServiceDependencies
|
65
|
-
) -> ReportResult:
|
66
|
-
"""
|
67
|
-
Process report generation request.
|
68
|
-
|
69
|
-
Args:
|
70
|
-
request: Report generation request
|
71
|
-
dependencies: Service dependencies
|
72
|
-
|
73
|
-
Returns:
|
74
|
-
ReportResult with generated reports
|
75
|
-
"""
|
76
|
-
dependencies.log_operation(
|
77
|
-
f"Generating reports for app '{request.generation_result.app_name}'",
|
78
|
-
formats=request.report_formats,
|
79
|
-
include_code_samples=request.include_code_samples,
|
80
|
-
include_metrics=request.include_metrics
|
81
|
-
)
|
82
|
-
|
83
|
-
try:
|
84
|
-
generated_reports = []
|
85
|
-
total_size = 0
|
86
|
-
|
87
|
-
# Determine output directory
|
88
|
-
output_dir = request.output_directory or dependencies.get_output_path()
|
89
|
-
report_dir = output_dir / request.generation_result.app_name / "@report"
|
90
|
-
report_dir.mkdir(parents=True, exist_ok=True)
|
91
|
-
|
92
|
-
# Generate reports in requested formats
|
93
|
-
for format_type in request.report_formats:
|
94
|
-
if format_type == "markdown":
|
95
|
-
report_path = await self._generate_markdown_report(
|
96
|
-
request, report_dir, dependencies
|
97
|
-
)
|
98
|
-
elif format_type == "json":
|
99
|
-
report_path = await self._generate_json_report(
|
100
|
-
request, report_dir, dependencies
|
101
|
-
)
|
102
|
-
else:
|
103
|
-
dependencies.logger.warning(f"Unknown report format: {format_type}")
|
104
|
-
continue
|
105
|
-
|
106
|
-
if report_path and report_path.exists():
|
107
|
-
generated_reports.append(str(report_path))
|
108
|
-
total_size += report_path.stat().st_size
|
109
|
-
|
110
|
-
# Generate summary
|
111
|
-
summary = {
|
112
|
-
"app_name": request.generation_result.app_name,
|
113
|
-
"generation_status": request.generation_result.status,
|
114
|
-
"reports_generated": len(generated_reports),
|
115
|
-
"formats": request.report_formats,
|
116
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
117
|
-
"total_files_generated": len(request.generation_result.generated_files)
|
118
|
-
}
|
119
|
-
|
120
|
-
result = ReportResult(
|
121
|
-
generated_reports=generated_reports,
|
122
|
-
report_summary=summary,
|
123
|
-
total_size_bytes=total_size
|
124
|
-
)
|
125
|
-
|
126
|
-
dependencies.log_operation(
|
127
|
-
"Report generation completed successfully",
|
128
|
-
reports_count=len(generated_reports),
|
129
|
-
total_size_kb=total_size // 1024
|
130
|
-
)
|
131
|
-
|
132
|
-
return result
|
133
|
-
|
134
|
-
except Exception as e:
|
135
|
-
dependencies.log_error("Report generation failed", e)
|
136
|
-
raise
|
137
|
-
|
138
|
-
async def _generate_markdown_report(
|
139
|
-
self,
|
140
|
-
request: ReportRequest,
|
141
|
-
output_dir: Path,
|
142
|
-
dependencies: ServiceDependencies
|
143
|
-
) -> Optional[Path]:
|
144
|
-
"""Generate markdown report."""
|
145
|
-
try:
|
146
|
-
result = request.generation_result
|
147
|
-
report_path = output_dir / "GENERATION_REPORT.md"
|
148
|
-
|
149
|
-
# Build markdown content
|
150
|
-
content = self._build_markdown_content(request, dependencies)
|
151
|
-
|
152
|
-
# Write report
|
153
|
-
report_path.write_text(content, encoding='utf-8')
|
154
|
-
|
155
|
-
return report_path
|
156
|
-
|
157
|
-
except Exception as e:
|
158
|
-
dependencies.log_error("Failed to generate markdown report", e)
|
159
|
-
return None
|
160
|
-
|
161
|
-
async def _generate_json_report(
|
162
|
-
self,
|
163
|
-
request: ReportRequest,
|
164
|
-
output_dir: Path,
|
165
|
-
dependencies: ServiceDependencies
|
166
|
-
) -> Optional[Path]:
|
167
|
-
"""Generate JSON report."""
|
168
|
-
try:
|
169
|
-
result = request.generation_result
|
170
|
-
report_path = output_dir / "generation_report.json"
|
171
|
-
|
172
|
-
# Build JSON data
|
173
|
-
report_data = {
|
174
|
-
"metadata": {
|
175
|
-
"generated_at": datetime.now(timezone.utc).isoformat(),
|
176
|
-
"generator_version": "0.1.0",
|
177
|
-
"report_format": "json"
|
178
|
-
},
|
179
|
-
"application": {
|
180
|
-
"name": result.app_name,
|
181
|
-
"status": result.status,
|
182
|
-
"message": result.message,
|
183
|
-
"duration_seconds": result.duration_seconds
|
184
|
-
},
|
185
|
-
"generation_process": {
|
186
|
-
"files_generated": len(result.generated_files),
|
187
|
-
"errors": result.errors,
|
188
|
-
"warnings": result.warnings,
|
189
|
-
"ai_dialogue_log": result.ai_dialogue_log if request.include_code_samples else []
|
190
|
-
},
|
191
|
-
"quality_metrics": result.quality_metrics.model_dump() if result.quality_metrics and request.include_metrics else None,
|
192
|
-
"generated_files": [
|
193
|
-
{
|
194
|
-
"path": f.path,
|
195
|
-
"type": f.file_type,
|
196
|
-
"description": f.description,
|
197
|
-
"size_bytes": f.size_bytes,
|
198
|
-
"content": f.content if request.include_code_samples else None
|
199
|
-
}
|
200
|
-
for f in result.generated_files
|
201
|
-
]
|
202
|
-
}
|
203
|
-
|
204
|
-
# Write JSON report
|
205
|
-
with open(report_path, 'w', encoding='utf-8') as f:
|
206
|
-
json.dump(report_data, f, indent=2, ensure_ascii=False)
|
207
|
-
|
208
|
-
return report_path
|
209
|
-
|
210
|
-
except Exception as e:
|
211
|
-
dependencies.log_error("Failed to generate JSON report", e)
|
212
|
-
return None
|
213
|
-
|
214
|
-
def _build_markdown_content(
|
215
|
-
self,
|
216
|
-
request: ReportRequest,
|
217
|
-
dependencies: ServiceDependencies
|
218
|
-
) -> str:
|
219
|
-
"""Build markdown report content."""
|
220
|
-
result = request.generation_result
|
221
|
-
|
222
|
-
content = f"""# Application Generation Report
|
223
|
-
|
224
|
-
## 📋 Summary
|
225
|
-
|
226
|
-
**Application Name**: `{result.app_name}`
|
227
|
-
**Status**: {result.status.upper()}
|
228
|
-
**Generated**: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')}
|
229
|
-
**Duration**: {result.duration_seconds:.2f} seconds
|
230
|
-
|
231
|
-
{result.message}
|
232
|
-
|
233
|
-
## 📊 Generation Statistics
|
234
|
-
|
235
|
-
- **Files Generated**: {len(result.generated_files)}
|
236
|
-
- **Errors**: {len(result.errors)}
|
237
|
-
- **Warnings**: {len(result.warnings)}
|
238
|
-
|
239
|
-
"""
|
240
|
-
|
241
|
-
# Add errors section if any
|
242
|
-
if result.errors:
|
243
|
-
content += "## ❌ Errors\n\n"
|
244
|
-
for error in result.errors:
|
245
|
-
content += f"- {error}\n"
|
246
|
-
content += "\n"
|
247
|
-
|
248
|
-
# Add warnings section if any
|
249
|
-
if result.warnings:
|
250
|
-
content += "## ⚠️ Warnings\n\n"
|
251
|
-
for warning in result.warnings:
|
252
|
-
content += f"- {warning}\n"
|
253
|
-
content += "\n"
|
254
|
-
|
255
|
-
# Add quality metrics if available and requested
|
256
|
-
if result.quality_metrics and request.include_metrics:
|
257
|
-
metrics = result.quality_metrics
|
258
|
-
content += f"""## 📈 Quality Metrics
|
259
|
-
|
260
|
-
- **Code Readability**: {metrics.code_readability_score:.2f}/1.0
|
261
|
-
- **Maintainability**: {metrics.maintainability_score:.2f}/1.0
|
262
|
-
- **Type Hint Completeness**: {metrics.type_hint_completeness:.2f}/1.0
|
263
|
-
- **Pydantic Compliance**: {metrics.pydantic_compliance_score:.2f}/1.0
|
264
|
-
- **Test Coverage**: {metrics.test_coverage_percentage:.1f}%
|
265
|
-
- **Security Vulnerabilities**: {metrics.security_vulnerabilities_found}
|
266
|
-
- **Performance Issues**: {metrics.performance_bottlenecks_found}
|
267
|
-
|
268
|
-
"""
|
269
|
-
|
270
|
-
# Add generated files section
|
271
|
-
content += "## 📁 Generated Files\n\n"
|
272
|
-
|
273
|
-
# Group files by type
|
274
|
-
files_by_type = {}
|
275
|
-
for file in result.generated_files:
|
276
|
-
file_type = file.file_type
|
277
|
-
if file_type not in files_by_type:
|
278
|
-
files_by_type[file_type] = []
|
279
|
-
files_by_type[file_type].append(file)
|
280
|
-
|
281
|
-
for file_type, files in files_by_type.items():
|
282
|
-
content += f"### {file_type.title()} Files\n\n"
|
283
|
-
for file in files:
|
284
|
-
content += f"- **{file.path}**"
|
285
|
-
if file.description:
|
286
|
-
content += f" - {file.description}"
|
287
|
-
content += f" ({file.size_bytes} bytes)\n"
|
288
|
-
content += "\n"
|
289
|
-
|
290
|
-
# Add code samples if requested
|
291
|
-
if request.include_code_samples and result.generated_files:
|
292
|
-
content += "## 💻 Code Samples\n\n"
|
293
|
-
|
294
|
-
# Show a few key files
|
295
|
-
key_files = [f for f in result.generated_files if f.file_type == "python"][:3]
|
296
|
-
|
297
|
-
for file in key_files:
|
298
|
-
content += f"### {file.path}\n\n"
|
299
|
-
if file.description:
|
300
|
-
content += f"{file.description}\n\n"
|
301
|
-
|
302
|
-
content += f"```python\n{file.content}\n```\n\n"
|
303
|
-
|
304
|
-
# Add AI dialogue log if available and requested
|
305
|
-
if result.ai_dialogue_log and request.include_code_samples:
|
306
|
-
content += "## 🤖 AI Generation Process\n\n"
|
307
|
-
|
308
|
-
for entry in result.ai_dialogue_log:
|
309
|
-
agent = entry.get("agent", "Unknown")
|
310
|
-
timestamp = entry.get("timestamp", "")
|
311
|
-
output = entry.get("output", {})
|
312
|
-
|
313
|
-
content += f"### {agent} Agent\n\n"
|
314
|
-
content += f"**Timestamp**: {timestamp}\n\n"
|
315
|
-
|
316
|
-
if isinstance(output, dict):
|
317
|
-
for key, value in output.items():
|
318
|
-
content += f"- **{key}**: {value}\n"
|
319
|
-
else:
|
320
|
-
content += f"Output: {output}\n"
|
321
|
-
|
322
|
-
content += "\n"
|
323
|
-
|
324
|
-
# Add footer
|
325
|
-
content += f"""---
|
326
|
-
|
327
|
-
**Report Generated**: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')}
|
328
|
-
**Generator**: Django App Agent v0.1.0
|
329
|
-
**Format**: Markdown
|
330
|
-
"""
|
331
|
-
|
332
|
-
return content
|
@@ -1,18 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Template Manager Service for Django App Agent Module.
|
3
|
-
|
4
|
-
This package provides sophisticated Jinja2-based template rendering
|
5
|
-
with feature-driven code generation capabilities.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from .main import TemplateManagerService
|
9
|
-
from .jinja_engine import JinjaTemplateEngine
|
10
|
-
from .template_loader import TemplateLoader
|
11
|
-
from .variable_processor import VariableProcessor
|
12
|
-
|
13
|
-
__all__ = [
|
14
|
-
"TemplateManagerService",
|
15
|
-
"JinjaTemplateEngine",
|
16
|
-
"TemplateLoader",
|
17
|
-
"VariableProcessor",
|
18
|
-
]
|