From c6b4fc7d505007b48115aa43338b630505980fd0 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Mon, 31 Aug 2026 13:16:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=A8=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=84=8F=E5=9B=BE=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:普通的当前发布查询未进入联网能力包,且需要避免历史表达被误判为实时请求。 变更:新增带当前时间约束的新发布表达识别,按句切分并让明确历史年份优先;补齐否定联网、翻译、工具降级和核验优先级回归测试。 验证:3557 passed,Ruff、格式、架构与 diff 检查通过;对抗复审无 P0/P1。 Co-Authored-By: Codex --- app/services/stream/run_capability_router.py | 41 +++++++++++- .../stream/test_run_capability_router.py | 65 ++++++++++++++++++- 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/app/services/stream/run_capability_router.py b/app/services/stream/run_capability_router.py index f4b294c4..58125b84 100644 --- a/app/services/stream/run_capability_router.py +++ b/app/services/stream/run_capability_router.py @@ -32,7 +32,7 @@ ResolutionMode = Literal["routed", "degraded", "clarification"] SCHEMA_VERSION = 2 -ROUTER_VERSION = "2026-08-31.1" +ROUTER_VERSION = "2026-08-31.2" _CANONICAL_EXTERNAL_TOOL_ORDER = CAPABILITY_CANONICAL_EXTERNAL_TOOL_ORDER _CONTROL_TOOL_NAMES = CAPABILITY_CONTROL_TOOL_NAMES @@ -63,6 +63,20 @@ r"current (?:price|score|exchange rate|ceo|president|release|version))\b", re.IGNORECASE, ) +_CURRENT_RELEASE_UPDATE_RE = re.compile( + r"(?:有什么|有何)(?:新|最新)(?:发布|更新|动态)", + re.IGNORECASE, +) +_EXPLICIT_HISTORICAL_TIME_RE = re.compile( + r"(?:(? bool: ) +def _has_current_release_update_request(message: str) -> bool: + for sentence in _SENTENCE_BOUNDARY_RE.split(message): + if _EXPLICIT_HISTORICAL_TIME_RE.search(sentence): + continue + if _RELATIVE_DATE_RE.search(sentence) and _CURRENT_RELEASE_UPDATE_RE.search(sentence): + return True + return False + + +def _has_current_external_query_request(message: str) -> bool: + for sentence in _SENTENCE_BOUNDARY_RE.split(message): + if _EXPLICIT_HISTORICAL_TIME_RE.search(sentence): + continue + if _RELATIVE_DATE_RE.search(sentence) and _CURRENT_EXTERNAL_QUERY_RE.search(sentence): + return True + return False + + def _needs_current_date(message: str) -> bool: return bool(_RELATIVE_DATE_RE.search(message)) diff --git a/test/services/stream/test_run_capability_router.py b/test/services/stream/test_run_capability_router.py index a48dcead..5c7edab1 100644 --- a/test/services/stream/test_run_capability_router.py +++ b/test/services/stream/test_run_capability_router.py @@ -139,6 +139,16 @@ def _resolve( "high", ("fresh_external_fact",), ), + ( + "今天 OpenAI 有什么新发布?请简单说明。", + "fresh_web", + ("web_search",), + "off", + True, + False, + "high", + ("fresh_external_fact",), + ), ( "OpenAI 今天发布了什么?阅读官方公告后总结", "verified_web", @@ -483,6 +493,59 @@ def test_route_matrix( assert len(route.external_tool_names) <= 3 or route.package_id == "deep_research" +@pytest.mark.parametrize( + "message", + [ + "2020 年 OpenAI 有什么新发布?", + "Python 3.8 当年有何新更新?", + "今天是星期几?另外,2020 年 OpenAI 有什么新发布?", + "今天先解释二分查找。另一个问题:Python 3.8 当年有何新更新?", + "今天,OpenAI 2020 年有什么新发布?", + "今天,OpenAI 2020年有什么新发布?", + "现在回顾1998年微软有何新发布的产品?", + "今天先解释二分查找. 秦始皇有何新发布的法令?", + "今天先解释二分查找.秦始皇有何新发布的法令?", + "今天回顾1898年微软前身有何新发布的产品?", + ], +) +def test_historical_new_release_phrasing_does_not_force_fresh_web(message): + route = _resolve(message) + + assert route.package_id == "clarification_only" + assert route.external_tool_names == () + assert route.include_current_date is False + + +def test_current_new_release_phrasing_keeps_verified_web_priority(): + route = _resolve("今天 OpenAI 有什么新发布?请阅读官方原文并交叉核验") + + assert route.package_id == "verified_web" + assert route.external_tool_names == ("web_search", "url_read") + assert route.include_current_date is True + + +def test_current_new_release_phrasing_respects_network_denial(): + route = _resolve("不要联网,告诉我今天 OpenAI 有什么新发布") + + assert route.package_id == "clarification_only" + assert route.external_tool_names == () + + +def test_quoted_current_new_release_phrasing_remains_transform(): + route = _resolve("把“今天 OpenAI 有什么新发布”翻译成英文") + + assert route.package_id == "transform" + assert route.external_tool_names == () + + +def test_current_new_release_phrasing_degrades_when_tools_are_disabled(): + route = _resolve("今天 OpenAI 有什么新发布?", tools_disabled=True) + + assert route.package_id == "tools_unavailable" + assert route.external_tool_names == () + assert route.network_boundary_required is True + + @pytest.mark.parametrize( "message", [ @@ -3245,7 +3308,7 @@ def test_serialization_only_contains_safe_protocol_fields(): assert payload == { "schema_version": 2, - "router_version": "2026-08-31.1", + "router_version": "2026-08-31.2", "package_id": "mobility_intercity", "confidence": "medium", "resolution_mode": "routed",