fix: direct-mode agent falls through to default when task needs tools

When IntentRouter matches a direct-mode agent (no tools), but the task
content suggests tool needs (shell, search, file ops, etc.), the routing
now falls through to the default agent which has full tool access.

This fixes the issue where "帮我执行个命令" would be routed to
direct_agent and fail because direct mode doesn't support tool calling.

Also restored "你好" in direct_agent keywords since it's correctly
handled now — greetings don't need tools, direct mode is fine.
This commit is contained in:
chiguyong 2026-06-11 15:26:19 +08:00
parent 52b7d6007d
commit cc4c6fe346
2 changed files with 50 additions and 11 deletions

View File

@ -8,7 +8,7 @@ max_steps: 1
max_concurrency: 5
intent:
keywords: ["翻译", "摘要", "格式化", "translate", "summarize", "什么是"]
keywords: ["翻译", "摘要", "格式化", "translate", "summarize", "你好", "什么是"]
description: "简单生成任务无需工具调用单次LLM生成即可"
examples:
- "翻译这段话"

View File

@ -133,12 +133,51 @@ async def resolve_skill_routing(
skill_name = routing_result.matched_skill
try:
matched_skill = skill_registry.get(skill_name)
skill_config = matched_skill.config
# Check if matched skill can handle tool-calling tasks.
# Direct-mode agents with no tools cannot execute tasks
# that require tool use (shell, search, etc.).
# If the task content suggests tool needs, fall through
# to default agent which has full tool access.
execution_mode = getattr(skill_config, "execution_mode", "react")
skill_tools = matched_skill.tools or []
if execution_mode == "direct" and not skill_tools:
# Direct agent matched but has no tools — check if
# the task might need tools. If so, skip this match
# and let it fall through to default agent.
tool_hints = [
"执行", "运行", "命令", "终端", "shell", "bash",
"搜索", "查找", "联网", "搜索", "search",
"安装", "部署", "启动", "停止", "重启",
"文件", "目录", "创建", "删除", "修改",
"run", "execute", "install", "deploy",
"start", "stop", "restart", "file",
]
content_lower = clean_content.lower()
needs_tools = any(h in content_lower for h in tool_hints)
if needs_tools:
logger.info(
f"Session {session_id}: skill '{skill_name}' is direct-mode "
f"but task may need tools, falling through to default agent"
)
# Don't set result.matched, let it fall through
else:
result.skill_name = skill_name
result.skill_config = matched_skill.config
result.skill_tools = matched_skill.tools or []
result.skill_config = skill_config
result.skill_tools = skill_tools
result.matched = True
result.match_method = routing_result.method
result.match_confidence = routing_result.confidence
else:
result.skill_name = skill_name
result.skill_config = skill_config
result.skill_tools = skill_tools
result.matched = True
result.match_method = routing_result.method
result.match_confidence = routing_result.confidence
if result.matched:
logger.info(
f"Session {session_id}: routed to skill '{skill_name}' "
f"via {routing_result.method} (confidence={routing_result.confidence})"