Merge branch 'main' of github.com:xlang-ai/OSWorld

This commit is contained in:
yuanmengqi
2025-07-31 04:16:42 +00:00

View File

@@ -262,55 +262,7 @@ class AnthropicAgent:
raise ValueError(f"Invalid action: {action}")
return result
def _trim_history(self, max_rounds=4):
messages = self.messages
if not messages or len(messages) <= 1:
return
# 计算需要保留的最近轮次数
actual_max_rounds = max_rounds * 2
# 如果消息数量不超过限制,不需要处理
if len(messages) <= actual_max_rounds:
return
# 保留前3条消息初始消息和最近的actual_max_rounds条消息 messages[0:1] + messages[-actual_max_rounds:]
keep_messages = []
# 对于中间被删除的消息,只保留非图片内容
for i in range(1, len(messages) - actual_max_rounds):
old_message = messages[i]
if old_message["role"] == "user" and "content" in old_message:
# 过滤掉image类型的内容块保留其他类型
filtered_content = []
for content_block in old_message["content"]:
filtered_content_item = []
if content_block.get("type") == "tool_result":
for content_block_item in content_block["content"]:
if content_block_item.get("type") != "image":
filtered_content_item.append(content_block_item)
filtered_content.append({
"type": content_block.get("type"),
"tool_use_id": content_block.get("tool_use_id"),
"content": filtered_content_item
})
else:
filtered_content.append(content_block)
# 如果过滤后还有内容,则保留这条消息
if filtered_content:
keep_messages.append({
"role": old_message["role"],
"content": filtered_content
})
else:
# 非用户消息或没有content的消息直接保留
keep_messages.append(old_message)
self.messages = messages[0:1] + keep_messages + messages[-actual_max_rounds:]
def predict(self, task_instruction: str, obs: Dict = None, system: Any = None):
system = BetaTextBlockParam(
type="text",
@@ -398,9 +350,6 @@ class AnthropicAgent:
min_removal_threshold=image_truncation_threshold,
)
#self._trim_history(max_rounds=MAX_HISTORY)
try:
if self.model_name == "claude-3-5-sonnet-20241022":
tools = [
@@ -445,31 +394,28 @@ class AnthropicAgent:
betas=betas,
)
logger.info(f"Response: {response}")
break # 成功则跳出重试循环
break
except (APIError, APIStatusError, APIResponseValidationError) as e:
error_msg = str(e)
logger.warning(f"Anthropic API error (attempt {attempt+1}/{API_RETRY_TIMES}): {error_msg}")
# 检查是否是25MB限制错误
if "25000000" in error_msg or "Member must have length less than or equal to" in error_msg:
logger.warning("检测到25MB限制错误自动裁剪图片数量")
# 将图片数量减半
logger.warning("Detected 25MB limit error, automatically reducing image count")
current_image_count = self.only_n_most_recent_images
new_image_count = max(1, current_image_count // 2) # 至少保留1张图片
new_image_count = max(1, current_image_count // 2) # Keep at least 1 image
self.only_n_most_recent_images = new_image_count
# 重新应用图片过滤
_maybe_filter_to_n_most_recent_images(
self.messages,
new_image_count,
min_removal_threshold=image_truncation_threshold,
)
logger.info(f"图片数量已从 {current_image_count} 减少到 {new_image_count}")
logger.info(f"Image count reduced from {current_image_count} to {new_image_count}")
if attempt < API_RETRY_TIMES - 1:
time.sleep(API_RETRY_INTERVAL)
else:
raise # 全部失败后抛出异常进入原有except逻辑
raise # All attempts failed, raise exception to enter existing except logic
except (APIError, APIStatusError, APIResponseValidationError) as e:
logger.exception(f"Anthropic API error: {str(e)}")
@@ -501,21 +447,21 @@ class AnthropicAgent:
backup_error_msg = str(backup_e)
logger.exception(f"Backup API call also failed: {backup_error_msg}")
# 检查备用API是否也是25MB限制错误
# Check if backup API also has 25MB limit error
if "25000000" in backup_error_msg or "Member must have length less than or equal to" in backup_error_msg:
logger.warning("备用API也遇到25MB限制错误进一步裁剪图片数量")
# 将图片数量再减半
logger.warning("Backup API also encountered 25MB limit error, further reducing image count")
# Reduce image count by half again
current_image_count = self.only_n_most_recent_images
new_image_count = max(1, current_image_count // 2) # 至少保留1张图片
new_image_count = max(1, current_image_count // 2) # Keep at least 1 image
self.only_n_most_recent_images = new_image_count
# 重新应用图片过滤
# Reapply image filtering
_maybe_filter_to_n_most_recent_images(
self.messages,
new_image_count,
min_removal_threshold=image_truncation_threshold,
)
logger.info(f"备用API图片数量已从 {current_image_count} 减少到 {new_image_count}")
logger.info(f"Backup API image count reduced from {current_image_count} to {new_image_count}")
return None, None
@@ -558,10 +504,10 @@ class AnthropicAgent:
actions = ["DONE"]
return reasonings, actions
except Exception as e:
logger.warning(f"parse_actions_from_tool_call解析失败(第{parse_retry+1}/3将重新请求API: {e}")
# 删除刚刚appendassistant消息,避免污染history
logger.warning(f"parse_actions_from_tool_call parsing failed (attempt {parse_retry+1}/3), will retry API request: {e}")
# Remove the recently appended assistant message to avoid polluting history
self.messages.pop()
# 重新请求API
# Retry API request
response = None
for attempt in range(API_RETRY_TIMES):
try:
@@ -585,7 +531,7 @@ class AnthropicAgent:
betas=betas,
)
logger.info(f"Response: {response}")
break # 成功则跳出重试循环
break # Success, exit retry loop
except (APIError, APIStatusError, APIResponseValidationError) as e2:
error_msg = str(e2)
logger.warning(f"Anthropic API error (attempt {attempt+1}/{API_RETRY_TIMES}): {error_msg}")
@@ -600,7 +546,7 @@ class AnthropicAgent:
"content": response_params
})
if parse_retry == max_parse_retry - 1:
logger.error(f"连续3次parse_actions_from_tool_call解析失败,终止: {e}")
logger.error(f"parse_actions_from_tool_call parsing failed 3 times consecutively, terminating: {e}")
actions = ["FAIL"]
return reasonings, actions
def reset(self, _logger = None, *args, **kwargs):