diff --git a/apps/web/vue3/index.html b/apps/web/vue3/index.html index 8711554d2..ec90242b3 100644 --- a/apps/web/vue3/index.html +++ b/apps/web/vue3/index.html @@ -23567,7 +23567,7 @@ compare: [[flesh, peel]]`; const wantsExtensionStage = lowerInput.includes('extension') || userInput.includes('拓展分析') || userInput.includes('扩展分析'); const asksExtensionHelp = wantsExtensionStage && ( lowerInput.includes('help') || userInput.includes('如何使用') || userInput.includes('怎么用') || - userInput.includes('输入') || userInput.includes('参数') || userInput.includes('功能') || userInput.includes('帮助') + userInput.includes('帮助') || userInput.includes('有什么功能') ); if (asksExtensionHelp) { try { diff --git a/apps/web/vue3/main.py b/apps/web/vue3/main.py index 49a0a7333..e76beb7f5 100644 --- a/apps/web/vue3/main.py +++ b/apps/web/vue3/main.py @@ -17944,7 +17944,9 @@ async def _run_agent_chat( "handoff_request": request.message, } - # 轻量拓展分析自然语言触发:预闸命中才查轻量 store(Phase A 命中在此不短路) + # 轻量拓展分析自然语言触发:预闸命中才查轻量 store。 + # 先直接问轻量匹配器(Phase A 打分器会用 legacy 扩展的弱 alias 抢占消息, + # 导致轻量命不中);轻量落空时保持原有 Phase A 链路不变。 try: from gfa_core.extension_stage_lightweight import nl_intent as _lightweight_nl @@ -17953,7 +17955,7 @@ async def _run_agent_chat( ) if _lightweight_published and _lightweight_nl._rough_trigger(request.message or "", _lightweight_published): extension_intent = await asyncio.to_thread( - _match_extension_stage_intent, request.message, request.job_id or "" + _match_lightweight_extension_intent, request.message, request.job_id or "" ) if extension_intent and extension_intent.get("lightweight"): assistant_message = extension_intent.get("message") or "已识别为轻量拓展分析。" diff --git a/gfa_core/extension_stage_lightweight/nl_intent.py b/gfa_core/extension_stage_lightweight/nl_intent.py index 964b237f5..6ccbac96d 100644 --- a/gfa_core/extension_stage_lightweight/nl_intent.py +++ b/gfa_core/extension_stage_lightweight/nl_intent.py @@ -363,14 +363,20 @@ def resolve_lightweight_extension_intent( raise DeepSeekSemanticError("no deepseek config for default client", code="configuration_error") client = _default_client(config) model = getattr(config, "model", None) if config is not None else None - response = client.chat.completions.create( - model=model or "deepseek-chat", - messages=_build_messages(message, catalog, hints), - temperature=0, - response_format={"type": "json_object"}, - max_tokens=4000, - ) - content = response.choices[0].message.content + content = None + for attempt in range(2): + response = client.chat.completions.create( + model=model or "deepseek-chat", + messages=_build_messages(message, catalog, hints), + temperature=0, + response_format={"type": "json_object"}, + max_tokens=4000, + ) + content = response.choices[0].message.content if response.choices else None + if content and str(content).strip(): + break + if not content or not str(content).strip(): + raise DeepSeekSemanticError("empty LLM response after retries", code="empty_response") sanitized, reason = _sanitize_resolution(json.loads(content), catalog) if sanitized is None: return LightweightIntentResolution(