智能体对话选 Agent 直达、澄清问题批量提交、LLM 错误中文化等

- 前端:新会话选 Agent 后直接跳转并自动发送,智能体页输入框宽度与首页对齐
- 前端:澄清卡片支持多选+多问题合并提交,消除单题逐一发送的割裂感
- 前端:定时任务弹窗 Agent 下拉支持长描述截断,避免撑破布局
- 后端:ask_clarification 支持同回合多次调用以提多个独立问题
- 后端:LLM 错误处理与定时任务失败提示统一改为中文

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
吉鑫升andClaude Opus 4.7 committed 2026-05-22 14:24:29 +08:00
1 parent c74be2b789
commit ba2bc46042
7 files changed
+327 -73

No files matched your search

@@ -464,11 +464,22 @@ You are {agent_name}, an internal super agent.
- ❌ DO NOT skip clarification for "efficiency" - accuracy matters more than speed
- ❌ DO NOT make assumptions when information is missing - ALWAYS ask
- ❌ DO NOT proceed with guesses - STOP and call ask_clarification first
- ❌ DO NOT cram several unrelated questions into one `question` string — split them into separate tool calls
- ✅ Analyze the request in thinking → Identify unclear aspects → Ask BEFORE any action
- ✅ If you identify the need for clarification in your thinking, you MUST call the tool IMMEDIATELY
- ✅ After calling ask_clarification, execution will be interrupted automatically
- ✅ Wait for user response - do NOT continue with assumptions
**Batching multiple independent questions:**
- When the request leaves **several independent aspects** unclear (e.g. project type AND tech stack
AND deployment target), call `ask_clarification` multiple times in the same turn — one call per
aspect, each with its own focused `question` and `options`.
- The frontend groups all clarification cards from one turn into a single submission, so the user
answers them together in one reply. You will then receive ONE combined user message addressing
every question in order — read it carefully and match answers back to the questions you asked.
- If the next question only makes sense after the previous answer (sequential dependency), ask
only the first one this turn and wait for the reply before asking the next.
**How to Use:**
```python
ask_clarification(
@@ -171,21 +171,21 @@ class LLMErrorHandlingMiddleware(AgentMiddleware[AgentState]):
def _build_retry_message(self, attempt: int, wait_ms: int, reason: str) -> str:
seconds = max(1, round(wait_ms / 1000))
reason_text = "provider is busy" if reason == "busy" else "provider request failed temporarily"
return f"LLM request retry {attempt}/{self.retry_max_attempts}: {reason_text}. Retrying in {seconds}s."
reason_text = "服务繁忙" if reason == "busy" else "网络/连接异常"
return f"大模型因{reason_text}调用失败,正在第 {attempt}/{self.retry_max_attempts} 次重试,{seconds} 秒后继续…"
def _build_circuit_breaker_message(self) -> str:
return "The configured LLM provider is currently unavailable due to continuous failures. Circuit breaker is engaged to protect the system. Please wait a moment before trying again."
return "大模型因连续多次调用失败已被熔断保护,请稍候再试。"
def _build_user_message(self, exc: BaseException, reason: str) -> str:
detail = _extract_error_detail(exc)
if reason == "quota":
return "The configured LLM provider rejected the request because the account is out of quota, billing is unavailable, or usage is restricted. Please fix the provider account and try again."
return "大模型因账户额度不足、账单异常或使用受限而拒绝请求,请检查模型账户后再试。"
if reason == "auth":
return "The configured LLM provider rejected the request because authentication or access is invalid. Please check the provider credentials and try again."
return "大模型因鉴权失败或无访问权限而拒绝请求,请检查模型的 API Key 与权限配置后再试。"
if reason in {"busy", "transient"}:
return "The configured LLM provider is temporarily unavailable after multiple retries. Please wait a moment and continue the conversation."
return f"LLM request failed: {detail}"
return "大模型因服务繁忙或网络异常,多次重试后仍未恢复,请稍候再继续。"
return f"大模型因「{detail}」原因调用失败。"
def _emit_retry_event(self, attempt: int, wait_ms: int, reason: str) -> None:
try:
@@ -713,7 +713,7 @@ class ScheduledTaskService:
retry_count: int = 0,
) -> None:
"""Mark a run failed and reflect the outcome on the parent task."""
result = _build_result(task, scheduled_for=scheduled_for, content=f"Scheduled task failed: {error}")
result = _build_result(task, scheduled_for=scheduled_for, content=f"定时任务执行失败:{error}")
await self.store.update_run(
run_id,
{"status": "failed", "finished_at": datetime.now(UTC), "error": error, "result": result, "retry_count": retry_count},
@@ -36,18 +36,31 @@ def ask_clarification_tool(
- You're about to perform a potentially dangerous operation
- You have a recommendation but need user approval
Batching multiple independent questions:
- **You CAN and SHOULD call ask_clarification multiple times in the same turn** when the user's
request leaves several **independent** aspects unclear (e.g. project type AND tech stack AND
deployment target). Emit one tool call per aspect — do NOT cram several unrelated questions
into one `question` string.
- The frontend automatically groups all clarification cards in one turn into a single submission,
so the user answers them together in one reply. You will then receive one combined user message
addressing every question in order.
- When the questions DEPEND on each other (the second only makes sense after the first is answered),
ask only the first one and wait for the reply before asking the next.
Best practices:
- Ask ONE clarification at a time for clarity
- Be specific and clear in your question
- Don't make assumptions when clarification is needed
- For risky operations, ALWAYS ask for confirmation
- After calling this tool, execution will be interrupted automatically
- One question per ask_clarification call — keep each `question` focused on a single decision.
- Be specific and clear in your question.
- Provide `options` (with concise labels) whenever there is a discrete set of reasonable choices —
this lets the user multi-select in the UI instead of typing free text.
- Don't make assumptions when clarification is needed.
- For risky operations, ALWAYS ask for confirmation.
- After calling this tool (or several in one turn), execution will be interrupted automatically.
Args:
question: The clarification question to ask the user. Be specific and clear.
question: The clarification question to ask the user. Focused on a single decision; be specific and clear.
clarification_type: The type of clarification needed (missing_info, ambiguous_requirement, approach_choice, risk_confirmation, suggestion).
context: Optional context explaining why clarification is needed. Helps the user understand the situation.
options: Optional list of choices (for approach_choice or suggestion types). Present clear options for the user to choose from.
options: Optional list of choices (for approach_choice or suggestion types). Present clear options for the user to choose from; the UI supports multi-select.
"""
# This is a placeholder implementation
# The actual logic is handled by ClarificationMiddleware which intercepts this tool call