复制 async def _execute_tool(self,
tool: Tool,
input_data: Dict[str, Any],
execution_record: Dict,
progress_callback: Optional[Callable] = None
) -> Tuple[Any, Optional[str]]:
"""阶段4:工具执行(带超时控制)"""
start = time.time()
try:
result = await asyncio.wait_for(
tool.call(input_data),
timeout=self.default_timeout
)
execution_record["stages"]["execute_tool"] = {
"duration": time.time() - start,
"success": True
}
return result, None
except asyncio.TimeoutError:
error = f"Tool execution timeout ({self.default_timeout}s)"
execution_record["stages"]["execute_tool"] = {
"duration": time.time() - start,
"success": False,
"error": "timeout"
}
return None, error
except Exception as e:
execution_record["stages"]["execute_tool"] = {
"duration": time.time() - start,
"success": False,
"error": type(e).__name__
}
return None, f"Tool execution error: {str(e)}"
async def _process_result(self, result: Any,
execution_record: Dict) -> Tuple[str, Optional[str]]:
"""阶段5:结果处理(序列化和截断)"""
start = time.time()
try:
if isinstance(result, str):
result_str = result
elif isinstance(result, (dict, list)):
result_str = json.dumps(result, indent=2)
else:
result_str = str(result)
if len(result_str) > self.max_result_size:
original_size = len(result_str)
result_str = result_str[:self.max_result_size]
result_str += f"\n... [Output truncated from {original_size} bytes]"
execution_record["stages"]["process_result"] = {
"duration": time.time() - start,
"truncated": True,
"original_size": original_size,
}
else:
execution_record["stages"]["process_result"] = {
"duration": time.time() - start,
"truncated": False,
"size": len(result_str)
}
return result_str, None
except Exception as e:
return None, f"Result processing error: {str(e)}"
async def _persist_result(self, tool_use_id: str, result: str,
execution_record: Dict):
"""阶段6:持久化(缓存)"""
start = time.time()
self.result_cache[tool_use_id] = {
"content": result,
"timestamp": time.time()
}
execution_record["stages"]["persist_result"] = {
"duration": time.time() - start,
"cached": True
}
def _create_error_result(self, tool_use: ToolUseBlock,
error: str) -> ToolResultBlock:
"""创建错误结果"""
return ToolResultBlock(
tool_use_id=tool_use.id,
content=error,
is_error=True,
error_type="ExecutionError"
)