fix: normalize Pro action targets and bound no-progress recovery
This commit is contained in:
1 parent
2ec563c079
commit
9d6833f092
7 files changed
+225
-20
No files matched your search
@@ -19,8 +19,10 @@ from uuid import uuid4
|
||||
from langchain_core.messages import SystemMessage, ToolMessage
|
||||
from langchain_core.tools import BaseTool
|
||||
|
||||
from artemis.core.tool_failure import is_tool_failure
|
||||
from artemis.agents.validator.tool_declarations import normalize_coordinate_target
|
||||
from artemis.config.settings import settings
|
||||
from artemis.context import ArtemisContext
|
||||
from artemis.core.tool_failure import is_tool_failure
|
||||
from artemis.data_engine.trace import (
|
||||
TraceSpan,
|
||||
trace,
|
||||
@@ -57,6 +59,11 @@ from artemis.utils.visualization import format_minimal_list_with_elements
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class OperatorNoProgressError(RuntimeError):
|
||||
"""The model repeatedly returned no usable tool call; stop without device actions."""
|
||||
|
||||
|
||||
DEFERRING_TOOLS = {
|
||||
"ask_diagnoser",
|
||||
"video_analyzer",
|
||||
@@ -485,6 +492,8 @@ class OperatorNode:
|
||||
native_thoughts = []
|
||||
tool_limit_exceeded = False
|
||||
plan_gate_bounced = False
|
||||
no_progress_attempts = 0
|
||||
no_progress_limit = settings.ARTEMIS_OPERATOR_MAX_NO_PROGRESS_ATTEMPTS
|
||||
|
||||
for iteration in range(max_iterations):
|
||||
if iteration == max_iterations - 1:
|
||||
@@ -568,8 +577,27 @@ class OperatorNode:
|
||||
logger.error(f"Failed to parse function_call fallback: {e}")
|
||||
|
||||
if not response.tool_calls:
|
||||
logger.warning("LLM stopped without calling any tool. Encouraging action.")
|
||||
break
|
||||
no_progress_attempts += 1
|
||||
if no_progress_attempts >= no_progress_limit:
|
||||
raise OperatorNoProgressError(
|
||||
f"模型连续 {no_progress_attempts} 次未提供可执行的工具调用,"
|
||||
"已停止任务以避免空转;未执行新的设备动作。"
|
||||
)
|
||||
logger.warning("LLM returned no tool call; requesting a concrete tool call.")
|
||||
current_messages.append(response)
|
||||
current_messages.append(
|
||||
SystemMessage(
|
||||
content=(
|
||||
"No tool call was returned, so no device action occurred. "
|
||||
"Use the available tool interface now, not a prose promise or JSON "
|
||||
"inside text. Use an index from the current element list or "
|
||||
"normalized coordinates with target_description. If blocked, "
|
||||
"use an observation/diagnostic tool; do not invent a click or "
|
||||
"claim success. This recovery has a limited retry budget."
|
||||
)
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
||||
current_messages.append(response)
|
||||
|
||||
@@ -840,9 +868,20 @@ class OperatorNode:
|
||||
break
|
||||
|
||||
if validation_errors:
|
||||
no_progress_attempts += 1
|
||||
if no_progress_attempts >= no_progress_limit:
|
||||
raise OperatorNoProgressError(
|
||||
f"模型连续 {no_progress_attempts} 次未提供可执行的工具调用,"
|
||||
"工具参数校验仍失败;已停止任务,未执行被拒绝的设备动作。"
|
||||
)
|
||||
logger.warning("Some action calls failed validation. Feeding back to LLM.")
|
||||
continue
|
||||
no_progress_attempts = 0
|
||||
else:
|
||||
if no_progress_attempts:
|
||||
raise OperatorNoProgressError(
|
||||
"模型在本轮工具调用预算内未恢复有效调用,已停止任务以避免空转。"
|
||||
)
|
||||
tool_limit_exceeded = True
|
||||
|
||||
raw_thinking = "\n".join(raw_thoughts) if raw_thoughts else None
|
||||
@@ -1122,6 +1161,9 @@ class OperatorNode:
|
||||
straight from the indexed list); a coordinate pair carries only the
|
||||
model's own ``target_description``. The two never mix.
|
||||
"""
|
||||
target = normalize_coordinate_target(target)
|
||||
if isinstance(target, bool):
|
||||
return None, "Error: Boolean values are not valid target indices."
|
||||
if isinstance(target, (int, float)):
|
||||
try:
|
||||
target_int = int(target)
|
||||
|
||||
Reference in new issue
Block a user