PMFlow/backend/app/services/codegen_core/service.py

74 lines
3.0 KiB
Python

"""Code draft generation service composition."""
from __future__ import annotations
from .mixin_context import CodegenContextMixin
from .mixin_prompt_llm import CodegenPromptLlmMixin
from .mixin_review_summary import CodegenReviewSummaryMixin
from .mixin_validation_diff import CodegenValidationDiffMixin
from .schemas import CodeDraftRequest, CodeDraftResponse
from .shared import logger, now_cn_aware
class CodeDraftService(
CodegenContextMixin,
CodegenPromptLlmMixin,
CodegenValidationDiffMixin,
CodegenReviewSummaryMixin,
):
"""AI code draft generation service (aggressive strategy)."""
def __init__(self, llm_service):
self.llm = llm_service
self._init_language_map()
async def generate_draft(self, request: CodeDraftRequest) -> CodeDraftResponse:
"""Generate draft code for the given signal."""
start_time = now_cn_aware().timestamp()
try:
file_contexts = await self._read_target_files(request)
repo_context = await self._analyze_repo_structure(request)
prompt = self._build_aggressive_prompt(request, file_contexts, repo_context)
llm_response = await self._call_llm_for_code(prompt)
generated_files = await self._parse_and_validate(llm_response, file_contexts)
for file in generated_files:
file.diff = self._generate_diff(file_contexts, file)
review_points = await self._extract_review_points(generated_files, file_contexts, request)
confidence = self._calculate_confidence(generated_files, file_contexts)
complexity = self._estimate_complexity(generated_files)
summary = self._generate_summary(generated_files, request)
warnings = self._collect_warnings(generated_files, file_contexts)
generation_time = now_cn_aware().timestamp() - start_time
return CodeDraftResponse(
success=True,
files=generated_files,
summary=summary,
confidence=confidence,
warnings=warnings,
review_points=review_points,
estimated_complexity=complexity,
generation_time=generation_time,
metadata={
"signal_id": request.signal_id,
"files_count": len(generated_files),
"new_files": sum(1 for f in generated_files if f.is_new),
"modified_files": sum(1 for f in generated_files if not f.is_new),
},
)
except Exception as exc:
logger.error(f"Code generation failed: {exc}", exc_info=True)
return CodeDraftResponse(
success=False,
files=[],
summary=f"代码生成失败: {str(exc)}",
confidence=0.0,
warnings=[f"生成过程出错: {str(exc)}"],
review_points=[],
generation_time=now_cn_aware().timestamp() - start_time,
)