from __future__ import annotations import asyncio from datetime import datetime import re from typing import Any, Literal, Optional from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel, Field from sqlalchemy import and_, select from sqlalchemy.ext.asyncio import AsyncSession from ...core.logging import get_logger from ...core.response import success_response from ...database import AsyncSessionLocal, get_db from ...dependencies.auth import get_current_user from ...dependencies.tenant import get_tenant_id from ...models import DecisionRecord, IngestEvent, PlanBundle, PortfolioSnapshot, Project, ReplyReceipt, User, WorkItem from ...services.ai_pmo_cadence_service import AIPMOCadenceService from ...services.ai_pmo_kernel_service import AIPMOKernelService router = APIRouter(prefix="/ai-pmo", tags=["AI PMO"]) logger = get_logger(__name__) FRONT_NOISE_INTENTS = {"query.read_only", "query.answer"} FRONT_NOISE_EXACT = { "收到", "收到啦", "好的", "ok", "okk", "yes", "no", "谢谢", "thanks", "thx", "在吗", "在不在", "怎么样了", "咋样了", "辛苦了", } FRONT_NOISE_HINTS = ("怎么样了", "咋样了", "在吗", "辛苦了", "ok", "谢谢", "收到") FRONT_NOISE_STRUCTURED_HINTS = ("项目", "信号", "任务", "风险", "进度", "状态", "work_item", "工作项", "#") GENERIC_SOURCE_TEXT_RE = re.compile( r"^(?:请)?(?:按|按照)?(?:这个|上述|这条)?(?:分步|步骤)?(?:骤)?(?:把|将)?(?:它|该需求|这条需求)?(?:加入|接入|录入).{0,24}信号源(?:中)?$", re.IGNORECASE, ) LOW_VALUE_CLOSURE_HINTS = ("缺少项目归属", "必须先确认项目", "无法创建", "不能创建")