from __future__ import annotations """ Proactive Signal Capture Service - 主动式信号捕获服务 核心功能: 1. 飞书群聊监控 - 自动捕获群内讨论的产品/技术相关内容 2. 浏览器标签监控 - 检测用户访问的技术文档、竞品页面 3. GitHub 仓库监控 - 跟踪上游仓库更新、竞品开源项目 4. HackerNews 自动抓取 - 定时抓取技术前沿信息 每个信号都会自动: - 评估战略重要性 - 提取关键技术栈 - 生成任务建议 - 推送给相关角色 """ import asyncio import inspect import json import re from uuid import uuid4 from datetime import datetime, timedelta, timezone from typing import Any, Dict, List, Optional from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from sqlalchemy import and_, text from ....core.logging import get_logger from ....core.database import AsyncSessionLocal from ....models import ( Signal, Project, ProjectDomain, User, ProjectSignalLink, Task, TruthNode, SkillTag, UserProject, UserWorkload, UserSkillBinding, ) from ....config.ai_prompts import ( PROMPT_FEISHU_PROJECT_SIGNAL_CLASSIFICATION, PROMPT_FEISHU_TASK_ORCHESTRATION, ) from ...llm_service import LLMService from ...notification_service import NotificationService from ... import workload as workload_service from ...adaptive_rag_service import AdaptiveRAGService from ...ai_orchestration_run import AIOrchestrationRunService from ...context_cache_service import context_cache_service from ..signal_source_orchestration import SignalSourceOrchestrationService from ...ai_pmo.ai_pmo_kernel import AIPMOKernelService from ....utils.project_members import ensure_project_default_members from ....utils.sequence import ensure_project_id_sequence, ensure_signal_id_sequence from app.utils.thread_context import build_feishu_thread_key from ....utils.timezone import CN_TZ, now_cn_aware EMOJI_UNICODE_RE = re.compile( r"[\U0001F300-\U0001F6FF\U0001F700-\U0001F77F\U0001F780-\U0001F7FF" r"\U0001F800-\U0001F8FF\U0001F900-\U0001F9FF\U0001FA00-\U0001FAFF" r"\U00002600-\U000026FF\U00002700-\U000027BF]+" ) ONLY_PUNCT_OR_SPACE_RE = re.compile(r"^[\s\W_]+$", re.UNICODE) MENTION_TAG_RE = re.compile(r"]*>", re.IGNORECASE) CONTROL_CHAR_RE = re.compile(r"[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+") logger = get_logger(__name__) AI_THINK_STAGE_ZH = { "capture_start": "开始处理飞书消息", "capture_skip_empty": "消息为空,忽略", "capture_skip_noise": "识别为噪音消息,忽略", "capture_done_ai_pmo": "AI PMO kernel 已完成决策闭环", "capture_kernel_failed": "AI PMO kernel 执行异常", "capture_kernel_failed_rollback_failed": "kernel 异常后回滚失败", "classification_done": "语义分类完成", "classification_parse_failed": "语义分类结果解析失败", "capture_skip_not_requirement": "非需求消息,忽略", "capture_skip_non_requirement": "判定为非需求,忽略", "signal_created": "信号已创建", "project_link_done": "项目关联完成", "project_link_failed": "项目关联失败", "task_orchestrate_failed": "任务编排失败", "capture_done": "飞书消息处理完成", "pipeline_post_orchestrate_failed": "分流后置任务编排失败", "pipeline_post_update_signal_failed": "分流后置信号结果回写失败", "pipeline_post_source_onboard_failed": "分流后置信号源接入编排失败", "task_plan_llm_done": "任务编排 LLM 返回成功", "task_plan_llm_failed": "任务编排 LLM 调用失败", "task_created": "任务已创建", "charter_auto_created": "自动创建宪章节点", "hn_story_captured": "HackerNews 信号已捕获", "hn_monitor_error": "HackerNews 监控异常", "new_project_created_from_signal": "已根据信号自动创建项目", "draft_new_project_brief_failed": "新项目摘要生成失败", } def _build_feishu_rag_conversation_key( *, source_chat_id: Optional[str], source_sender_open_id: Optional[str], sender: Optional[str], source_message_id: Optional[str] = None, thread_context: Optional[dict[str, Any]] = None, ) -> str: return build_feishu_thread_key( source_chat_id=source_chat_id, source_sender_open_id=source_sender_open_id, sender=sender, source_message_id=source_message_id, thread_context=thread_context, ) __all__ = [name for name in globals() if not name.startswith("__")]