From 4720c8117d334046941b4785fd58d5119201f316 Mon Sep 17 00:00:00 2001 From: Yuuuu <1569752928@qq.com> Date: Thu, 16 Apr 2026 11:17:52 +0800 Subject: [PATCH] feat: add external query and semantic facts runtime --- .../brainstorm/95325-1776240518/.events | 2 + .../95325-1776240518/.server-stopped | 1 + .../brainstorm/95325-1776240518/.server.pid | 1 + .../semantic-facts-layout.html | 96 + AGENTS.md | 10 + CLAUDE.md | 18 +- HEARTBEAT.md | 10 + .../20260415_add_query_route_memories.py | 98 + .../versions/20260415_add_semantic_facts.py | 138 ++ backend/app/api/mcp_api/__init__.py | 4 + backend/app/api/mcp_api/routes.py | 136 ++ backend/app/api/router.py | 4 + .../app/api/semantic_facts_api/__init__.py | 4 + backend/app/api/semantic_facts_api/routes.py | 104 ++ backend/app/config/ai_prompts.py | 258 ++- backend/app/main.py | 2 + backend/app/models/__init__.py | 6 + backend/app/models/query_route_memory.py | 44 + backend/app/models/semantic_fact.py | 44 + .../models/semantic_fact_extraction_run.py | 29 + .../mixin_answer_entry.py | 8 + .../mixin_answer_mainline.py | 566 ++++-- .../mixin_answer_payload.py | 196 +- .../mixin_answer_precheck.py | 92 +- .../mixin_answer_retrieval.py | 407 +++- .../adaptive_rag_service/mixin_core_intent.py | 204 +- .../mixin_deep_guard_answer.py | 345 ++-- .../mixin_deep_guard_rules.py | 2 +- .../mixin_deterministic_query_core.py | 73 +- .../mixin_fast_answer_project_main.py | 273 ++- .../mixin_fast_answer_project_utils.py | 237 ++- .../mixin_fast_answer_semantic_p2.py | 78 +- .../mixin_followup_anchor.py | 15 +- .../mixin_manifest_core.py | 6 +- .../mixin_manifest_feature_p1.py | 16 +- .../mixin_multistep_core.py | 12 +- .../mixin_multistep_flow.py | 18 +- .../mixin_qa_feedback_records.py | 13 +- .../mixin_query_route_gateway.py | 467 +++++ .../mixin_retrieval_graph.py | 8 +- .../mixin_retrieval_router_db.py | 203 +- .../mixin_session_state.py | 7 +- .../mixin_target_resolution.py | 766 ++++++++ .../services/adaptive_rag_service/service.py | 4 + .../adaptive_rag_service/shared_imports.py | 5 + .../adaptive_rag_service/shared_part_02.py | 3 + .../ai_pmo_kernel/ai_pmo_reply_renderer.py | 9 +- .../ai_pmo_kernel_mixins_intent_resolve.py | 6 - .../ai_pmo_kernel_ingress_flow/mixin_entry.py | 264 ++- .../mixin_execute_query_project.py | 198 +- .../services/ai_pmo/draft_confirm_handler.py | 6 + .../workflow_semantic_planner/service.py | 2 + .../external_query_service/__init__.py | 21 + .../adapters/__init__.py | 6 + .../adapters/live_search.py | 151 ++ .../external_query_service/adapters/mcp.py | 129 ++ .../external_query_service/gateway.py | 271 +++ .../external_query_service/planner.py | 163 ++ .../external_query_service/registry.py | 11 + .../external_query_service/schemas.py | 62 + .../app/services/feedback_center/mappers.py | 2 + .../mixin_card_action.py | 26 +- .../llm_service/mixin_cache_circuit.py | 8 +- .../services/llm_service/mixin_chat_openai.py | 66 +- .../llm_service/mixin_chat_transport.py | 1 + .../llm_service/mixin_task_helpers.py | 81 +- .../services/llm_service/shared_part_01.py | 34 + backend/app/services/mcp_config/__init__.py | 3 + backend/app/services/mcp_config/catalog.py | 87 + backend/app/services/mcp_config/runtime.py | 149 ++ backend/app/services/mcp_config/schemas.py | 62 + backend/app/services/mcp_config/service.py | 374 ++++ .../mixin_event_queue.py | 40 + .../semantic_fact_service/__init__.py | 4 + .../services/semantic_fact_service/hooks.py | 152 ++ .../semantic_fact_service/mixin_admin.py | 567 ++++++ .../semantic_fact_service/mixin_extract.py | 370 ++++ .../semantic_fact_service/mixin_query.py | 198 ++ .../services/semantic_fact_service/service.py | 19 + .../services/semantic_fact_service/shared.py | 162 ++ .../feishu_weather2_run_20260416_1000.json | 0 .../test_adaptive_rag_mainline_contract.py | 1651 ++++++++++++++++- backend/tests/test_ai_pmo_ingress_mainline.py | 729 +++++++- backend/tests/test_ai_service_core_runtime.py | 186 ++ backend/tests/test_draft_confirm_handler.py | 106 ++ backend/tests/test_external_query_planner.py | 51 + .../tests/test_feishu_card_action_contract.py | 7 +- backend/tests/test_mcp_config_api.py | 269 +++ .../tests/test_mcp_external_query_bridge.py | 448 +++++ backend/tests/test_mcp_runtime_service.py | 120 ++ backend/tests/test_model_routing_service.py | 104 ++ ...ct_knowledge_graph_event_queue_contract.py | 75 + backend/tests/test_semantic_fact_admin_api.py | 178 ++ .../tests/test_semantic_fact_runtime_hooks.py | 250 +++ backend/tests/test_semantic_fact_service.py | 575 ++++++ backend/tests/test_semantic_lint.py | 58 + .../consultant_dispatch_feishu_runs.jsonl | 2 + .../feishu_weather2_run_20260416_1000.json | 78 + docs/architecture/ARCHITECTURE_INVENTORY.md | 23 + docs/architecture/CODE_REFERENCE_INDEX.md | 17 + docs/architecture/DATAFLOW.md | 21 + docs/architecture/RUNTIME_GUARDRAILS.md | 36 +- ...2026-04-14-query-source-policy-refactor.md | 70 + ...6-04-15-external-query-gateway-baseline.md | 63 + ...04-15-internal-query-dsl-semantic-facts.md | 306 +++ .../2026-04-14-query-source-policy-design.md | 47 + ...04-15-answer-presentation-policy-design.md | 280 +++ ...026-04-15-external-query-gateway-design.md | 274 +++ ...26-04-15-internal-query-dsl-plan-design.md | 212 +++ ...-04-15-semantic-facts-read-model-design.md | 191 ++ frontend/package-lock.json | 1287 ++++++++++++- frontend/package.json | 8 +- frontend/src/api/mcp.ts | 122 ++ frontend/src/api/semanticFacts.ts | 154 ++ frontend/src/pages/MCPConfigPage.tsx | 1 + frontend/src/pages/SemanticFactsBoardPage.tsx | 1 + frontend/src/pages/ai-config/constants.ts | 16 + .../mcp-config/MCPConfigPage.test.tsx | 280 +++ .../ai-config/mcp-config/MCPConfigPage.tsx | 596 ++++++ .../SemanticFactsBoardPage.tsx | 205 ++ .../components/SemanticFactsDetailDialog.tsx | 188 ++ .../components/SemanticFactsObjectTable.tsx | 179 ++ .../components/SemanticFactsOverviewCards.tsx | 61 + .../components/SemanticFactsQueuePanel.tsx | 99 + .../components/SemanticFactsStatusBadge.tsx | 41 + frontend/src/router/index.tsx | 15 + frontend/src/test/renderWithProviders.tsx | 23 + frontend/vite.config.ts | 5 + frontend/vitest.setup.ts | 15 + mdproject/PLAN.md | 115 ++ scripts/semantic_lint.py | 24 + 131 files changed, 17773 insertions(+), 826 deletions(-) create mode 100644 .superpowers/brainstorm/95325-1776240518/.events create mode 100644 .superpowers/brainstorm/95325-1776240518/.server-stopped create mode 100644 .superpowers/brainstorm/95325-1776240518/.server.pid create mode 100644 .superpowers/brainstorm/95325-1776240518/semantic-facts-layout.html create mode 100644 backend/alembic/versions/20260415_add_query_route_memories.py create mode 100644 backend/alembic/versions/20260415_add_semantic_facts.py create mode 100644 backend/app/api/mcp_api/__init__.py create mode 100644 backend/app/api/mcp_api/routes.py create mode 100644 backend/app/api/semantic_facts_api/__init__.py create mode 100644 backend/app/api/semantic_facts_api/routes.py create mode 100644 backend/app/models/query_route_memory.py create mode 100644 backend/app/models/semantic_fact.py create mode 100644 backend/app/models/semantic_fact_extraction_run.py create mode 100644 backend/app/services/adaptive_rag_service/mixin_query_route_gateway.py create mode 100644 backend/app/services/adaptive_rag_service/mixin_target_resolution.py create mode 100644 backend/app/services/external_query_service/__init__.py create mode 100644 backend/app/services/external_query_service/adapters/__init__.py create mode 100644 backend/app/services/external_query_service/adapters/live_search.py create mode 100644 backend/app/services/external_query_service/adapters/mcp.py create mode 100644 backend/app/services/external_query_service/gateway.py create mode 100644 backend/app/services/external_query_service/planner.py create mode 100644 backend/app/services/external_query_service/registry.py create mode 100644 backend/app/services/external_query_service/schemas.py create mode 100644 backend/app/services/mcp_config/__init__.py create mode 100644 backend/app/services/mcp_config/catalog.py create mode 100644 backend/app/services/mcp_config/runtime.py create mode 100644 backend/app/services/mcp_config/schemas.py create mode 100644 backend/app/services/mcp_config/service.py create mode 100644 backend/app/services/semantic_fact_service/__init__.py create mode 100644 backend/app/services/semantic_fact_service/hooks.py create mode 100644 backend/app/services/semantic_fact_service/mixin_admin.py create mode 100644 backend/app/services/semantic_fact_service/mixin_extract.py create mode 100644 backend/app/services/semantic_fact_service/mixin_query.py create mode 100644 backend/app/services/semantic_fact_service/service.py create mode 100644 backend/app/services/semantic_fact_service/shared.py create mode 100644 backend/backend/tmp_acceptance/feishu_weather2_run_20260416_1000.json create mode 100644 backend/tests/test_external_query_planner.py create mode 100644 backend/tests/test_mcp_config_api.py create mode 100644 backend/tests/test_mcp_external_query_bridge.py create mode 100644 backend/tests/test_mcp_runtime_service.py create mode 100644 backend/tests/test_semantic_fact_admin_api.py create mode 100644 backend/tests/test_semantic_fact_runtime_hooks.py create mode 100644 backend/tests/test_semantic_fact_service.py create mode 100644 backend/tmp_acceptance/feishu_weather2_run_20260416_1000.json create mode 100644 docs/superpowers/plans/2026-04-14-query-source-policy-refactor.md create mode 100644 docs/superpowers/plans/2026-04-15-external-query-gateway-baseline.md create mode 100644 docs/superpowers/plans/2026-04-15-internal-query-dsl-semantic-facts.md create mode 100644 docs/superpowers/specs/2026-04-14-query-source-policy-design.md create mode 100644 docs/superpowers/specs/2026-04-15-answer-presentation-policy-design.md create mode 100644 docs/superpowers/specs/2026-04-15-external-query-gateway-design.md create mode 100644 docs/superpowers/specs/2026-04-15-internal-query-dsl-plan-design.md create mode 100644 docs/superpowers/specs/2026-04-15-semantic-facts-read-model-design.md create mode 100644 frontend/src/api/mcp.ts create mode 100644 frontend/src/api/semanticFacts.ts create mode 100644 frontend/src/pages/MCPConfigPage.tsx create mode 100644 frontend/src/pages/SemanticFactsBoardPage.tsx create mode 100644 frontend/src/pages/ai-config/mcp-config/MCPConfigPage.test.tsx create mode 100644 frontend/src/pages/ai-config/mcp-config/MCPConfigPage.tsx create mode 100644 frontend/src/pages/semantic-facts-board/SemanticFactsBoardPage.tsx create mode 100644 frontend/src/pages/semantic-facts-board/components/SemanticFactsDetailDialog.tsx create mode 100644 frontend/src/pages/semantic-facts-board/components/SemanticFactsObjectTable.tsx create mode 100644 frontend/src/pages/semantic-facts-board/components/SemanticFactsOverviewCards.tsx create mode 100644 frontend/src/pages/semantic-facts-board/components/SemanticFactsQueuePanel.tsx create mode 100644 frontend/src/pages/semantic-facts-board/components/SemanticFactsStatusBadge.tsx create mode 100644 frontend/src/test/renderWithProviders.tsx create mode 100644 frontend/vitest.setup.ts create mode 100644 mdproject/PLAN.md diff --git a/.superpowers/brainstorm/95325-1776240518/.events b/.superpowers/brainstorm/95325-1776240518/.events new file mode 100644 index 00000000..e7e967d9 --- /dev/null +++ b/.superpowers/brainstorm/95325-1776240518/.events @@ -0,0 +1,2 @@ +{"type":"click","text":"C. Tab 分对象类型\n \n 概览 | 项目 | 任务 | 信号 | 文档 | 人员 | 宪章 | 发布 | 复盘\n \n 当前 tab facts 数\n 失败数\n 最后抽取\n \n 当前对象类型的列表和详情\n \n \n \n \n 方案 C\n 对象边界最清楚,但你要横向看整体积压和失败会来回切 tab,运营效率最低。","choice":"c","id":null,"timestamp":1776240598958} +{"type":"click","text":"C. Tab 分对象类型\n \n 概览 | 项目 | 任务 | 信号 | 文档 | 人员 | 宪章 | 发布 | 复盘\n \n 当前 tab facts 数\n 失败数\n 最后抽取\n \n 当前对象类型的列表和详情\n \n \n \n \n 方案 C\n 对象边界最清楚,但你要横向看整体积压和失败会来回切 tab,运营效率最低。","choice":"c","id":null,"timestamp":1776241280184} diff --git a/.superpowers/brainstorm/95325-1776240518/.server-stopped b/.superpowers/brainstorm/95325-1776240518/.server-stopped new file mode 100644 index 00000000..c2cfd3d0 --- /dev/null +++ b/.superpowers/brainstorm/95325-1776240518/.server-stopped @@ -0,0 +1 @@ +{"reason":"idle timeout","timestamp":1776243098908} diff --git a/.superpowers/brainstorm/95325-1776240518/.server.pid b/.superpowers/brainstorm/95325-1776240518/.server.pid new file mode 100644 index 00000000..c063f411 --- /dev/null +++ b/.superpowers/brainstorm/95325-1776240518/.server.pid @@ -0,0 +1 @@ +95325 diff --git a/.superpowers/brainstorm/95325-1776240518/semantic-facts-layout.html b/.superpowers/brainstorm/95325-1776240518/semantic-facts-layout.html new file mode 100644 index 00000000..41513958 --- /dev/null +++ b/.superpowers/brainstorm/95325-1776240518/semantic-facts-layout.html @@ -0,0 +1,96 @@ +
先确认页面信息架构和操作区布局。后端统一按“提交后自动入队 + 失活旧 facts + 手动重抽入口”设计。
+ +一页看全:先看风险和积压,再搜对象,再在右侧展开 facts 详情。我推荐这个,最适合排查“哪个对象没抽上、为什么失败、要不要重跑”。
+偏“工作台”操作感,适合长时间盯一个对象排障;但全局统计和横向比较会弱一点。
+对象边界最清楚,但你要横向看整体积压和失败会来回切 tab,运营效率最低。
+用于生成租户内 MCP 配置标识,以及 Local Bridge/host 侧的引用名。
+状态口径
++ 后端直连模板保存后即可由 PMFlow 发起探测;Local Bridge 模板的“已确认”只表示你手动确认客户本机已经承载,不代表后端直接碰到了宿主机。 +
+当前执行路径
+{activeRuntimeProbe.message}
+ {activeRuntimeProbe.tool_names?.length ? ( ++ 可用工具:{activeRuntimeProbe.tool_names.join(" / ")} +
+ ) : null} +{activeExecutionMode === "backend_direct" ? "后端直连,不要求客户机器安装额外 MCP host" : "不直接改客户本机配置"}
++ {activeExecutionMode === "backend_direct" + ? "PMFlow 会从后端直接连接远程 MCP endpoint;只要网络可达并校验通过,大模型就能直接消费这条能力。" + : "PMFlow 只保存模板参数、接入说明和手动确认状态,不会从 Docker 容器直接写客户机器,也不会冒充已经接通了宿主机资源。"} +
++ 搜索对象名称、对象 ID 或 facts 内容,查看每个对象的抽取状态与最后入库时间。 +
++ {kpis?.[key] ?? "-"} +
+待处理
+{queue?.pending ?? 0}
+处理中
+{queue?.processing ?? 0}
+失败
+{queue?.failed ?? 0}
+最老待处理
++ {formatBeijingDateTime(queue?.oldest_pending_at)} +
+最近失败
+当前没有 dead letter 或失败积压。
+ ) : ( + (queue?.recent_failures || []).map((row) => ( +{row.error_message || "无错误详情"}
+{formatBeijingDateTime(row.updated_at)}
+