98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
from .shared import *
|
|
|
|
class AIStewardCreationPipelineMixin:
|
|
async def create_project_from_natural_language(
|
|
self,
|
|
input_text: str,
|
|
creator_id: int,
|
|
tenant_id: int = 1,
|
|
) -> Dict[str, Any]:
|
|
"""零配置项目创建,统一走 draft -> normalize -> persist 三段式。"""
|
|
analysis = await self._analyze_project_input(input_text, tenant_id)
|
|
draft = await self._generate_project_creation_draft(
|
|
input_text=input_text,
|
|
analysis=analysis,
|
|
tenant_id=tenant_id,
|
|
)
|
|
normalized = await self._normalize_project_creation_draft(
|
|
draft=draft,
|
|
input_text=input_text,
|
|
creator_id=creator_id,
|
|
tenant_id=tenant_id,
|
|
)
|
|
payload = await self._persist_project_creation_draft(
|
|
normalized=normalized,
|
|
input_text=input_text,
|
|
creator_id=creator_id,
|
|
tenant_id=tenant_id,
|
|
)
|
|
|
|
await self.db.commit()
|
|
|
|
try:
|
|
charter = payload["charter"]
|
|
project = payload["project"]
|
|
asyncio.create_task(
|
|
AdaptiveRAGService.upsert_pmflow_record_async(
|
|
tenant_id=tenant_id,
|
|
record_type="charter",
|
|
record_id=int(charter["id"]),
|
|
project_id=int(project["id"]),
|
|
title=str(charter.get("title") or "项目宪章"),
|
|
content=json.dumps(charter.get("content") or {}, ensure_ascii=False),
|
|
)
|
|
)
|
|
for task in payload.get("tasks", []):
|
|
task_id = int(str(task.get("id") or "0") or 0)
|
|
if task_id <= 0:
|
|
continue
|
|
asyncio.create_task(
|
|
AdaptiveRAGService.upsert_pmflow_record_async(
|
|
tenant_id=tenant_id,
|
|
record_type="task",
|
|
record_id=task_id,
|
|
project_id=int(project["id"]),
|
|
title=str(task.get("title") or "任务"),
|
|
content=str(task.get("description") or ""),
|
|
)
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
return payload
|
|
|
|
async def _generate_project_creation_draft(
|
|
self,
|
|
*,
|
|
input_text: str,
|
|
analysis: Dict[str, Any],
|
|
tenant_id: int,
|
|
) -> dict[str, Any]:
|
|
if PROJECT_CREATION_SERIAL_DRAFT_STEPS:
|
|
signal_draft = await self._generate_competitive_signal_draft(analysis=analysis, tenant_id=tenant_id)
|
|
charter_draft = await self._generate_charter_draft(analysis=analysis, tenant_id=tenant_id)
|
|
task_drafts = await self._generate_task_chain_draft(analysis=analysis, tenant_id=tenant_id)
|
|
else:
|
|
signal_draft, charter_draft, task_drafts = await asyncio.gather(
|
|
self._generate_competitive_signal_draft(analysis=analysis, tenant_id=tenant_id),
|
|
self._generate_charter_draft(analysis=analysis, tenant_id=tenant_id),
|
|
self._generate_task_chain_draft(analysis=analysis, tenant_id=tenant_id),
|
|
)
|
|
return {
|
|
"analysis": analysis,
|
|
"project": {
|
|
"name": analysis.get("project_name") or input_text[:20] or "未命名项目",
|
|
"title": analysis.get("project_title") or input_text[:50] or "未命名项目",
|
|
"description": input_text,
|
|
"assigned_role": analysis.get("primary_role") or "backend",
|
|
"domain_id": analysis.get("domain_id"),
|
|
},
|
|
"signal": signal_draft,
|
|
"charter": charter_draft,
|
|
"tasks": task_drafts,
|
|
"risks": self._build_risk_alert_drafts(analysis=analysis),
|
|
}
|
|
|