@dsh-enhanced/traex-acp-provider
把同一台机器、同一 OS 用户已经登录的 TraeX / TRAE CLI 注册为 DeepSeek Harness 的 traex-agent provider。DSH 在这里是 ACP client:每次模型请求都会在校验 live Agent session 工作区后启动新的 traex acp serve、完成 ACP v1 握手、创建会话、校验模型/effort,并把握手目录作为非权威展示缓存。普通 agent_message_chunk 会映射为 DSH 文本;当请求带 DSH tool schema 时,TraeX 可以返回受控工具信封,插件把它转换成 DSH 原生 tool call,由 Harness 执行后进入下一 step。
启用时,插件会在同一个 LlmRuntime 上通过 @dsh-enhanced/llm-route-capabilities 发布 traex-agent 的 toolCalls: bridge,并随 Cordis fiber 撤回。这个字段只描述 adapter 如何把模型输出投影成标准 DSH tool call,不参与 Delivery/Automations 准入,也不改变模型可见的工具或 Skill;真正的工具授权与执行仍由统一的 Agent Loop、Policy、审批和 sandbox 负责。
这不是订阅 OAuth 转接,也不是模型 API provider。认证、模型供应、网络请求和可能产生的费用均由本机 TraeX 负责;插件不读取或托管 token。仓库中的 @dsh-enhanced/acp 方向正好相反——它让 DSH 自己成为供编辑器调用的 ACP agent。
前置条件
需要包含 ACP server 的 TraeX 版本。先在运行 DSH 的同一用户下检查:
traex --version
traex acp serve --help
traex login status
--version 只是人工兼容记录;运行时的机器门禁是精确 login status 加 ACP initialize 返回的 protocol / agent identity / auth method,不依赖对版本文本的宽松解析。
如命令名是 trae-cli,可在插件配置中覆盖 command。首次登录应在 DSH 外单独完成,例如本机版本提供的 traex login --sso 或 traex login --sso-device;插件不会启动交互式登录或打开浏览器。
公开的 ByteDance trae-agent Python 项目与这里检测到的 TraeX / TRAE CLI 不是同一个运行时。只有 acp serve 可用且握手返回 agentInfo.name = "traex-acp" 的实现会被本插件接受。
安装
dsh plugin --profile web add @dsh-enhanced/traex-acp-provider
dsh --profile web --dump-config
该实验性 route 默认关闭。确认本机版本、登录和 ACP 入口后设置 enabled: true,再在 DSH 的 provider/model 选择处选择 traex-agent。首次打开模型选择器时,listModels 会自动执行一次不提交 prompt 的只读 ACP discovery,展示当前账号完整模型目录;并发查询共享同一次发现,短 TTL 内直接复用,过期后刷新。default 沿用 TraeX 当前模型。具体模型和 effort 都通过 ACP session config option 选择,不会拼进 shell 命令。
设为部署默认模型
除了在选择器里临时选用,也可把 traex-agent 设为该 profile 的部署默认模型。个人助理套件的 dsh-model-setup(见 personal-assistant)会把 agent-default-model 指向 traex-agent,并在指定 profile 的 patch 层把本 route 置为 enabled: true:
dsh-model-setup --provider traex-agent --enable-in-profile web
一键安装器同样支持:本机存在 traex/trae-cli 时交互向导会出现「本机 TraeX」选项,或直接 ./scripts/install/install-local.sh --model-provider traex-agent——它会自动把本 bundle 加入安装集、把全局 agent-default-model 指向 traex-agent、在该 profile 启用 route,并探测 traex login status(未登录仅提示,不中断)。
关键区别:agent-default-model 是全局唯一的 settings 段,被所有 profile 共享;而本 route 的适配器按 profile 注册,只在启用了本 bundle 的 profile 里存在。因此把默认设为 traex-agent 后,只有已启用本 route 的 profile(默认 web)能解析它,headless 等未安装本 bundle 的 profile 会报 NO_ADAPTER。安装器的 --model-route verify 因此对 agent route 采用结构化验证(校验目标 profile 已注册适配器 + traex login status),不发模型请求、不消耗额度。enabled 仍是本 bundle 的最终开关。
快速开始(5 步)
- 确认 ACP 可用:
traex acp serve --help 能打开、traex login status 输出 Logged in using Trae。命令名是 trae-cli 时用它替换下面的 traex。
- 安装插件:
dsh plugin --profile web add @dsh-enhanced/traex-acp-provider。
- 开启 route:本 route 默认关闭,需在配置里显式设
enabled: true(命令名不同则一并改 command)。bundle 已把 cwd 设为 $DSH_HOME/assistant-workspace,与标准 Delivery 的新会话工作区一致;若覆盖整段 config,必须保留该值或同时把两端改到同一目录。
- 落盘检查:
dsh --profile web --dump-config 确认 enabled、command 与 cwd 生效。
- 选择模型调用:打开 DSH 模型选择器;首次查询会通过安全、无 prompt 的 ACP discovery 加载
traex-agent 完整目录。选 default 会沿用 TraeX 当前模型,也可直接选目录里的具体模型与 effort。
每次调用会启动一个新的 traex acp serve 进程并消耗 TraeX 侧额度。遇到报错先看下文「协议与失败策略」的错误码表。
配置
完整配置如下。Cordis config 会整段替换,覆盖时请保留仍需使用的字段:
- id: dsh-enhanced-traex-acp-provider
name: '@dsh-enhanced/traex-acp-provider'
config:
enabled: true
command: traex
cwd: !!js dshHomePath('assistant-workspace')
models: [default]
timeoutMs: 600000
authProbeTimeoutMs: 10000
maxAuthProbeBytes: 32768
killGraceMs: 3000
maxMessageBytes: 262144
maxProtocolBytes: 16777216
maxProtocolMessages: 10000
maxOutputBytes: 2097152
maxStderrBytes: 32768
maxPromptBytes: 4194304
extraEnvNames: []
logDiagnostics: false
enabled 默认 false;只在完成本机兼容性与登录检查后显式开启。
command 是单个可执行文件名或绝对路径;插件固定参数数组并使用 shell: false,不接受 shell 片段。
cwd 是 ACP session/new 允许使用的工作目录;bundle 默认使用 $DSH_HOME/assistant-workspace,与标准 Delivery 默认值一致。相对路径按 DSH 进程启动目录解析。每个带 prompt 的普通对话调用必须是深冻结的 DSH Agent Loop 请求:同模块 marker 可直接验证;包被源码 link 或 DSH 在 adapter 边界复制请求时,则由 Host agents 服务核对仍在运行的精确 Agent、registry/session 对象身份,并从 live Session 的 header 与 derived messages 重建请求,只容许 0.1.2-rc.1 forAdapter() 删除跨 route replayState。随后插件用同一 live Session 的 header cwd,与配置 cwd 分别 realpath 后要求完全相等。缺失、过期、伪造、辅助/嵌套调用、请求变形、cwd mismatch 或 symlink escape 都会在 traex login status 和 ACP 启动前以 LOCAL_SESSION_CWD_REQUIRED 拒绝;ACP 收到的是 canonical live-session cwd。Cordis config 是整段替换,手工覆盖时不要意外删掉 bundle 的 cwd;若改用其他目录,还要把创建该会话的 Delivery defaultWorkspace 改为同一 realpath。
listModels 在缓存为空、过期或只有不完整的普通 stream 观察时,会通过当前 adapter 的 probeReadiness 执行 traex login status 和无 prompt 的 ACP discovery。它固定使用配置 cwd、read-only sandbox、ask-for-approval=never,不携带消息内容,不声明文件/terminal capability,并拒绝 permission request。并发查询 single-flight;完整目录在短 TTL 内复用,过期后刷新。发现失败时 /model 不会整体失败,而是安全回退到 models 配置别名,并只记录固定、无错误原文的诊断。
resolveModel 仍然 不认证、不启动子进程,只读取配置与当前短 TTL 内存缓存,保证 Agent Loop 的 prepareCall 路径 process-free。真实 stream 不信任该展示缓存;它继续要求 live session + canonical cwd,并以自己新建 ACP session 的目录重新权威校验模型与 effort。
- 部署工具仍可在启用 route 前显式调用包导出的
probeTraexReadiness,主动验证本机登录和完整目录;调用完成后应 shutdown 临时 adapter。adapter shutdown 会 abort 尚未完成的目录发现、清除 single-flight 引用与缓存。
models 是实时 ACP 目录以外需要额外展示的非权威别名列表,默认只有 default。它不是执行允许列表;每次请求都会在新的 ACP 会话里重新验证具体模型,模型不可用时失败且不会静默换模型。若 DSH 已放行的 effort 在新会话的 selector 中消失,transport 会保留当前模型并使用该会话的默认档位,绝不重放 prompt。
timeoutMs 覆盖握手、建会话和整轮 prompt。取消或超时时先发 ACP session/cancel 和 SIGINT,等待 killGraceMs 后升级为 SIGKILL,再等待一个等长窗口确认 close。仍未关闭时以 teardown=failed 错误结算,保留原始 abort/timeout 分类,并继续跟踪迟到的 close;不会伪称已完成回收。
authProbeTimeoutMs / maxAuthProbeBytes 限制每次 live-session 调用以及显式 readiness probe 的 traex login status;authProbeTimeoutMs 同时作为 的 auth + discovery 整体短时限,目录查询不会沿用生成请求默认 10 分钟的 。当前 TraeX 可能把精确文本 单独写入 stdout 或 stderr,这两种形式都会被接受,混合输出、ChatGPT、API key、access token、未登录与未知输出全部拒绝。
固定安全策略
插件只接受并启动下面这一组 server 参数:
traex --sandbox read-only --ask-for-approval never acp serve
不会传 --yolo、bypass_permissions 或任意用户追加参数。ACP client 不声明文件系统或 terminal capability;TraeX 发起的每个 session/request_permission 都返回 cancelled。TraeX 子进程自身因此不能通过本插件修改项目或运行命令。模型请求的 DSH tool call 会返回 Harness,由 Harness 既有的工具注册、sandbox、权限和审计链决定是否执行;插件不会替它放行。
安全仍取决于 TraeX 对其配置和沙箱的正确实现。不要把 prompt 约束当作操作系统隔离;处理不可信仓库时,仍应使用只读挂载、容器或独立 OS 账号。
权限与数据边界
| 能力 | 行为 |
|---|
| 文件系统 | 对 prompt-bearing 调用,只把经过 live-loop session 身份和 canonical realpath 精确校验的 cwd 发送给 TraeX,并强制 read-only sandbox。冷/过期的 listModels 可在配置的 static cwd 启动无 prompt、read-only/no-approval discovery;resolveModel 不启动进程。插件本身不提供 ACP 文件读写接口。 |
| 网络 | 插件本身不直连模型服务;TraeX 会连接自己的认证、推理、更新或遥测服务。 |
| 子进程 | 每次经过 live-session 校验的请求直接启动一个 TraeX ACP stdio 子进程,shell: false,并从同一握手观察目录。冷/过期的 listModels 或部署者显式调用 probeTraexReadiness 时,会另开无 prompt 临时 ACP 会话;并发列表查询只启动一个。取消/shutdown 时先 abort discovery 或走 ACP cancel,再回收进程组;Windows 后代进程回收为 best-effort。 |
| 凭据 | 不读取 TraeX auth 文件、不实现登录、不刷新或上传 token;只让 TraeX 在本机用户配置目录中使用自己的缓存凭据。 |
| 浏览器 | 插件不会打开浏览器;用户在插件外执行 TraeX login 时可能打开。 |
| ACP 权限 | 所有 permission request 均拒绝;不暴露 client-side FS、terminal 或 MCP server。 |
| DSH 工具 | 请求中的 tool schema 会进入模型隐藏的兼容协议;只接受本次实际声明的精确工具名和对象参数,随后映射为 DSH tool call。工具声明只表示可用性,不构成授权;模型须遵循序列化的 DSH system/user 指令和先前 tool result。某项操作被 user、Policy 或缺失授权拒绝后,除非后续经授权的 user 或 system 指令明确允许,模型不得重试、绕过或以等效操作替代;参数无效且工具回执建议只读发现时可以在原授权内纠正。模型可以继续独立获准的工作,或如实说明阻塞,不能把未发生的工作称为完成。真正的读写、网络、子进程或外部服务权限仍由对应 DSH 工具及 Harness 策略控制。 |
| 日志 | 不主动记录 prompt;stderr 有界且默认不输出内容。每次请求结算记录一条无凭据生命周期诊断(阶段/提交状态/结果分类/teardown、可测得的毫秒级延迟指标,以及 ACP 返回时的纯数值 usage 快照),并在观测目录时只记录模型数量。均不含 prompt、stderr 原文、认证凭据或 model id 原文;usage 快照可能包含 ACP 报告的 token 数量。 |
| 安装脚本 | 包内没有 install/postinstall 脚本,也不会安装或更新 TraeX。 |
协议与失败策略
- 只接受 ACP protocol v1 和
traex-acp agent identity;版本或 identity 不符时 fail closed。
- SDK 前的 wire guard 会追踪 JSON-RPC request id;非法 envelope、未知/重复 response id、未声明的 filesystem/terminal request 和未知 notification 都会终止该轮,不交给 SDK 宽松处理。
- 只消费当前 session 的文本
agent_message_chunk;普通文本直接成为最终回复,严格匹配 dsh-tool-calls/v1 的信封会转换为 DSH tool call。thought、plan 和 TraeX 自己的 tool update 不会伪装成 DSH 输出。
- 工具信封只允许调用本次
GenerateOptions.tools 中存在的精确名称,参数必须是 JSON 对象。兼容模型把参数编码成 JSON 字符串的情况,但只解码一次,结果仍须是对象;数组、null、畸形文本和再次编码的字符串均拒绝。未知工具、空调用或畸形信封以 ACP_PROTOCOL_ERROR fail closed。参数继续交给原生工具校验和权限检查。截断终态不会执行工具信封。若模型误在合法信封前附加一小段进度说明,插件会只提取并隐藏该信封,避免原始 JSON 泄漏到对话界面;不含协议标记的普通 JSON 仍按文本处理。
end_turn 是正常完成终态;max_tokens、max_turn_requests 都映射为 DSH max-tokens 截断终态,供上层决定是否创建新的补全 turn。refusal、cancelled、断连、畸形/超限 NDJSON、无文本或缺少终态都会失败。
- TraeX 可能仍在 stderr 记录
unsupported call 一类内部工具路由告警;这是其内部工具未向本兼容层开放,不等同于 DSH 工具失败。插件会要求模型只返回 dsh-tool-calls/v1 信封;若调用仍失败,生命周期日志会同时给出 phase、terminal、exitCode 和 signal,便于区分终态缺失、协议校验与进程退出。
- 已保存的 effort 可能在切换模型、账号权益变化或目录更新后失效。此时插件在
session/prompt 前丢弃该陈旧值,使用本次 ACP session 返回的当前默认档位继续执行;不会重放 prompt 或重复计费,生命周期日志会标记 reasoningFallback=true。下次打开模型选择器会显示新目录。
- Provider 不会重放同一个已提交请求。外部 agent 可能已经读取上下文或产生服务端计费,原请求自动重试会放大副作用;上层
assistant-delivery 可在持久化 max_tokens / max_turn_requests 终态后,选择创建新的、有界、禁止工具执行的后续 turn 来补齐回答,这不属于 Provider 重试。DSH 0.1.2-rc.1 仍可能向 Provider 序列化 scoped tool schema,但恢复期间的任何工具调用都会在审批和执行前被拒绝。TraeX 的每个后续 turn 仍会启动新进程/session,并按一次新的模型调用消耗额度。
调用失败时返回的稳定 LlmError code 与排查:
| 错误码 | 含义 | 处理 |
|---|
ACP_AUTH_REQUIRED | 每次调用前的 traex login status 未精确报告 Logged in using Trae | 在同一 OS 用户下重新 traex login;ChatGPT/API key/access token/未登录都会被拒。 |
LOCAL_SESSION_CWD_REQUIRED | 请求没有匹配的 live loop session,或其 canonical cwd 与配置 cwd 不完全一致 | 从真实 DSH Agent Loop 发起调用;确认 session header cwd 与插件 cwd 指向同一 realpath,且不要通过 symlink 跨出该目录。 |
ACP_ENTITLEMENT_REQUIRED | 握手成功但当前 Trae 账号没有任何可用模型 | 确认账号权益/套餐,必要时在 TraeX 侧切换账号。 |
ACP_MODEL_UNAVAILABLE | 请求的模型不在本次 ACP 会话的 model selector 中 | 刷新模型列表或用 default;账号权益或 TraeX 目录可能已经变化。 |
ACP_REFUSAL | TraeX 明确拒绝了本次请求 | 属模型侧决定,调整 prompt 后重试。 |
ACP_TIMEOUT | 握手+建会话+整轮 prompt 超过 timeoutMs | 简化 prompt 或调大 timeoutMs。 |
ACP_OUTPUT_LIMIT | 助手文本超过 maxOutputBytes | 调大 maxOutputBytes 或缩小任务。 |
ACP_PROTOCOL_ERROR | protocol/identity 不符、非法 envelope、无文本或缺终态 | 确认 TraeX 版本仍提供 ACP v1 + traex-acp identity;升级后握手变化时插件会拒绝而非猜测。 |
ACP_PROCESS_FAILED | 子进程非零退出或其他未归类失败 | 开 logDiagnostics 看脱敏 stderr;单独 traex acp serve 复现。 |
CONTEXT_WINDOW_EXCEEDED | 序列化后的 DSH 请求超过 maxPromptBytes,在握手前失败 | 调大 maxPromptBytes,或压缩/清理对话历史;该上限只防本机内存膨胀,与 argv 长度无关。 |
ACP_PROMPT_INVALID | 请求中含无法序列化的内容(如图片或未知 content block) | 本 route 是 text-only 兼容层;改用纯文本,或换用支持该模态的 provider。 |
CLI_NOT_FOUND | 找不到可执行文件(ENOENT) | 核对 command 名称/路径及 PATH。 |
INVALID_PROVIDER | 选择了非 traex-agent 的 provider id | 只使用 traex-agent。 |
- 认证不足会返回
ACP_AUTH_REQUIRED,无可用权益/模型分别映射为 ACP_ENTITLEMENT_REQUIRED / ACP_MODEL_UNAVAILABLE,明确拒绝映射为 ACP_REFUSAL;其他稳定错误包括 ACP_PROTOCOL_ERROR、ACP_TIMEOUT、ACP_OUTPUT_LIMIT、ACP_PROCESS_FAILED、CONTEXT_WINDOW_EXCEEDED、ACP_PROMPT_INVALID 和 CLI_NOT_FOUND。
- 握手前的 prompt 序列化失败(超限或含不支持的 content block)一律带稳定错误码抛出,不会退化为未分类失败;此时 prompt 确定未进入 ACP 流,重试安全。
模型目录:listModels 在冷启动、TTL 到期或仅有不完整观察时调用 probeReadiness,以 prompt-free、read-only/no-approval ACP session 加载完整目录;并发调用 single-flight,成功结果短 TTL 复用,失败则返回配置别名且只留固定诊断。resolveModel 始终只读缓存、不做 I/O。每次真实调用仍以自己的 session/new 返回值为唯一执行依据,重新选择并核对模型与 effort;auth 失败、reload 或 shutdown 会清除缓存。目录日志只输出模型数量,不含 model id 原文。
已知限制
- DSH
0.1.2-rc.1 暴露的是 LlmAdapter seam,因此工具调用通过模型隐藏的严格 JSON 信封桥接,不是 TraeX 原生 tool update,也不是完整 ACP UI。TraeX 的 plan、diff、permission UI、会话列表和富内容不会进入 DSH。
- 每次 DSH 请求使用一个新的 TraeX 进程和 ACP session,不恢复外部历史;完整 DSH 对话会被序列化进 prompt。
- 暂不转发图片、音频或 TraeX token usage。DSH tool schema 会随每一步序列化,工具结果则通过下一步的完整 DSH 对话返回给模型;实验性的 ACP
PromptResponse.usage 只保留显式数值字段用于内部诊断,不会映射或发送为 DSH usage chunk。
- TraeX 是变化中的开发工具;本实现以本机
traecli 0.201.1 (internal edition) 的 ACP v1 握手、逐模型 reasoning selector 与官方 ACP SDK 0.25.1 为验证基线。升级后若 identity、模型/effort selector 或终态变化,插件会拒绝而不是猜测兼容。
兼容性与调研
- Node.js
^22.19.0 || >=24.0.0
- DeepSeek Harness /
@deepseek-ai/dsh-agent / @deepseek-ai/dsh-llm / @deepseek-ai/dsh-session >=0.1.2-rc.1 <0.2.0
- Cordis
^4.0.1
- Agent Client Protocol SDK
0.25.1,protocol version 1
进一步阅读:两个 provider 的 ACP 边界与优化调研、兼容基线。