"""AI PMO kernel ingress flow mixin.""" from __future__ import annotations from . import ai_pmo_kernel_common as _common for _name, _value in vars(_common).items(): if not _name.startswith("__"): globals()[_name] = _value class KernelIngressFlowMixin: async def process_feishu_message( self, *, group_chat_id: str, message_content: str, sender: str, source_message_id: Optional[str], source_sender_open_id: Optional[str] = None, captured_at: Optional[datetime] = None, chat_type: Optional[str] = None, ) -> dict[str, Any]: return await self.process_ingress( source_system="feishu", source_message_id=source_message_id, message_text=message_content, sender=sender, channel_ref=group_chat_id, source_sender_open_id=source_sender_open_id, captured_at=captured_at, chat_type=chat_type, ) async def process_ingress( self, *, source_system: str, source_message_id: Optional[str], message_text: str, sender: str, channel_ref: Optional[str] = None, source_sender_open_id: Optional[str] = None, captured_at: Optional[datetime] = None, chat_type: Optional[str] = None, project_hint_id: Optional[int] = None, ) -> dict[str, Any]: started = time.perf_counter() perf_work_item_id: Optional[int] = None perf_intent_name = "" def _log_perf(stage_name: str, stage_started_at: float) -> None: elapsed_seconds = time.perf_counter() - stage_started_at perf_line = ( f"[PERF] {stage_name} took {elapsed_seconds:.2f}s " f"work_item={perf_work_item_id if perf_work_item_id is not None else 'N/A'} " f"intent={perf_intent_name or 'N/A'}" ) logger.info(perf_line) print(perf_line, flush=True) clean_text = self._normalize_text(message_text) if not clean_text: return {"handled": True, "status": "ignored", "classification": "empty", "direct_reply_required": False} transport_mode_reply = self._build_transport_mode_reply(clean_text) if transport_mode_reply: return { "handled": True, "status": "answered", "classification": "question", "linked_project_ids": [int(project_hint_id)] if project_hint_id is not None else [], "signal_id": None, "created_project_id": None, "auto_tasks": [], "ai_trace_id": None, "results": [], "intent": INTENT_QUERY, "direct_reply_required": True, "direct_reply_text": transport_mode_reply, "reply_template_key": "transport_mode_ack", "work_item_id": None, "decision_level": None, "review_summary": None, } synthetic_message_id = self._build_source_message_id( source_system=source_system, source_message_id=source_message_id, channel_ref=channel_ref, sender=sender, message_text=clean_text, ) closure_payload = await self._build_message_closure_payload( source_system=source_system, channel_ref=channel_ref, sender=sender, source_sender_open_id=source_sender_open_id, message_text=clean_text, source_message_id=synthetic_message_id, captured_at=captured_at, project_id=project_hint_id, ) ingest_event, created = await self._claim_ingress_event( source_system=source_system, source_message_id=synthetic_message_id, payload={ "sender": sender, "source_sender_open_id": source_sender_open_id, "channel_ref": channel_ref, "chat_type": chat_type, "captured_at": captured_at.isoformat() if isinstance(captured_at, datetime) else None, "message_text": clean_text, "closure_dialogue": closure_payload.get("closure_dialogue"), "closure_summary": closure_payload.get("closure_summary"), "closure_modules": closure_payload.get("closure_modules"), "closure_turns": closure_payload.get("closure_turns"), }, ) if not created: return { "handled": True, "status": "ignored", "reason": "duplicate_filtered", "classification": "duplicate", "direct_reply_required": False, "source_message_id": synthetic_message_id, } operator = await self._resolve_operator_user(sender=sender, sender_open_id=source_sender_open_id) work_item = await self._create_work_item( ingest_event=ingest_event, source_system=source_system, source_message_id=synthetic_message_id, owner_user_id=_safe_int(getattr(operator, "id", None)), ) perf_work_item_id = int(work_item.id) session = await self._get_or_create_session(tenant_id=self.tenant_id, sender=sender) try: stage_started_at = time.perf_counter() project, world_model = await self.context_assembler.assemble_world_model( sender=sender, message_text=clean_text, project_hint_id=project_hint_id, session=session, ) _log_perf("_build_world_model", stage_started_at) self._schedule_portfolio_snapshot_persist(world_model=world_model) work_item.state = STATE_MODELED stage_started_at = time.perf_counter() intent, intent_context_source = await self._resolve_intent( message_text=clean_text, session=session, world_model=world_model, ) intent = self._enrich_signal_source_intent_from_closure( intent=intent, message_text=clean_text, closure_payload=closure_payload, ) if intent.name in WRITE_INTENTS and IntentResolver._looks_like_negated_write_statement(text=clean_text): metadata = dict(intent.metadata or {}) metadata["guard_reason"] = "negated_write_statement" metadata["guarded_from_intent"] = intent.name intent = CanonicalIntent( INTENT_QUERY, max(float(intent.confidence or 0.0), 0.9), intent.project_id, "", clean_text[:300], metadata, ) workflow_route = self.route_resolver.from_canonical( canonical_intent=intent, message_text=clean_text, ) route_metadata = dict(intent.metadata or {}) route_metadata.update( { "workflow_route": workflow_route.key, "workflow_family": workflow_route.family, "workflow_action": workflow_route.action, "requested_count": workflow_route.requested_count, "requires_confirmation": workflow_route.requires_confirmation, "world_model_capacity": world_model.get("capacity") if isinstance(world_model.get("capacity"), list) else [], "world_model_skill_graph": world_model.get("skill_graph") if isinstance(world_model.get("skill_graph"), list) else [], } ) intent.metadata = route_metadata workflow_route.metadata = route_metadata perf_intent_name = workflow_route.key _log_perf("_resolve_intent", stage_started_at) if intent_context_source: world_model["context_source"] = intent_context_source work_item.context_snapshot = world_model resolved_project_for_session = _safe_int(workflow_route.project_id) or _safe_int(world_model.get("resolved_project_id")) fallback_intent = self.intent_resolver.resolve( text=clean_text, project_id=_safe_int(world_model.get("resolved_project_id")), ) if intent.name == INTENT_IGNORE: work_item.state = STATE_IGNORED work_item.intent = INTENT_IGNORE ingest_event.status = "done" ingest_event.processed_at = _utc_now_naive() await self._write_processing_log( source_message_id=synthetic_message_id, work_item=work_item, message_text=clean_text, route="ai_pmo.ignore", operation_code=None, operation_result={"reason": intent.metadata.get("reason")}, processing_status="success", duration_ms=int((time.perf_counter() - started) * 1000), ) await self._update_session( tenant_id=self.tenant_id, sender=sender, current_project_id=resolved_project_for_session, last_intent=intent.name, last_message_text=clean_text[:200], ) await self.db.commit() return { "handled": True, "status": "ignored", "classification": "ignored", "direct_reply_required": False, "work_item_id": int(work_item.id), "ai_trace_id": f"ai-pmo-{int(work_item.id)}", } work_item.intent = workflow_route.key work_item.project_id = workflow_route.project_id stage_started_at = time.perf_counter() decision_payload = self.decision_engine.decide( intent=intent, world_model=world_model, message_text=clean_text, ) _log_perf("DecisionEngine.decide", stage_started_at) correction_action = str((intent.metadata or {}).get("correction_action") or "none").strip() or "none" requires_manual_review = bool((intent.metadata or {}).get("requires_manual_review")) manual_review_code = str((intent.metadata or {}).get("manual_review_code") or "manual_review_required").strip() manual_review_reason = str((intent.metadata or {}).get("manual_review_reason") or "").strip() llm_function = str((intent.metadata or {}).get("llm_function") or INTENT_LLM_FUNCTION_NAME).strip() route_tier = str((intent.metadata or {}).get("route_tier") or "rule").strip() route_reasons = (intent.metadata or {}).get("route_reasons") gate = kernel_gate_execution( confidence=float(intent.confidence or 0.0), risk_level=self._risk_level_for_intent(intent.name), correction_action=correction_action, force_manual=requires_manual_review, force_manual_code=manual_review_code, force_manual_reason=manual_review_reason, ) decision_trace = build_decision_trace( intent=intent.name, confidence=float(intent.confidence or 0.0), route_tier=route_tier, route_function=llm_function, gate_action=gate.action, gate_code=gate.gate_code, correction_action=correction_action, correction_keywords=(intent.metadata or {}).get("correction_keywords") if isinstance(intent.metadata, dict) else [], complexity_reasons=route_reasons if isinstance(route_reasons, list) else [], ) work_item.state = STATE_DECIDED work_item.decision_level = str((decision_payload["strategic"] or {}).get("decision_level") or "portfolio") decision_row = await self._create_decision_record( work_item=work_item, world_model=world_model, decision_payload=decision_payload, ) await self._create_plan_bundle( work_item_id=int(work_item.id), plan_type="strategic", summary="Strategic Brain 产出的项目群/项目策略。", payload=decision_payload["strategic_plan"], ) await self._create_plan_bundle( work_item_id=int(work_item.id), plan_type="execution", summary="Execution Plan typed action bundle。", payload=decision_payload["execution_plan"], ) policy = decision_payload["policy"] if self._should_bypass_policy_gate( intent=intent, workflow_route=workflow_route, ): policy["auto_execute"] = True policy["policy_gate_hit"] = False policy["policy_gate_code"] = None policy["approval_requirement"] = { "required": False, "reason": "workflow_policy_bypass", "message": "工作流恢复路径按快照执行,不触发仿真门禁拦截。", } if not gate.auto_execute: policy["auto_execute"] = False policy["policy_gate_hit"] = True policy["policy_gate_code"] = gate.gate_code policy["approval_requirement"] = { "required": True, "reason": gate.gate_code, "message": gate.reason, } if not bool(policy.get("auto_execute")): work_item.state = STATE_WAITING_MANUAL work_item.action_bundle = decision_payload["execution_plan"] work_item.execution_result = { "status": "waiting_manual", "reason": ((policy.get("approval_requirement") or {}).get("message") or "").strip(), "workflow_route": workflow_route.key, "workflow_action": workflow_route.action, "decision_trace": decision_trace, } manual_issues = ["waiting_manual"] policy_gate_code = str(policy.get("policy_gate_code") or "").strip() if policy_gate_code: manual_issues.append(policy_gate_code) work_item.review_summary = await self.review_service.review_work_item( work_item=work_item, intent_name=intent.name, execution_result=work_item.execution_result, world_model=world_model, verification={"verified": False, "issues": manual_issues}, simulation=decision_payload["simulation"], ) render = self.reply_renderer.render( work_state=STATE_WAITING_MANUAL, intent=intent, decision_record={ "approval_requirement": policy.get("approval_requirement"), }, execution_result={}, ) work_item.reply_template_key = str(render["template_key"]) await self._project_waiting_manual( work_item=work_item, message_text=clean_text, render=render, intent=intent, ) await self._maybe_emit_risk_cadence_snapshot( project_id=_safe_int(work_item.project_id), review_summary=work_item.review_summary, ) direct_reply_required = await self._claim_reply_receipt( work_item_id=int(work_item.id), source_system=source_system, source_message_id=synthetic_message_id, receipt_phase=str(render["receipt_phase"]), template_key=str(render["template_key"]), payload=render["payload"], ) ingest_event.status = "done" ingest_event.processed_at = _utc_now_naive() await self._write_processing_log( source_message_id=synthetic_message_id, work_item=work_item, message_text=clean_text, route="ai_pmo.waiting_manual", operation_code=None, operation_result=work_item.execution_result, processing_status="success", duration_ms=int((time.perf_counter() - started) * 1000), ) await self._update_session( tenant_id=self.tenant_id, sender=sender, current_project_id=_safe_int(work_item.project_id), last_intent=intent.name, last_message_text=clean_text[:200], ) await self.db.commit() stage_started_at = time.perf_counter() capture_result = self._build_capture_result( work_item=work_item, intent=intent, execution_result=work_item.execution_result or {}, render=render, direct_reply_required=direct_reply_required, status="captured", classification="command", ) _log_perf("_build_capture_result", stage_started_at) return capture_result work_item.state = STATE_PLANNED work_item.action_bundle = decision_payload["execution_plan"] work_item.state = STATE_EXECUTING if intent.name in {INTENT_FOLLOWUP_CONFIRM, INTENT_FOLLOWUP_CONTINUE}: stage_started_at = time.perf_counter() execution_result, verification = await self._execute_followup_intent( work_item=work_item, intent=intent, message_text=clean_text, sender=sender, operator_user_id=_safe_int(getattr(operator, "id", None)), source_system=source_system, source_message_id=synthetic_message_id, channel_ref=channel_ref, source_sender_open_id=source_sender_open_id, world_model=world_model, workflow_route=workflow_route, ) _log_perf("TypedExecutor.execute", stage_started_at) else: stage_started_at = time.perf_counter() handler = self.workflow_registry.get_handler(route=workflow_route) execution_result = await handler.start( route=workflow_route, intent=intent, message_text=clean_text, sender=sender, operator_user_id=_safe_int(getattr(operator, "id", None)), source_system=source_system, source_message_id=synthetic_message_id, channel_ref=channel_ref, ) _log_perf("TypedExecutor.execute", stage_started_at) verification = await self._verify_execution(intent=intent, execution_result=execution_result, world_model=world_model) if isinstance(execution_result, dict): execution_result.setdefault("decision_trace", decision_trace) execution_result.setdefault("workflow_route", workflow_route.key) execution_result.setdefault("workflow_action", workflow_route.action) resolved_route = str(execution_result.get("resolved_route") or "").strip().lower() if resolved_route: work_item.intent = self.route_resolver.normalize_route_key(resolved_route) work_item.execution_result = execution_result if _safe_int(execution_result.get("project_id")) is not None: work_item.project_id = _safe_int(execution_result.get("project_id")) if _safe_int(execution_result.get("signal_id")) is not None: work_item.signal_id = _safe_int(execution_result.get("signal_id")) work_item.review_summary = await self.review_service.review_work_item( work_item=work_item, intent_name=intent.name, execution_result=execution_result, world_model=world_model, verification=verification, simulation=decision_payload["simulation"], ) await self._maybe_emit_risk_cadence_snapshot( project_id=_safe_int(work_item.project_id), review_summary=work_item.review_summary, ) decision_row.execution_result = execution_result issues = verification.get("issues") if isinstance(verification.get("issues"), list) else [] if verification["verified"]: work_item.state = STATE_SUCCEEDED await self._project_success(intent=intent, execution_result=execution_result) elif any( issue in {"waiting_manual", "followup_ambiguous", "signal_source_pending_manual"} for issue in issues ) or str(execution_result.get("status") or "").strip().lower() in {"pending_manual", "pending_confirmation"}: work_item.state = STATE_WAITING_MANUAL else: work_item.state = STATE_FAILED decision_row.final_outcome = work_item.state render = self.reply_renderer.render( work_state=work_item.state, intent=intent, decision_record={ "approval_requirement": decision_payload["policy"].get("approval_requirement"), }, execution_result=execution_result, ) work_item.reply_template_key = str(render["template_key"]) direct_reply_required = await self._claim_reply_receipt( work_item_id=int(work_item.id), source_system=source_system, source_message_id=synthetic_message_id, receipt_phase=str(render["receipt_phase"]), template_key=str(render["template_key"]), payload=render["payload"], ) ingest_event.status = "done" ingest_event.processed_at = _utc_now_naive() await self._write_processing_log( source_message_id=synthetic_message_id, work_item=work_item, message_text=clean_text, route=f"ai_pmo.{work_item.intent or intent.name}", operation_code=self._primary_operation_code(str(work_item.intent or intent.name)), operation_result=execution_result, processing_status="success" if work_item.state in {STATE_SUCCEEDED, STATE_WAITING_MANUAL} else "failed", duration_ms=int((time.perf_counter() - started) * 1000), ) final_project_id = _safe_int(work_item.project_id) or resolved_project_for_session final_intent_name = intent.name or fallback_intent.name await self._update_session( tenant_id=self.tenant_id, sender=sender, current_project_id=final_project_id, last_intent=final_intent_name, last_message_text=clean_text[:200], ) await self.db.commit() execution_route_key = RouteResolver.normalize_route_key( str((execution_result or {}).get("workflow_route") or "") ) if isinstance(execution_result, dict) else "" should_run_signal_planner = ( work_item.state == STATE_SUCCEEDED and ( intent.name == INTENT_SIGNAL_CREATE or execution_route_key == ROUTE_PROJECT_SIGNAL_COMMIT ) ) if should_run_signal_planner: signal_ids = _normalize_signal_id_list(execution_result.get("signal_ids")) signal_id = _safe_int(execution_result.get("signal_id")) if signal_id is not None and signal_id not in signal_ids: signal_ids = [signal_id, *signal_ids] for planner_signal_id in signal_ids: asyncio.create_task( SignalPlannerService.analyze( signal_id=int(planner_signal_id), tenant_id=int(self.tenant_id), source_message_id=synthetic_message_id, source_chat_id=channel_ref, dedupe_seed=f"signal-planner-failed:{int(planner_signal_id)}", session_factory=self._background_session_factory, ) ) stage_started_at = time.perf_counter() capture_result = self._build_capture_result( work_item=work_item, intent=intent, execution_result=execution_result, render=render, direct_reply_required=direct_reply_required, status="answered" if intent.name in {INTENT_QUERY, INTENT_FOLLOWUP_CONFIRM, INTENT_FOLLOWUP_CONTINUE} and work_item.state == STATE_SUCCEEDED else "captured", classification=( "question" if intent.name == INTENT_QUERY else ("signal" if intent.name == INTENT_SIGNAL_CREATE else "command") ), ) _log_perf("_build_capture_result", stage_started_at) return capture_result except Exception as exc: await self.db.rollback() logger.warning( "ai_pmo_kernel_failed", tenant_id=self.tenant_id, source_system=source_system, source_message_id=synthetic_message_id, error=str(exc), ) return {"handled": False, "reason": "kernel_exception", "error": str(exc)}