← 返回列表
未验证
图像、视频和语音生成,作为 deepseek-harness 工具,由 OpenRouter 提供支持。以树外…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/24 · 已提供中文文档
OpenRouter 图像、视频和语音生成作为 deepseek-harness 工具——一个树外配置文件包,无需 fork
综合分
28.1
GitHub 分
28.1
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add launchmaniac/dsh-media-tools该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/19(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-attachment@deepseek-ai/dsh-credentials@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-llm@deepseek-ai/dsh-settings@deepseek-ai/dsh-tools@deepseek-ai/schemastery用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-media-tools 图像、视频和语音生成,作为 deepseek-harness 工具,由 OpenRouter 提供支持。以树外 profile 包的形式发布——无需 fork harness,无需修改核心。 它注册了什么 | 工具 | 后端端点 | 结果以何种形式到达模型 | |---|---|---| | generate_image | POST /images | 图像本身——提交到附件存储,以图像块的形式返回。同时写入 outputDir,以便人工打开。 | | generate_video | POST /videos + 轮询 | 一个文件路径 | | generate_speech | POST /audio/speech | 一个文件路径,外加一个播放链接 | | transcribe_audio | POST /audio/transcriptions | 转录文本——这里唯一一个向内运行的工具 | 这种划分就是整个设计的核心,而且并非随意为之。harness 的内容词汇表(ContentBlockMap)包含 text、reasoning、image、tool-call 和 tool-result——没有视频,没有音频——而模型路由可能只声明 text 和 image 输入。因此,生成的图像可以重新进入模型上下文,而生成的视频则不能。添加视频或音频块需要修改 harness 本身及其适配器、UI 和压缩消费者,这是任何树外包都无法做到的。 实际后果是:模型永远看不到视频,也听不到音频。 它只知道路径和字节数。正因如此,渲染出的工具结果严格保持事实性——模型无法核实任何关于产物外观或声音的说法。 生成的图像确实会内联显示在 Web UI 中,其实现路径值得你在依赖它之前了解清楚。没有任何 harness 界面会渲染工具结果中的图像——卡片显示的是持久引用,而非像素——并且客户端的 markdown 渲染器只接受来自 http(s) 的图像,拒绝 data: URI 和 file:// 路径。因此,本包会在 harness Web 服务器上,用一个不可猜测的进程本地令牌来提供每张写入的图像,工具结果则将该 URL 交给模型,并指示其将 URL 包含在回复中。 最后一步正是需要注意的地方:显示取决于模型是否遵循该指令。 如果模型忽略它,你只会得到文件路径而没有图片。因此,每张图像也会以真实扩展名写入 outputDir,并且 revealImages: true 会在每张图像生成时在你的桌面查看器中打开它——这两条路径不依赖模型行为。 安装 dsh plugin --profile add @launchmaniac/dsh-media-tools dsh --profile --dump-config # verify the layer without booting 这是推荐的方式:npm tarball 已经附带构建好的 lib/,因此安装时你的机器上不会执行任何内容,也不涉及构建许可。 改为从 GitHub 安装 git 安装获取的是源代码,而非构建产物,因此 pnpm 会运行本包的 prepare 脚本来构建 lib/。pnpm ≥10 拒绝运行 git 依赖的构建脚本,直到你允许它为止,所以第一次 add 会失败,并给出它想要的包键。把它加到你的 profile 的 pnpm-workspace.yaml 中: allowBuilds: "@launchmaniac/dsh-media-tools": true 然后重新运行 add。 npm v12 将 git 依赖与构建脚本分开管控——安装一个还需要 --allow-git,而远程 URL 依赖需要 --allow-remote。npm approve-scripts --allow-scripts-pending 会审查正在等待的内容。这是优先选择上面那种 npm 安装方式的另一个原因:它是一个普通的 registry 依赖,不会触发这些问题中的任何一个。 把这项许可当作它本来的样子:允许在安装时在你的机器上执行这个包的代码,在 agent 运行所在的任何沙箱之外。先阅读源码,并固定一个 commit,这样后续的推送就无法悄悄改变运行的内容: dsh plugin --profile add github:launchmaniac/dsh-media-tools# 如果你不想授予构建许可,可以从一个 checkout 用 pnpm pack 打包成 tarball,然后 dsh plugin --profile add ./launchmaniac-dsh-media-tools-0.1.0.tgz——已预构建,因此不涉及构建权限。 设置你的密钥: export OPENROUTER_API_KEY=sk-or-... 当挂载了 harness 凭据接缝(ctx.credentials)时,密钥会通过它读取,否则回退到进程环境。它是按调用解析的,从不缓存,因此轮换后的密钥会在下一次工具调用时生效。 配置 三个地方,优先级递增。 1. 每次调用,在对话中。 generate_image 接受一个可选的 model,所以你可以说“用 recraft/recraft-v4-vector 生成一个 logo”,它只对该次调用生效。 2. $DSH_HOME/settings.yaml 中的 media-tools 键下。这是实时生效的那个——更改会在下一次工具调用时生效,无需重启: media-tools: imageModel: black-forest-labs/flux.2-pro Settings 对话框的 Open configuration file 按钮可以打开这个文件。该 bundle 通过 installSettingsSection 注册其 schema,因此值在写入时会经过校验。它尚未作为卡片出现在 Settings → Plugins 中:那需要一个用 dsh.client 声明的浏览器端部分,而客户端 bundle 的构建预设并未在 harness monorepo 之外发布。 3. 你的 profile 的 cordis.patch.yml —— 其他所有配置都叠加其上的部署默认值: - id: media-tools name: "@launchmaniac/dsh-media-tools" config: imageModel: bytedance-seed/seedream-4.5 videoModel: bytedance/seedance-2.5 A voice-requiring model must be given one, or every call 400s. speechModel: google/gemini-3.1-flash-tts-preview speechVoice: Kore outputDir: ./media videoTimeoutMs: 900000 | 键 | 默认值 | 含义 | |---|---|---| | apiKeyEnv | OPENROUTER_API_KEY | 保存密钥的环境变量 | | baseURL | https://openrouter.ai/api/v1 | API 根地址 | | attributionTitle | deepseek-harness | 作为 X-Title 发送 | | attributionUrl | — | 作为 HTTP-Referer 发送 | | imageModel | bytedance-seed/seedream-4.5 | 由 generate_image 使用 | | videoModel | bytedance/seedance-2.5 | 由 generate_video 使用 | | speechModel | fish-audio/s2.1-pro | 由 generate_speech 使用 | | speechVoice | — | 默认语音,可在每次调用时覆盖 | | transcribeModel | openai/whisper-1 | 由 transcribe_audio 使用;deepgram/nova-3 和 openai/gpt-4o-transcribe 也可用 | | maxTranscribeBytes | 26214400 | 发送用于转录的最大音频文件 | | outputDir | ./media | 产物写入的位置。相对路径会相对于会话的工作目录解析,因此每个工作区保留各自的目录;绝对路径则将所有内容汇集到一处 | | revealImages | false | 在桌面查看器中打开每张生成的图像 | | requestTimeoutMs | 120000 | 每个 HTTP 请求的预算 | | videoPollIntervalMs | 5000 | 视频任务轮询之间的延迟 | | videoTimeoutMs | 900000 | 单个视频任务的总等待时间 | 补丁会替换某一行的整个 config 值,而不是合并键,因此覆盖时必须重新声明它所需的每一个键。 要求与拒绝 generate_image 在两种情况下会拒绝,而不是降级: - 未挂载附件存储。 该工具注册在 ctx.inject(['attachments'], …) 内部,因此没有附件存储时它不存在。@deepseek-ai/dsh-attachment-local 随 @deepseek-ai/dsh-base 一起提供,因此正常配置文件中会有它。 - 调用模型未声明 image 输入。 生成当前路由无法承载的图像,会把一个块放入持久会话历史中,而该路由无法重放它。拒绝信息会指明模型并提示你切换。 两项检查都在任何 HTTP 请求之前运行,因此拒绝绝不会消耗一次调用。 音频输入:转录 transcribe_audio 是唯一向内运行的工具。没有聊天路由接受音频 输入——ModelModality 仅支持文本和图像——因此转录是录制的 语音到达模型的唯一方式。将它指向一个文件,模型就会读取所说的内容。 提供三种模型:openai/whisper-1(默认)、deepgram/nova-3 和 openai/gpt-4o-transcribe。它们都不出现在普通的 /models 列表中, 就像 TTS 模型一样。 这是基于轮次的,而不是对话。与智能体实时交谈需要在浏览器中进行 麦克风采集,而插件无法触及这一点——那是测试框架侧的改动。 文本转语音:语音与容器 在配置 TTS 之前,有两件事值得了解,它们都是通过运行端点而不是 阅读其文档学到的: - 大多数提供商要求显式的 voice,而语音名称不可 移植。 Gemini TTS 会拒绝无语音的请求,并接受像 Kore 或 Puck 这样的名称(alloy 返回 500)。Deepgram 接受 flux-*-en 名称 并在其错误中列出有效集合。fish-audio/s2.1-pro 在完全没有语音的情况下 进行合成,这就是它成为随附默认值的原因——该工具可以正常工作 开箱即用,并且你有意选择了一个需要语音的模型。 - 原始 PCM 会被重新封装为 WAV。 两个已验证的提供方都会返回 audio/pcm,采样率只出现在媒体类型参数中。按原样写入这些字节是无法播放的, 因此 generate_speech 会前置一个 RIFF/WAVE 头(16 位小端序,采样率和声道数取自媒体类型), 并写入 .wav。非 PCM 音频则原样透传。 选择模型 GET https://openrouter.ai/api/v1/images/models 和 .../videos/models 会列出每个端点当前可用的内容。默认的 /api/v1/models 列表只返回文本输出模型,这就是生成模型不出现在其中的原因。 已知限制 - 视频和音频写入绕过了 ctx.fs 接缝。 产物使用 node:fs 直接写入 outputDir,因此它们不受会话文件系统沙箱或观察策略的约束。这受限于目标是一个由部署配置的单一目录,且绝不是模型提供的路径,但这确实是一个真实的缺口——参见 src/output.ts 中的 FIXME。 - 不支持流式传输。 图像和语音调用会在写入之前将整个产物缓冲在内存中。 - 假定 PCM 为 16 位。 audio/pcm 媒体类型携带采样率和声道数,但不携带采样位宽。观察到的每个提供方都输出有符号 16 位小端序;如果有提供方输出 24 位或 32 位,生成的 WAV 会以错误的速度播放,而不是直接失败。参见 src/output.ts 中的 PCM_BITS_PER_SAMPLE。 - 视频内容过滤器会基于音轨进行拒绝。 即使视觉提示词无害,generate_audio: true 请求也可能因版权拒绝而失败。如果你一直遇到这种情况,请传入 generate_audio: false。 - 视频任务的生命周期会超过其超时时间。 当 videoTimeoutMs 到期时,该工具会报告超时并指明任务 id;任务会在服务端继续运行,且该 id 仍可轮询。 - 配置在加载时读取,而非实时读取。 该插件只读取其配置节一次。如果你想要实时编辑,请接入来自 @deepseek-ai/dsh-settings 的 installSettingsSection。 - 不生成声明文件。 prepare 必须在 git 安装环境中工作,此时 peer 依赖可能无法解析,因此 tsdown 以 dts: false 运行。在已安装 peer 依赖的检出中运行 pnpm typecheck 以获得真实的类型信号。 开发 pnpm install pnpm check # 对纯辅助函数进行自检;不需要密钥,也不需要 peer 依赖 pnpm typecheck # 真实的类型信号;需要安装 peer 依赖 pnpm build pnpm check 会测试唯一没有请求覆盖的分支逻辑——扩展名选择、文件命名,以及可重放安全的呈现器收窄。它可以独立运行,因为 src/output.ts 没有运行时 peer 导入。 许可证 MIT
扫码进群