本地创作工具箱:连接本机 ComfyUI 出图、连接本地 GPT-SoVITS 配音,检查服务是否在线,并把生成的文件保存到工作区。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:vamyane/dsh-local-studio
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DeepSeek Harness 的本地创作面板:把 ComfyUI 变成侧栏里的「出图」按钮,把 GPT-SoVITS 变成「配音」按钮,生成的文件都留在本机目录。
插件不上传提示词/图片/音频,也不调用任何云端付费 API。
功能
- 侧栏入口 + 全屏面板:React 直接渲染(没有 iframe),跟随 DSH 主题深浅色,
Esc关闭。 - 健康状态点:ComfyUI 与 GPT-SoVITS 各 3 秒超时探活;鼠标悬停能看到具体原因 (连接被拒绝 / 超时 / …)和修复建议。
- 出图:提示词 / 宽 / 高 / 步数 → ComfyUI
/prompt→ 轮询/history/{id}→ 下载/view→ 存到outputs/local-studio/image-<时间戳>.png,面板里直接预览。 - 配音:文本(可选参考音频)→ GPT-SoVITS
/tts(先 GET,失败自动回退 POST)→ 存voice-<时间戳>.wav,面板里直接试听。 - 最近输出:输出目录里最新的 30 个图片/音频,带缩略图 / 试听和「复制路径」。
- 错误一定友好:所有路由失败都返回
{ "error": "...", "hint": "..." }+ 4xx/5xx; ComfyUI 没启动、模型名写错都不会把宿主搞崩。
环境要求
| 组件 | 版本 | 说明 |
|---|---|---|
| DeepSeek Harness | >= 0.2.2-rc.1 < 0.3.0-0 |
用到 connection 的 Fetch 路由服务 |
| Node.js | >= 20 |
DSH 运行时已经满足 |
| ComfyUI | 可选 | 默认 http://127.0.0.1:8188 |
| GPT-SoVITS | 可选 | 它的 api.py 服务,默认 http://127.0.0.1:9880 |
两个服务都可以不装:面板照样能打开,只是顶部状态点会告诉你该启动什么。
内置工作流用的是 Animagine XL 3.1(animagine-xl-3.1.safetensors);换 comfyCheckpoint
或提供自己的 comfyWorkflow 就能用别的 SDXL 模型。
安装
npm pack
dsh plugin --profile desktop add ./dsh-local-studio-0.1.0.tgz
本地开发也可以用 link 方式(参考 ai-brain/dsh-plugin/install.mjs):把本目录复制到
<profile>/local-plugins/dsh-local-studio,在 profile 的 dependencies 里加
link:./local-plugins/dsh-local-studio,把 dsh-local-studio 追加到 dsh.profile.bundles,
跑一次 pnpm install,然后重启 DSH。
重启后左侧栏底部出现 🎨 本地创作,点开就是面板。
配置
~/.dsh/local-studio.config.json 是可选的:不存在时直接用默认值,插件不会主动创建文件。
{
"comfyUrl": "http://127.0.0.1:8188",
"comfyCheckpoint": "animagine-xl-3.1.safetensors",
"comfyWorkflow": "",
"ttsUrl": "http://127.0.0.1:9880",
"ttsRefAudio": "",
"ttsPromptText": "",
"ttsPromptLang": "zh",
"outputDir": ""
}
| 字段 | 说明 |
|---|---|
comfyUrl |
ComfyUI 地址;填 "" 表示禁用(出图路由返回 501)。 |
comfyCheckpoint |
CheckpointLoaderSimple 的 ckpt_name,必须和 ComfyUI/models/checkpoints 里的文件名一致。 |
comfyWorkflow |
可选:自定义 ComfyUI API 格式工作流 JSON 的绝对路径,支持下面的占位符。 |
ttsUrl |
GPT-SoVITS 地址;填 "" 表示禁用(配音路由返回 501)。 |
ttsRefAudio |
可选:默认参考音频(本机绝对路径)。 |
ttsPromptText / ttsPromptLang |
可选:参考音频的 prompt_text / prompt_lang。 |
outputDir |
输出目录;留空 = <workspace>/outputs/local-studio。 |
环境变量覆盖(测试用,排查问题时也方便):
DSH_LOCAL_STUDIO_CONFIG:配置文件路径DSH_LOCAL_STUDIO_OUTPUT:覆盖outputDirDSH_WORKSPACE:覆盖工作区解析
内置工作流(也随包提供 app/workflow.json)支持这些占位符:
{{PROMPT}} {{NEGATIVE}} {{WIDTH}} {{HEIGHT}} {{STEPS}} {{SEED}} {{CHECKPOINT}}。
自定义工作流可以用它们,也可以把参数全部写死。
HTTP 接口
所有路由都挂在 DSH 带登录态的共享 /api 通道上(connection.fetch.register),
Host/Origin 栅栏与登录态在进入 handler 之前就已经校验。除 /file 外响应都是 JSON;
失败统一是 { "error": "...", "hint": "..." } + 4xx/5xx。
GET /api/dsh-local-studio/health
{
"ok": false,
"comfy": { "ok": false, "detail": "/system_stats → 连接被拒绝(服务可能没启动);/queue → …", "hint": "…", "url": "http://127.0.0.1:8188" },
"tts": { "ok": true, "detail": "HTTP 200 · 根路径可达", "url": "http://127.0.0.1:9880" },
"config": { "comfyUrl": "…", "ttsUrl": "…", "comfyCheckpoint": "…", "outputDir": "…", "configFile": "…", "configExists": false },
"warnings": [],
"version": "0.1.0"
}
两个探活各自 3 秒超时。
POST /api/dsh-local-studio/image
请求:{ "prompt": "1girl, cherry blossoms", "width": 1024, "height": 1024, "steps": 28 }
(宽高必须是 8 的倍数、256–2048;步数 1–80;seed 可选)。
响应:{ "file": "C:\\…\\image-20261108-135732.png", "name": "…", "width": 1024, "height": 1024, "bytes": 123456, "promptId": "…", "elapsedMs": 8123, "seed": 123456 }
流程:POST /prompt → 每 1 秒轮询 GET /history/{prompt_id}(最多 90 秒)→ GET /view
下载 → 存 PNG 到 outputDir。
POST /api/dsh-local-studio/tts
请求:{ "text": "你好,世界", "refAudio": "D:\\voices\\ref.wav" }(refAudio 可选;
文本最多 2000 字)。
响应:{ "file": "…/voice-20261108-135800.wav", "name": "…", "bytes": 123456, "mediaType": "audio/wav", "chars": 6, "ms": 1830, "mode": "GET" }
调用 GET {ttsUrl}/tts?text=…&text_language=zh&text_lang=zh&media_type=wav…;如果这个端点
不被接受(404/405/422),自动改用 POST {ttsUrl}/tts + JSON body 重试一次。
ttsUrl 显式留空时返回 501 并给配置提示。
GET /api/dsh-local-studio/outputs
{ "dir": "…\\outputs\\local-studio", "count": 3, "limit": 30, "files": [ { "name": "image-…png", "path": "…", "size": 123, "mtimeMs": 1762…, "kind": "image", "ext": "png" } ] }
只列 .png/.jpg/.jpeg/.webp/.wav/.mp3/.ogg/.flac,按 mtime 倒序,最多 30 个。
GET /api/dsh-local-studio/file?name=image-…png
按正确 content-type 返回原始字节。只接受 outputDir 里的裸文件名
(..、路径分隔符、控制字符一律 400)。
面板
| Tab | 内容 |
|---|---|
| 🖼️ 出图 | 提示词 + 宽/高/步数、生成、实时计时、预览、复制路径 |
| 🔊 配音 | 文本 + 可选参考音频、生成、内嵌 <audio> 试听、复制路径 |
| 🗂️ 最近输出 | 最新 30 个文件列表,点一下就能预览图片/试听语音、复制路径 |
顶部是两个健康状态点(ComfyUI / TTS)和刷新按钮;底部显示解析后的输出目录。
构建与测试
node build.mjs # app/workflow.json 经 gzip 内嵌成 lib/workflow.data.js,
# app/panel.css 内嵌进 lib/client.js,并校验包名一致性
npm test # smoke + unit + mock
npm run pack:check # npm pack --dry-run
test/smoke.mjs:离线结构测试——用桩件加载构建产物lib/client.js,验证__ModuleLoader__.load的 id、两个槽位注册与可渲染、宿主半边能导入且注册五条路由、 内嵌的 gzip 工作流能解回合法 JSON,以及package.json/cordis.patch.yml/图标/README/LICENSE 的一致性。test/unit.mjs:不依赖网络的单测——服务没启动时/health返回友好的{ok:false, detail}、/outputs的排序与上限、参数校验、TTS 禁用时的 501、 路径穿越防护、占位符替换、PNG 头解析。test/mock.mjs:在本机起一个假 ComfyUI + 假 GPT-SoVITS(127.0.0.1,离线),跑完整链路: 探活 → 提交工作流 → 轮询 history → 下载并落盘 PNG → TTS 的 GET 与 POST 回退 → 落盘 WAV → outputs 列表 →/file读回;另外验证node_errors和status_str=error两条错误分支。
本仓库没有在真实 ComfyUI / GPT-SoVITS 上实测:mock 覆盖了协议和错误分支,但模型名、 生成耗时、显存行为需要真机确认。出问题先看面板健康点的悬停提示——它会指出 URL 和底层 socket 错误。
已知限制
- 一次一张图;批量/队列管理交给 ComfyUI。
- 内置工作流只有一条 SDXL 文生图链路;LoRA、ControlNet、放大、视频请用
comfyWorkflow。 - 提示词最多 2000 字,配音文本最多 2000 字。
- 出图请求最多同步等 90 秒;面板上有实时计时。
- 主要在 Windows 上开发(路径按宿主返回原样显示)。
许可证
MIT,见 LICENSE。
链接
同类插件
liustack/modlens★ 4725
为纯文本模型架起视觉桥梁:粘贴图片,输出结构化 JSON 证据(OCR、版面、语义)。
ysr666/dsh-vision-router★ 1211
为纯文本 Agent 提供视觉能力:内置免 Key 视觉链 + 像素级视觉工具(看图问答、定位、裁剪、像素对比、取色、OCR、矢量化、抠图、截图);粘贴图片即可用。
Anionex/dsh-vision-toolkit★ 922
让纯文本模型处理视觉任务:粘贴图片后自动切换到 Vision Toolkit 变体,支持图片问答、多图比较、长截图 OCR、截图还原前端 UI、元素定位与像素对比。默认无需 API Key——图片经作者自建的免费服务处理,每台机器每天 100 张;也可改为指向自己的服务商。
SAOS-3624/dsh-video-storyboard★ 384
把视频(本地文件,或 B 站 / yt-dlp 链接)压成一张可寻址的宫格图:每格烧编号、对应精确时间、挂台词,底部还有同时间轴的音频包络;video_zoom 可对任意窗口高清重看——纯文本模型因此能「看」视频,而不是读别人写的摘要。
dickpy/dsh-imagegen★ 167
面向 DSH Web GUI 的 AI 生图插件:通过可配置的 OpenAI 兼容端点(gpt-image-2 / gpt-image-1 / dall-e-3)实现文生图与图生图,提供 api_url/api_key 设置卡片与侧边栏分栏生图工作台。
fandc520/dsh-comfyui★ 159
让 DeepSeek Harness 的 Agent 直接驱动本地或远程 ComfyUI:comfyui_run / comfyui_object_info / comfyui_workflow 工具生成与编辑图像、视频,附带工作流库(图工作流提取:按分量 / 主流程 / 整体)、加载区分辨率自动匹配、实时队列、SDXL 与 Wan 2.1 模板、配套 skill 与同源媒体代理。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。