Honor tool plans despite weak classification

This commit is contained in:
2026-05-11 00:14:49 +08:00
parent 7215033028
commit 28a2f63713
2 changed files with 55 additions and 18 deletions
+25 -18
View File
@@ -169,24 +169,14 @@ class AsyncRouter:
session_id,
)
# If mode_hint is conversation, only allow respond type
if mode_hint == "conversation" and not self._is_simple_response(thinker_result):
# Check if Thinker is trying to create an execution plan instead
if any(word in thinker_result.lower() for word in ["шаг", "step", "выполнить", "execute", "shell", "команда"]):
# Override to conversation-only response
respond_text = self._extract_conversation_response(thinker_result)
self._emit_event(
ORCHESTRATOR_RESULT,
{"directive": {"type": "respond", "payload": {"text": respond_text}}, "mode_violation": True},
task_id,
session_id,
)
return ExecutionDirective(
type="respond",
payload={"text": respond_text},
requires_permission=False,
reason="Mode violation: conversation only",
)
if mode_hint == "conversation" and self._looks_like_tool_plan(thinker_result):
mode_hint = "execution"
self._emit_event(
ORCHESTRATOR_FALLBACK_USED,
{"reason": "thinker_proposed_tool_plan_despite_conversation_hint"},
task_id,
session_id,
)
if self._is_simple_response(thinker_result):
json_compiler_prompt = self._build_json_compiler_prompt(thinker_result)
@@ -295,6 +285,15 @@ class AsyncRouter:
sentences = thinker_result.split('.')[:3]
return '. '.join(sentences).strip()
def _looks_like_tool_plan(self, thinker_result: str) -> bool:
result = thinker_result.lower()
tool_names = set()
if self._tool_registry:
tool_names = set(self._tool_registry.list_names())
tool_markers = {"shell_exec", "file_read", "file_write", "memory", *tool_names}
plan_markers = ("план:", "шаг", "step", "tool", "инструмент")
return any(marker in result for marker in tool_markers) and any(marker in result for marker in plan_markers)
def _build_thinker_prompt(
self, task_summary: str, context: dict[str, Any], mode_hint: str
) -> str:
@@ -393,6 +392,14 @@ class AsyncRouter:
return result
result = re.sub(r"<think>.*?</think>", " ", result, flags=re.DOTALL)
if (
"shell_exec" in result
or "execute command" in result
or "command execution" in result
or "use the tool" in result
or "use a tool" in result
):
return "execution"
tokens = re.findall(r"\b(execution|conversation|clarification_needed)\b", result)
if tokens:
return tokens[-1]