- 页头只保留品牌与操作图标,三栏改为 1:2:1、容器最宽 1320 - 任务卡片:状态标签移入标题行并缩小,隐藏任务标识,操作行贴内容底边 - uv 配置弹窗:删掉与首页重复的状态条,三段配置改成标签页 - 镜像源:弹窗去掉默认镜像汇总,首页卡片改为展示默认镜像与运行时注入的变量 - 后端:迁移合并为单一基线 0001_init,删掉未生效的 concurrency_policy / retry_*, 运行触发只剩 schedule / manual;contracts、前端生成类型、README / PLAN 同步
3.0 KiB
3.0 KiB
ADR-0009:uv 与托管 Python 环境
- 状态:已接受
- 日期:2026-11-07
背景
Python 任务需要一个可复现的运行环境,但宿主机上的工具链状态不可控:PATH 上的 uv 版本随启动方式变化(终端 / 快捷方式 / 计划任务各不相同),也可能根本没装;pip、conda 与项目 .venv 的组合更是无法预设。之前的实现直接依赖 PATH 里的 uv,并要求用户先手动准备好虚拟环境,出了问题要到第一次运行时才暴露。
决策
- uv 是唯一的环境工具:建环境、装依赖、跑预装都走 uv,不依赖
pip.exe。 - uv 来源只认平台副本或指定路径:默认
程序目录\uv\uv.exe,或用户指定的uv.exe;不读系统 PATH。缺失时从科大镜像mirrors.ustc.edu.cn/github-release/astral-sh/uv/LatestRelease下载当前架构压缩包,校验 sha256 后安装到程序目录。 - 镜像只在装包时生效:建环境 / 预装依赖时注入
UV_DEFAULT_INDEX(以及兼容的UV_INDEX_URL);任务运行时不再注入PIP_*或镜像变量。 - 路径默认值相对程序目录:
UV_PYTHON_INSTALL_DIR默认python、UV_CACHE_DIR默认uv-cache,注入前统一按可执行文件目录解析成绝对路径;用户可改成绝对路径。 - 用户环境优先,缺失才创建:解析顺序仍是显式
venv→ 解释器路径推断 → 工作目录向上查找;都没有时在保存任务时用 uv 创建.venv,运行期只校验、不再自动装依赖。 - 托管环境:
data/envs/<名称>预创建常用环境,Python 版本来自uv python install下载到平台的列表,可预装包、查看已装包。 - 解释器下载归 uv 配置:
uv python install/uv python list的入口放在「uv 配置」弹窗(解释器由 uv 管理、落在UV_PYTHON_INSTALL_DIR);「虚拟环境」弹窗只负责从已下载列表里选版本创建环境。
原因
- PATH 上的 uv 版本与可用性不可控;平台副本随包分发,行为可预期。
- 相对默认值让整个发布目录可以整体搬迁;注入前解析成绝对路径,是因为 uv 的 cwd 在调用间会变化(项目目录 / 环境目录),相对路径会漂。
- 把装依赖限制在保存任务阶段,问题能当场暴露;运行期保持"只运行、不改环境"。
- 单机场景下,用户自己调试好的虚拟环境就是最可信的运行环境,应当优先复用而不是覆盖。
边界
- 托管环境不会自动升级依赖,也不跟随
pyproject.toml变更重建。 uv python install走 uv 自己的 Python 发行源(python-build-standalone),和 PyPI 镜像不是一回事;uv 配置弹窗里配「下载镜像」统一给 uv 本体与解释器用,解释器还可以用UV_PYTHON_INSTALL_MIRROR单独覆盖。- 删除托管环境是直接删除目录,不可恢复。
- 自定义 uv 若版本过旧,
uv python list/envs等子命令可能与平台预期的参数不一致。