From 10497362bb2be6b0352b6a2551cc756c8af0ba7f Mon Sep 17 00:00:00 2001 From: iven Date: Thu, 23 Apr 2026 19:21:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(chat):=20=E6=BE=84=E6=B8=85=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=8D=A1=E7=89=87=20UX=20=E4=BC=98=E5=8C=96=20?= =?UTF-8?q?=E2=80=94=20=E5=8E=BB=E6=82=AC=E7=A9=BA=E5=BC=95=E7=94=A8=20+?= =?UTF-8?q?=20=E9=BB=98=E8=AE=A4=E5=B1=95=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 提示词增加 ask_clarification 引用规则,避免 LLM 在文本中生成 "以下信息"/"比如:"等悬空引用短语 - 新增 stripDanglingClarificationRef 前端安全网,当消息包含 ask_clarification 工具调用时自动移除末尾悬空引用 - 澄清卡片默认展开,让用户直接看到选项无需额外点击 --- crates/zclaw-kernel/src/kernel/messaging.rs | 1 + desktop/src/components/ChatArea.tsx | 27 ++++++++++++++++++++- desktop/src/components/ai/ToolCallChain.tsx | 3 ++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/zclaw-kernel/src/kernel/messaging.rs b/crates/zclaw-kernel/src/kernel/messaging.rs index 35df8e5..b529ebf 100644 --- a/crates/zclaw-kernel/src/kernel/messaging.rs +++ b/crates/zclaw-kernel/src/kernel/messaging.rs @@ -426,6 +426,7 @@ impl Kernel { prompt.push_str("- Provide clear options when possible\n"); prompt.push_str("- Include brief context about why you're asking\n"); prompt.push_str("- After receiving clarification, proceed immediately\n"); + prompt.push_str("- CRITICAL: When calling ask_clarification, do NOT repeat the options in your text response. The options will be shown in a dedicated card above your reply. Simply greet the user and briefly explain why you need clarification — avoid phrases like \"以下信息\" or \"the following options\" that imply a list follows in your text\n"); prompt } diff --git a/desktop/src/components/ChatArea.tsx b/desktop/src/components/ChatArea.tsx index 0b7fe69..6536b7e 100644 --- a/desktop/src/components/ChatArea.tsx +++ b/desktop/src/components/ChatArea.tsx @@ -665,6 +665,28 @@ function stripToolNarration(content: string): string { return result || content; } +/** + * Strip dangling clarification references from text when ask_clarification tool was called. + * When the LLM calls ask_clarification, it often ends its text with phrases like + * "比如:" / "以下信息" / "以下选项" that reference the tool output — but the tool output + * is rendered in a separate ClarificationCard, so these become confusing dead-end sentences. + */ +function stripDanglingClarificationRef(text: string, hasClarificationTool: boolean): string { + if (!hasClarificationTool || !text) return text; + // Match trailing dangling references in Chinese and English + const patterns = [ + /[,,]\s*可以(?:提供以下|告诉我更多细节,)?(?:信息|选项|方向|细节|分类|类型)[::]\s*$/, + /[,,]\s*比如[::]\s*$/, + /[,,]\s*(?:例如|譬如|如以下)[::]\s*$/, + /,\s*(?:for example|such as|like|the following)[::]?\s*$/i, + ]; + for (const pat of patterns) { + const stripped = text.replace(pat, ''); + if (stripped !== text) return stripped; + } + return text; +} + function MessageBubble({ message, onRetry }: { message: Message; setInput?: (text: string) => void; onRetry?: () => void }) { if (message.role === 'tool') { return null; @@ -749,7 +771,10 @@ function MessageBubble({ message, onRetry }: { message: Message; setInput?: (tex ? (isUser ? message.content : s.toolName === 'ask_clarification') ?? false, + )} isStreaming={!!message.streaming} className="text-gray-700 dark:text-gray-200" /> diff --git a/desktop/src/components/ai/ToolCallChain.tsx b/desktop/src/components/ai/ToolCallChain.tsx index 446a6b1..9b23f67 100644 --- a/desktop/src/components/ai/ToolCallChain.tsx +++ b/desktop/src/components/ai/ToolCallChain.tsx @@ -166,7 +166,8 @@ interface ToolStepRowProps { } function ToolStepRow({ step, isActive, showConnector }: ToolStepRowProps) { - const [expanded, setExpanded] = useState(false); + // Clarification cards default to expanded so users see options immediately + const [expanded, setExpanded] = useState(step.toolName === 'ask_clarification'); const Icon = getToolIcon(step.toolName); const label = getToolLabel(step.toolName); const isRunning = step.status === 'running';