From bcb2128b02be32699461e0f1ef4fc4da464f5553 Mon Sep 17 00:00:00 2001 From: sora <2075279110@qq.com> Date: Thu, 17 Sep 2026 08:56:48 +0000 Subject: [PATCH] tau2 env: auto-install the engine (local checkout -> GitHub), manual fallback Same UX as the docker image chain: try local sources first, then the GitHub URL, and on total failure print the exact manual commands -- with a warning that PyPI's 'tau2' is an unrelated physics package. Co-Authored-By: Claude --- evalharness/agent/envs/tau2_official.py | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/evalharness/agent/envs/tau2_official.py b/evalharness/agent/envs/tau2_official.py index f91d686..2f4413c 100644 --- a/evalharness/agent/envs/tau2_official.py +++ b/evalharness/agent/envs/tau2_official.py @@ -11,6 +11,7 @@ The env consumes a Sample whose metadata carries the official Task json import asyncio import json +import os from typing import Any, Dict, List, Optional from ...data.sample import ChatMessage, Sample @@ -19,6 +20,54 @@ from ..loop import Environment, register_env _PATCHED = False +_TAU2_GIT = 'git+https://github.com/sierra-research/tau2-bench' +# 本机常见的 tau2-bench checkout 位置(es 仓库 tools/ 下),按序探测 +_TAU2_LOCAL_CANDIDATES = [ + '/data1/sora/evalscope/tools/tau2-bench', + os.path.expanduser('~/tau2-bench', + ) if hasattr(os.path, 'expanduser') else '', +] + + +def _ensure_tau2_engine(): + """Auto-install the REAL tau2-bench engine when missing. + + PyPI's 'tau2' is an unrelated physics package -- never 'pip install + tau2'. We try: (1) already importable, (2) a local checkout + (editable), (3) the GitHub URL, then print the manual fallback.""" + try: + import tau2.data_model.message # noqa: F401 + return + except ImportError: + pass + import importlib + import subprocess + import sys + + cands = [p for p in _TAU2_LOCAL_CANDIDATES if p and os.path.isdir(p)] + attempts = [('local checkout', ['-e', p]) for p in cands] + \ + [('github', [_TAU2_GIT])] + for src, arg in attempts: + print(f'· tau2 engine missing -- installing from {src} ...', flush=True) + r = subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', *arg], + capture_output=True, text=True, timeout=600) + if r.returncode == 0: + try: + importlib.invalidate_caches() + import tau2.data_model.message # noqa: F401 + print(f'✓ tau2 engine installed from {src}', flush=True) + return + except ImportError: + continue + raise RuntimeError( + 'tau2-bench 引擎不可用且自动安装失败。手动安装(任选一):\n' + f' A. pip install git+{_TAU2_GIT}\n' + ' B. 本机源码: pip install -e /path/to/tau2-bench\n' + ' C. 内网无出口时:在有网的机器 ' + '`pip download tau2-bench --no-deps -d pkg/`?注意 PyPI 的 tau2 是' + '无关物理库,必须用 GitHub 源或本机源码!') + + def _patch_tau2_generate(adapter, user_adapter=None, gen_kwargs=None) -> None: """user_adapter: separate model for the USER simulator (es production parity: strong user model like DeepSeek while the agent under test stays @@ -28,6 +77,7 @@ def _patch_tau2_generate(adapter, user_adapter=None, gen_kwargs=None) -> None: if _PATCHED: return + _ensure_tau2_engine() import tau2.utils.llm_utils as llm_utils original = llm_utils.generate