封装了Python虚拟环境管理指令,减少Agent使用终端指令管理环境时遇到的网络问题和权限问题,兼容不同操作系统,工具内部设置自动网络与镜像路由。工具严格受给定读写权限限制。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-python-env
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:AngelosZou/dsh-python-env
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
English | 中文
面向 DeepSeek Harness 项目的工作区级 Python 虚拟环境管理——发现、创建、安装、删除虚拟环境,远离沙箱、网络与子进程的坑。
一个 DeepSeek Harness 插件,为每个项目(工作区)提供面向 Agent 的 Python 虚拟环境管理:
- 五个模型工具 ——
pyenv_discover、pyenv_create、pyenv_install、pyenv_uninstall、pyenv_remove,外加python-env技能与 system-prompt 引导段。 - 通过平台 subprocess 通道(宿主进程)运行标准库
python -m venv/pip,而非沙箱 shell——venv 创建、ensurepip引导、包索引网络访问在 shell 侧 pip 会失败的地方照常工作。 - 镜像与代理回退 —— 网络类失败时按清华 TUNA → 阿里云 → 中科大 USTC 镜像链重试,并探测常见本地代理端口;
index/proxy参数可分别钉死。 - 工作区约束 —— 所有路径都解析在工作区内(Windows 大小写不敏感);缓存与临时状态位于
<工作区>/.dsh-pyenv/;命令为 argv 数组(不经 shell);全局 Python 环境、宿主 pip 缓存、系统临时目录永不被触碰。 - 跨平台 —— Windows / macOS / Linux 的布局与解释器链(
Scripts与bin、py -3与python3)。 - 零第三方依赖 —— 不需要 uv、virtualenv 或任何其他插件;缺失 pip 的环境用
ensurepip离线修复。 - 会话模式对齐 —— 写工具遵循会话沙箱模式,read-only 会话中拒绝执行;发现工具始终可用。
环境要求
- Node.js >= 20
- 由
@deepseek-ai/dsh-base组合的 DSH profile(提供插件使用的subprocess、jobs、tools、skills服务) - Python >= 3.8(在 PATH 上,或显式传入)——仅用于插件管理的环境
安装
从 npm:
dsh plugin --profile web add dsh-python-env
从本地检出(开发):
dsh plugin --profile web add link:<本仓库绝对路径>
然后重启 DSH 后端(宿主组合在进程启动时加载)。新会话中即出现 pyenv_discover / pyenv_create / pyenv_install / pyenv_uninstall / pyenv_remove 五个工具与 python-env 技能。
用法
Agent 侧:
| 工具 | 作用 |
|---|---|
pyenv_discover |
按 pyvenv.cfg 标记或常见命名(.venv、venv、env、.env、virtualenv)在工作区内最多两层深度发现环境,报告路径、解释器、版本、pip 状态。 |
pyenv_create |
用 python -m venv 创建环境——支持 name / root_dir / 基础 python 参数,对已存在环境幂等。 |
pyenv_install |
把 packages 和/或 requirements 文件装入环境(显式 venv / 自动发现 / 自动创建 .venv);ensurepip 修复缺失 pip;镜像/代理回退;upgrade 升级;本地项目 editable 安装;run_in_background 支持长安装。 |
pyenv_uninstall |
从环境卸载包(pip uninstall -y);离线;从不自动创建环境。 |
pyenv_remove |
只删除工作区内的真实环境(拒绝非环境目录与工作区逃逸)。 |
pyenv_create # -> 创建 .venv 并报告解释器路径
pyenv_install { packages: ["pytest>=8"] } # 装入 .venv
pyenv_install { requirements: "requirements.txt" }
pyenv_uninstall { packages: ["pytest"] } # 再卸载
pyenv_discover # 查看全部环境
# 用报告的解释器路径运行代码:
# Windows: <venv>\Scripts\python.exe macOS/Linux: <venv>/bin/python
行为说明:
- 写工具(create / install / uninstall / remove)遵循会话沙箱模式,read-only 会话中拒绝执行;发现工具仍可用。
- 常见需求覆盖:版本(
"pkg==1.2.3")、升级(upgrade: true)、按requirements.txt安装(requirements)、本地项目 editable 安装(packages: ["-e", "."]——editable 路径必须位于工作区内,远程/VCS editable URL 会被拒绝)。 - 未传
venv时,pyenv_install使用唯一发现的环境(优先.venv),不存在则自动创建.venv,存在多个则要求显式指定。 - 后台安装注册到 jobs 运行时——用
job_output轮询、job_kill停止。 - 两分钟预算。 每个 pyenv 工具必须在 2 分钟内完成(发现工具 1 分钟内)。超出预算时工具会终止运行中的进程树,并返回详细的停止原因——正在执行的操作、已尝试的索引/代理、最后输出、可能的原因与下一步建议——而不是挂起或只报一个干巴巴的超时。后台安装同样受 2 分钟上限约束;install/uninstall 的按次
timeoutMs参数仍然有效,但上限为 120000 ms。
工作原理
- Subprocess 通道 —— DSH 沙箱会拦截 CPython 的 owner-only 临时目录(Windows 上
ensurepip/ wheel 解包时[Errno 13])与包索引网络访问。插件代码运行在宿主进程中,因此所有 python/pip/venv 调用都走ctx.subprocess(与 graphlint 插件同通道):argv 数组、字节上限的输出收集、进程树级终止。非受限 token 由下述约束模型补偿——而非削弱沙箱。 - 约束模型 —— 每个受模型影响的路径都经过
guardWorkspacePath(绝对解析 + 包含性判定,防..);venv 名称经单段正则校验并在join后再次守卫;子进程的PIP_CACHE_DIR/ TMP / TEMP / TMPDIR 重定向到<工作区>/.dsh-pyenv/。 - 安装尝试链 —— 先走默认索引;网络类失败(连接重置/超时/DNS——绝非"No matching distribution found"或 TLS 错误)按 TUNA → 阿里云 → USTC 镜像回退,并一次性探测常见本地代理端口(7890、7891、10809、10808、8888),命中则经代理重试同一索引。
- ensurepip 修复 ——
<venv-python> -m ensurepip --upgrade用内置 wheel 离线引导 pip;ensurepip 本身缺失时报错附带 Debian/Ubuntupython3-venv提示。 - 并发 —— 写工具声明
isConcurrencySafe: false,调度器原生串行化;发现只读。 - 技能与引导 ——
python-env技能教 Agent 工具优先与"绝不为 pip 申请升级"的规则;system-prompt 段(dsh-python-env:guidance,order 120)提醒每个会话 pyenv 工具才是正规路径。
项目结构
| 路径 | 用途 |
|---|---|
cordis.patch.yml |
Profile 补丁层,插入 dsh-python-env 行 |
lib/index.js |
宿主插件:注册五个工具、技能与引导段 |
lib/tools/ |
五个模型工具(discover / create / install / uninstall / remove) |
lib/guard.js、lib/venv.js、lib/layout.js、lib/paths.js、lib/python.js |
工作区约束、venv 解析、发现、平台布局、解释器链 |
lib/runner.js、lib/pip.js、lib/envdir.js |
Subprocess 通道、安装链、工作区缓存 |
test/ |
无运行时行为测试(见开发) |
docs/ |
设计与分析文档 |
开发
无构建步骤:插件是纯 ESM,测试直接用 Node 运行(mock ctx 替代 DSH 服务;真实的 defineTool 校验所有 schema):
npm test
# 或:node --test --test-isolation=none "test/*.test.js"
开发循环(含离线依赖解析)见 CONTRIBUTING.md。
兼容性
当 DSH 同时安装了 dsh-multi-folder 插件时,Agent 可以通过 dsh-python-env 提供的工具管理在 dsh-multi-folder 中由用户指定的副工作目录,即使该工作目录不在主要工作目录内。对副工作目录的环境管理权限与主要工作目录一致,当Agent处于Read Only模式运行时,工具会拒绝任何操作。这一兼容是自动及可选的,当DSH环境中同时安装了dsh-multi-folder和dsh-python-env时这一兼容功能会自动生效。如果环境中未安装dsh-multi-folder,这不会对dsh-python-env的功能造成任何影响。这一兼容不会带来任何额外的性能负担或上下文开销。
安全
安装包意味着执行第三方代码:pyenv_install(含自动创建 .venv 的路径)会以宿主用户权限从配置的索引下载并运行代码,editable 安装会原样引入工作区内的项目。插件的缓解措施包括:仅 HTTPS 索引、爆炸半径限定在工作区(被攻破的环境可用 pyenv_remove 一次性丢弃)、路由全程透明、会话模式对齐(read-only 会话无法触发任何安装)、按 profile 选择安装。完整威胁模型与缓解清单见 SECURITY.md。
文档
- docs/design.md —— 架构、约束模型、安装链、已知限制
- SECURITY.md —— 威胁模型与补偿控制
参与贡献
见 CONTRIBUTING.md。欢迎提 issue 与 pull request。
许可证
链接
同类插件
strukto-ai/mirage#dsh★ 3502
把文件系统与 bash 提供者换成 mirage 虚拟工作区:文件工具与 shell 命令作用于挂载的资源(RAM、S3、Redis、Slack、Gmail、Notion、Postgres)而非宿主磁盘,支持按挂载点设置读/写/执行模式、按命令选择沙箱(进程内 monty、pyodide、quickjs;远程 docker、e2b、daytona),并可在虚拟终端中安装 CLI(git、gh、slack、linear、ntn、gws,或自行注册的程序树)作为命令头词。
hust-open-atom-club/oh-dsh★ 246
社区发行版:TUI、桌面端与 Web UI 统一体验,分层安装、一步到位。
lire1131/dsh-undo-plugin★ 72
DSH 撤销/回退系统:配置变更自动存档,一键撤销/恢复/回退到任意版本,支持 WebUI 与离线 CLI/GUI 工具(DSH 启动失败也能救)。
Jayden-X-L/forkprobe★ 67
同一任务并行试跑多个技能,对比结果选出最优。
forrestchang/dsh-multica-runtime★ 46
让 dsh 运行时跑在 Multica 上。
omdsh-dev/dsh-plugin-check★ 24
插件健康检查:扫描清单协议/patch 格式/构建陷阱,零依赖只读。