dsh-conductor
dsh-conductor 是一个零第三方依赖的 Python 3.13 SDK。它把一段自然语言 prompt 交给工作环境中的 DSH:DSH 负责拆解任务、根据 prompt 选择 Claude Code 或 Codex、通过 tmux 监督执行、独立验证产物,并返回结构化验收结果。
DSH 由运行环境提供,本项目不会安装或调用模型 API。Claude Code 与 Codex 分别由 tmux-claude-code 和 tmux-codex 两个独立 skill 驱动。
SDK 使用:从安装到第一次运行
1. 准备运行环境
项目要求 Python 3.13 或更高版本。dsh-conductor 本身是零第三方依赖的 Python SDK,
但运行任务时还需要由运行环境提供 DSH、tmux,以及 prompt 选择的 worker(Claude Code
或 Codex)。SDK 不安装 DSH,也不调用模型 API。
建议为调用方项目创建虚拟环境:
cd /path/to/your-project
python3.13 -m venv .venv
source .venv/bin/activate # Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install dsh-conductor
安装后可以确认 SDK 版本和命令入口:
python -c 'import conductor; print(conductor.__version__)'
conductor --version
DSH 不在 PATH 中时,设置 DSH_BIN,或在 ConductorConfig 中传入 dsh_bin。首次运行前
建议执行诊断:
conductor doctor
doctor 会检查 Python、tmux、DSH、随包 skills、worker 可用性和 DSH 凭据。凭据由 DSH
管理;SDK 不会写入模型 API key。
2. 编写一个最小 SDK 调用
下面的程序把任务和验收标准放在同一个 prompt 中,并实时打印进度:
from pathlib import Path
from conductor import Conductor, ConductorConfig, ConductorError
workspace = Path("/path/to/your-project").resolve()
client = Conductor(
workspace,
ConductorConfig(
# None 表示从 DSH_BIN 或 PATH 查找 dsh。
dsh_bin=None,
max_attempts=2,
),
)
prompt = """
请使用 Codex 创建 hello.txt,内容为 Hello Conductor 加一个换行。
验收标准:hello.txt 必须存在,且 bytes 恰好等于 b'Hello Conductor\\n'。
"""
try:
result = client.run(prompt, on_event=lambda event: print(event.format(), flush=True))
except ConductorError as exc:
print(f"运行失败:{exc}")
if exc.state_directory:
print(f"运行记录:{exc.state_directory}")
else:
print(f"accepted = {result.accepted}")
print(f"agent = {result.plan.agent.value}")
print(result.verdict.summary)
run() 的第一个参数是唯一业务输入。prompt 中可以明确写“使用 Claude Code”或“使用
Codex”;没有明确指定时,DSH 根据任务与当前环境选择。调用方不再传 agent、task 或
verify 参数。
on_event 会在运行中接收 RunEvent,事件来源包括 dsh、claude、codex 和
conductor。事件只用于显示进度,完成事实仍由 DSH 协议、worker receipt 和最终 verdict
文件决定。TaskResult 包含:
plan:DSH 生成的 agent、任务摘要、步骤和带 ID 的验收项;verdict:DSH 独立检查后的accepted/rejected、每项证据、产物和剩余问题;state_directory:本轮 request、plan、task、receipt、verdict 与worker-screen.log;dsh:协议状态、耗时、事件数量和 DSH 最后文本。
被 DSH 拒绝是正常业务结果,result.accepted 为 False;DSH 启动失败、协议失败或结果文件不合法时抛出 ConductorError。
3. 处理结果并读取 JSON
业务代码通常先检查 result.accepted,再读取结构化计划和验收结论:
payload = result.to_json()
if payload["status"] == "accepted":
for artifact in payload["verdict"]["artifacts"]:
print("已验收产物:", artifact)
else:
print("未通过:", payload["verdict"]["remaining_issues"])
状态目录默认创建在 <workspace>/.dsh-conductor/,每次运行使用独立的 run id。若需要将
审计记录保存到其他位置,可传入 ConductorConfig(state_dir=Path("/path/to/state"))。
目录包含原始 prompt、DSH 计划、worker task/receipt、verdict 和可选的 tmux 屏幕日志,
建议将 .dsh/ 与 .dsh-conductor/ 加入项目的 Git 忽略规则。
4. 可直接运行的示例
下例以 run_task.py 在已激活的虚拟环境中运行时为例:
import json
from pathlib import Path
from conductor import Conductor
result = Conductor(Path.cwd()).run(
"请使用 Claude Code 创建 hello.txt。验收标准:文件存在且内容为 Hello。",
)
print(json.dumps(result.to_json(), ensure_ascii=False, indent=2))
raise SystemExit(0 if result.accepted else 1)
更完整的字段说明、错误 JSON 和实时事件格式见 docs/result-json.md。
可运行示例见 examples/quickstart.py。
仓库中的 quickstart 预设了一个较完整的订单 CSV 汇总任务。先自检 tmux 长输出采集,再让
worker 实现金额汇总、错误处理和单元测试,最后交付记录实现、检查结果及文件路径的 result.md。
默认报告只包含业务内容。调用方会再次检查报告末尾标记、汇总是否为 66.00,以及无效输入
是否保留既有输出。
在仓库根目录运行(直接执行脚本会使用当前仓库源码):
python3.13 -m conductor doctor
python3.13 examples/quickstart.py # 默认使用 Claude Code
python3.13 examples/quickstart.py --agent codex # 使用 Codex 再验证一次
仅验证 tmux 采集、不启动 DSH 或模型时,运行:
python3.13 examples/quickstart.py --tmux-only
仅在需要验证长报告交接时,显式启用 6000 行编号压力测试:
python3.13 examples/quickstart.py --stress-report
该选项要求 worker 用 Python 生成编号,并要求 DSH 读取完整报告,会增加模型上下文开销。 日常验证无需启用;tmux 的 6000 行采集自检由本地 Python 生成和检查,任务明确无需读取其日志。
正常会看到 tmux 当前屏幕 50 行、最近历史连同屏幕 5050 行、扩大读取 6000 行;
日志保留 5050 行,实时回调只有 12 行。真实 worker 任务成功后显示“全部验证通过”。
每次使用新的 /tmp/dsh-quickstart-… 工作区(系统临时目录配置可改变位置),运行结束后保留
quickstart-result.json、result.md 和日志;成功时保留 worker 会话并打印 attach/关闭命令,失败时停止 worker。
quickstart-result.json 在 run() 返回后才写入;运行中的 request、plan、verdict 和屏幕日志
位于 <workspace>/.dsh-conductor/runs/<run-id>/,每轮 task、result、receipt 位于该目录的
attempts/<claude或codex>/<轮次>/。<workspace>/.dsh-conductor/latest.json 记录最近运行的目录。
运行中的 worker 屏幕日志每 10 秒采样一次,结束时立即补采;DSH 协议事件仍实时显示。
--agent 是此示例选择预设 prompt 的参数;SDK 业务输入仍只有 workspace 与完整 prompt。
验证仅由 worker 活动驱动的静默检测时,可以排除 SDK 自动心跳,并缩短测试阈值:
python3.13 examples/quickstart.py --agent codex \
--no-sdk-heartbeat-counts-as-activity --worker-idle-timeout-seconds 30
正常运行使用默认 300 秒。示例会打印 supervision.json 和 supervision.jsonl 路径,可查看
诊断、恢复次数、选择理由与停止原因。无需真实模型的故障回归运行
python3.13 -m unittest tests.test_supervision tests.test_tmux tests.test_sdk -v,覆盖恢复上限、
菜单、缺失报告、迟到回执及总超时;tmux 流程使用本地模拟 worker。
CLI
CLI 是 SDK 的薄封装,保留给脚本和人工调用:
python3.13 -m conductor install-skills --workspace /path/to/project
python3.13 -m conductor doctor
python3.13 -m conductor run \
--workspace /path/to/project \
--prompt '请使用 Claude Code 创建 hello.txt。验收标准:文件存在且内容为 Hello。'
run 的 stdout 始终只有一个 JSON 对象;实时事件由 CLI 写入 stderr,因此可以安全地重定向 stdout。每次运行启动 DSH 前,SDK 都会把包内两个 skill 直接覆盖到 <workspace>/.dsh/skills/,供 DSH 项目级发现;不会写入 ~/.dsh/skills,任务结束后也不会删除。install-skills --workspace 可提前执行同样的复制操作。show 可读取最近一次运行的 request、用户 prompt、manager prompt、plan、verdict 和日志路径。
.dsh/skills/ 和 .dsh-conductor/ 都是 SDK 生成的运行目录,建议加入项目的 Git 忽略规则。
日志与状态
DSH 负责监督判断;控制器把提交、观察、恢复、选择和结束拆成独立操作。run/send 登记任务后
立即返回,watch 就绪时提交任务、每 10 秒检查一次,每次最多等待 300 秒就把屏幕和文件状态
交回 DSH。DSH 不再把整轮任务挂在长时间 job_output 上等待。菜单、连接错误、无效回执和
worker 退出会提前交回判断;正常运行也会周期返回屏幕,便于发现“说完成了但文件没写好”。
| 配置 | 默认值 | 含义 |
|---|---|---|
worker_idle_timeout_seconds |
300 | 连续没有活动的阈值,替代旧 attempt_timeout_seconds |
sdk_heartbeat_counts_as_activity |
True | SDK waiting 心跳也重置活动时钟 |
max_recovery_attempts |
5 | 全 run 主动恢复上限,可设 1–5 |
max_attempts |
2 | 业务委派总轮数(含首轮),与恢复次数分开 |
timeout_seconds |
3600 | DSH 管理回合总时限,活动和恢复都不重置 |
任何 worker 输出或可观察的界面变化都算活动,包括 spinner、计时器、重复错误和光标控制。
pipe-pane 统计原始输出字节,因此相同内容重画也能重置时钟;只在终端客户端本地绘制的
光标闪烁不可被 tmux 感知。默认 SDK 心跳也算活动,因此持续心跳时 300 秒静默检测不会触发。
DSH 仍须检查 watch 周期返回的屏幕,错误、选择和无效回执仍可提前触发判断,总超时仍有效。
如需只计 worker 活动,设置 ConductorConfig(sdk_heartbeat_counts_as_activity=False),
CLI 使用 --no-sdk-heartbeat-counts-as-activity。关闭屏幕日志或回调不会关闭监督或 SDK 心跳记录。
网络或模型连接暂时故障时,DSH 根据现场发送“继续”或具体补交指令;交互选择由 DSH 根据任务
代做。首次普通菜单选择免费,重复卡住的菜单和主动恢复共用恢复预算,跨 watch 和业务返工不
清零,最多 5 次。明确无法恢复或额度耗尽时先保存末屏、停止 worker,再写 rejected;失败无需
有效回执。失败与总超时即使设置 keep_session=True 也会停止 worker,所有诊断文件仍保留。
Claude Code 和 Codex 每轮都必须将完整回答、关键结论、修改记录、检查结果及阻塞信息写入
result.md,长检查输出另存文件并在结果中引用。结果最终原子落盘后才能写入绑定 token 的
receipt;控制器和 SDK 都会拒绝缺失、空白或非 UTF-8 的结果文件。DSH 收到回执后读取完整结果
及相关引用文件,再独立检查工作区。TaskResult.worker_result(JSON 中同名字段)提供最后
一轮已有结果文件的路径;它是 worker 的报告,不替代 verdict。
conductor 会同时轮询两个候选 tmux 会话;DSH 选择哪个 agent 后,只有实际存在的会话产生屏幕日志。
会话名精确匹配,读屏和输入固定到启动时的 worker pane,切换 tmux 窗口不会改变控制目标。
启动时立即采样,之后默认每 10 秒采样当前屏幕及最近 5000 行历史,只有内容变化才发出日志事件,
不会随屏幕刷新触发采样。tmux 窗口创建时的历史上限为 50000 行。
SDK 可通过 ConductorConfig(worker_log_interval_seconds=...) 调整间隔,CLI 可通过
--worker-log-interval-seconds 调整。采样到的全部新增或替换行追加到 worker-screen.log;
实时 RunEvent(source="claude"/"codex", kind="worker_output") 回调每次最多展示 12 行。
大段重复历史会保存完整变化区域而不做昂贵的精细比较,因此诊断日志可能包含重复上下文。
运行结束时无需等待下个周期,立即扩大到最多 50000 行历史补采一次。正常验收结束由 SDK 补采后
按 keep_session 清理会话;DSH 主动 stop 则先保存末屏到 observations,再关闭会话。
两个 skill 的 capture 同样默认读取 5000 行历史,可用 --history-lines 50000 扩大范围,
或用 --history-lines 0 只看当前屏幕。控制器处理菜单时始终只看当前屏幕,避免误认历史菜单。
备用屏幕、重绘或超出采样范围的输出仍可能遗漏,屏幕日志只用于观察状态;文件出现和屏幕文字
都不会被当作完成或验收信号,完整结果以 result.md 及引用文件为准。
屏幕日志与 watch 各自以 10 秒周期采样,DSH 协议事件仍实时回调。原始输出活动计数独立于日志
展示,不使用去重或 spinner 归一化结果;交接和菜单通常在下次 watch 检查时被发现。
状态目录默认位于当前 workspace 下的 .dsh-conductor/;可通过
ConductorConfig(state_dir=...) 或 CLI 的 --state-dir 指定其他位置:
<workspace>/.dsh-conductor/runs/<run-id>/
├── request.json
├── user-prompt.md
├── manager-prompt.md
├── plan.json
├── verdict.json
├── worker-screen.log
├── supervision.json # 活动时钟、恢复预算、当前轮次
├── supervision.jsonl # 诊断、选择、恢复与停止审计
├── worker-activity.json # 原始终端字节计数及最后输出时间
├── sdk-heartbeat.json # SDK 心跳时间(计入活动时生成)
├── observations/ # DSH 操作前屏幕证据,stop 保存最终历史
├── sdk-stop.json # 失败/总超时的结束原因(发生时生成)
├── sdk-stop-<agent>.txt # SDK 兜底结束前的历史快照(发生时生成)
└── attempts/
├── claude/1/{task.md,result.md,receipt.json}
└── codex/1/{task.md,result.md,receipt.json}
每轮运行使用新的 run id 和 receipt token,避免读取旧结论。accepted verdict 必须同时满足 DSH turn/end + session.status=idle、所有验收项通过、产物路径安全且选定 agent 的最终 receipt 有效。
开发验证
python3.13 -m compileall -q conductor skills tests examples
python3.13 -m unittest discover -v
python3.13 ~/.codex/skills/.system/skill-creator/scripts/quick_validate.py skills/tmux-claude-code
python3.13 ~/.codex/skills/.system/skill-creator/scripts/quick_validate.py skills/tmux-codex
发布
推送 GitHub Release 后,.github/workflows/publish.yml 会先在独立 job 中运行测试并构建
发行包,再用 PyPI Trusted Publishing 上传已验证的 wheel 与 sdist。首次发布前,需要在
PyPI 为 GitHub Actions 配置 Trusted Publisher,并在 GitHub 创建 pypi 环境。完整字段、
版本标签规则和发布步骤见 docs/pypi-publishing.md。
Metadata
Release files for dsh-conductor 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| dsh_conductor-0.4.0.tar.gz | 89.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dsh_conductor-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 156.3 kB
Release files / dsh_conductor-0.4.0.tar.gz
| Download URL | dsh_conductor-0.4.0.tar.gz |
|---|---|
| Size | 89.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7bd18de30016c237b503208f2bc5ae172adb877c048dc9acff8440d33229eab1
|
|
BLAKE2b-256 checksum How to use checksums |
f545d7fd8772becd0c148920c3be9bd91279fa83a85417714e9827bef3c2f040
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logRelease files / dsh_conductor-0.4.0-py3-none-any.whl
| Download URL | dsh_conductor-0.4.0-py3-none-any.whl |
|---|---|
| Size | 67.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca848eb9a06ef756138c6c6d5c79207c392651d6305f8e1e790648385723b577
|
|
BLAKE2b-256 checksum How to use checksums |
71913f718d7eee10cdc8faf3a925197bbbf6223c741e88bf685e772f853aded7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logSecurity for dsh-conductor 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for dsh_conductor-0.4.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.