前言¶
DeepSeek Harness(DSH)的插件化架构让开发者可以按需组合能力。在模型推理场景中,不少开发者需要接入 WPS 灵犀(Lingxi)的服务,但原生的 /completions 或 /expert_completion 端点要么缺少思考过程,要么在代码执行时会被劫持成「深度研究」流程,无法直接获取真实输出。针对这个痛点,xfyang728/dsh-router-wpslingxi 提供了一个独立供应商插件,专门为 dsh-router 提供 WPS 灵犀的接入层。
插件定位¶
这是一个为 dsh-router 提供的 WPS 灵犀供应商插件,维护者为 xfyang728。它通过 cowork WebSocket 通道,同时支持思考过程输出、工具调用与真实沙箱代码执行,并将沙箱生成的文件回传到本地工作目录。插件采用独立供应商结构,自含契约,不依赖 dsh-router 包。
核心能力¶
思考过程¶
支持将上游的 c_reasoning 组件映射为 reasoning_content,让思考过程在 dsh 侧可见。
工具调用与真沙箱执行¶
支持以下工具调用,且代码在真实的云端沙箱中运行:
c_execute_code/c_read_file/c_write_file/c_edit_file/c_list_files/c_install_package/c_websearch/c_urlfetch
工具调用会渲染成 Markdown,包含代码块与真实的沙箱 stdout 输出。
模型选择与思考强度¶
支持通过 agent_input.expect_model 选择模型,实测可路由 11 个模型 key。同时支持通过 agent_input.reasoning_effort 控制思考强度(low / high / max)。
积分上报¶
在 run.end 事件中上报 session_credit_consumed,将灵犀的积分消耗同步到 DSH 侧。
产出文件回传(沙箱 → 本机)¶
灵犀的沙箱路径为 /home/lingxi/workspace,文件不会自动出现在本机。插件通过以下步骤将文件拉回:
- 在用户消息末尾约定「产出目录」为
/home/lingxi/workspace/output,引导 agent 将文件写入该目录; - 在
run.end之后,列出该目录,获取预签名直链; - 下载文件并落到会话工作目录(cwd);
- 在回答末尾追加回传摘要。
示例摘要:
> 📁 **沙箱产出已回传到本机**:`D:\your\project`
> - `merge_sort.py` (1608 字节)
注意:必须显式约定绝对路径,agent 才会真正落盘。如果只在回答中贴代码,沙箱内不会生成文件。
安装与启用¶
安装前需要确保已安装 Node.js 20 或更高版本。
pnpm install && pnpm build
作为 DSH 插件安装时,使用 cordis.patch.yml 单行 insert,dsh bundle 机制会自动挂载。
在 Windows 上,如果跨盘无法使用 link: 安装(pnpm 会把路径拼坏),可以先执行 pnpm pack 生成 tgz 包,然后在 profile 目录执行 pnpm add <tgz>。改源码后需要 bump 版本号再重新 pack,否则 pnpm 会复用旧缓存。
测试¶
pnpm test # node --test(全部离线,WS 用注入的假实现)
pnpm typecheck
pnpm build
工作方式¶
凭证与通道¶
凭证为登录 lingxi.wps.cn 后从 DevTools → Application → Cookies 复制的 wps_sid cookie。面板「添加 API key」粘贴即可。注意 host 为 lingxi.kdocs.cn,同一个 cookie 两边都认。
协议与帧格式¶
走 cowork WebSocket 通道,服务端回 JSON 文本帧,通过 data.type 区分语义:
run.start/run.end:会话开始与结束component.start/component.content/component.end:组件内容,包含思考、文本、工具调用等turn.start/turn.end:轮次开始与结束
组件类型映射:
| type | 映射 |
|---|---|
c_reasoning |
→ reasoning_content |
c_text |
→ content |
c_execute_code 等工具 |
→ 渲染成 Markdown 正文 |
c_recommend |
忽略 |
语义状态映射¶
| 上游信号 | AccountState |
|---|---|
| 401 / 403 | session_dead |
| 429 | rate_limit |
| 402 | quota |
| 404 | unavailable |
| HTTP 0(连不上) | transport |
| WebSocket 报错 | transport(走 onLateFailure) |
| 模型不在列表 | no_such_model(跳过供应商,不惩罚账号) |
| 请求体解析失败 / 空消息 | bad_request(不惩罚账号) |
实现注意事项¶
pull绝不能「空手返回」:ReadableStream 只在上一次 pull 解决且队列空时才再次调用 pull。若 pull 消费了一帧却没有 enqueue 任何东西就返回,读侧的read()会永远挂着。必须循环到「产出数据」或「收尾」才返回。- stream 回调里的
this是 underlying source,不是供应商实例。写this.env.log(...)会让this.env是 undefined → 第一次 pull 抛 TypeError。一律用闭包捕获(const log = this.env.log)。 - 控制器只能 close 一次,统一走带
closed标志的finish(controller)。 - WS 是推模型、ReadableStream 是拉模型,中间必须有队列 +
wake()唤醒,不能 busy-loop。 c_execute_code的代码正文不要逐帧推:component.content阶段是半截代码,等component.end拿完整arguments.code+output一次性渲染。
适用场景与注意¶
适合需要同时获取思考过程、工具调用与真实代码执行输出的场景,尤其是需要将沙箱生成的文件拉回本机的项目。
插件以当前 dsh 进程权限运行,安装前应检查源码与许可证(MIT)。
结尾¶
本插件通过 cowork WebSocket 通道,为 dsh-router 提供了 WPS 灵犀的完整接入能力,包括思考过程、工具调用、真实沙箱执行与文件回传。适合需要强代码执行能力的智能体开发场景。