返回目錄

dsh-plugin-speech

維護狀態: 活躍

nakamuraia/dsh-plugin-speech

为 DeepSeek Harness 的助手回复提供文本转语音,支持多种 TTS 提供商与流式播放。

前往 GitHub專案首頁
$ dsh plugin add dsh-plugin-speech

安裝

dsh 沒有統一的安裝指令 —— 把該外掛 README 中的設定行加入你的 profile / patch 設定,然後重啟即可。

查看安裝教學

5

星數

0

Fork

TypeScript

語言

MIT

授權條款

2026-09-13

建立於

2026-10-26

最近推送

README

dsh-plugin-speech

English | 中文

Read aloud — DeepSeek Harness speech plugin

Read assistant replies aloud in DeepSeek Harness, one continuous voice per reply.

What it does

Each finished assistant message gets a play control in its action row. Press it and the reply is spoken through a text-to-speech service; press it again and it stops. A settings row in General owns the service, the voice, and the tuning.

The whole reply goes out in one request and the host streams the audio back while the service is still synthesizing it. The browser holds back only the first 1.5 seconds of audio — enough to cover the first chunk's jitter — and starts the voice: measured at about one second from the click, with a two-minute reading arriving in under two seconds from then on.

Providers

Service Key needed Voices
Microsoft Edge (default) no the service publishes its full catalog, every language it serves

Adding a provider means adding one folder under src/providers/ and one line in src/providers/registry.ts — the settings screen builds its fields from what the provider declares.

The Edge token

Every handshake carries a short-lived Sec-MS-GEC token: the current time in Windows file-time ticks, rounded down to five minutes, digested together with the well-known client token. In October 2026 the endpoint moved to a second generation of that token — a patched SHA-256 paired with a 64-bit checksum — and began answering the first generation with a bare 403 (Edge TTS WebSocket error: Unexpected server response: 403), which is what a reply that never speaks looks like from the browser. src/providers/edge/gec.ts reproduces the accepted generation; server.ts hands it to msedge-tts by replacing the library's private URL builder, which is also what pins the token version the endpoint now expects. If read-aloud stops working again, test that token first: it is the only part of this plugin that can expire without the code changing.

Requirements

  • A DeepSeek Harness surface — dsh web, or the desktop app — version 0.2.0-rc.2 or newer.
  • Network access to the speech service. Nothing else: there is no model to download, and the Edge provider needs no account.

The version floor is not decorative. The plugin's preferences are its own Cordis entry config, exposed to the settings screen as a form through ctx.configForms. Releases before 0.2.0-rc.2 had plugins register settings namespaces themselves (settings.register) and handed the browser a ctx.settingsScope; both services are gone.

Install

This package declares dsh.bundle.patch, so it installs as a profile bundle: the package manager links it, the launcher appends it to the profile's dsh.profile.bundles, and the bundle's own patch layer inserts the plugin row. Installing also enables it — in DeepSeek Harness, installing a plugin and enabling it in a profile are separate steps, and a bundle collapses the two.

Desktop app — sidebar → Plugins → Add plugin, then give one of:

  • @nakamuraia/dsh-plugin-speech (the npm registry)
  • github:NakamuraIA/dsh-plugin-speech
  • an absolute path to a local checkout

From the CLI — the same operation, profile-scoped:

dsh plugin --profile web add github:NakamuraIA/dsh-plugin-speech

Restart the surface afterwards. The host half claims its HTTP routes when the plugin loads, a desktop profile is owned by the app, and a newly installed out-of-tree bundle is not mounted by a live recomposition — an app-internal row added to a patch does reload immediately, a package that has to come from the profile's node_modules does not.

One-off overlay, without installing

cordis.patch.yml is the same patch the bundle applies, so it also works as a temporary command-line overlay:

dsh web --patch ./cordis.patch.yml

Do not do both. A profile patch that inserts ui-speech while the bundle is selected collides with duplicate loader entry id; the profile layer is for overriding the row's config, which is what the settings screen writes.

The row name is the package name and also the browser module id the built bundle registers under; the row id (ui-speech) is the settings namespace the config form is keyed by. Nothing works if either one drifts, so change the two together.

Settings

Settings opens on General, where a Read aloud row owns:

  • Service — which provider speaks.
  • Language and Voice — the catalog entry to use.
  • Speed, Volume, Pitch — sent to the service with every request.
  • Skip code — leave fenced code and inline code out of the reading.
  • Test voice — speaks a sample through the settings on screen, saved or not.

The row edits the plugin's own entry config, so the chosen values persist in the profile patch beside the entry rather than in a settings document. Resetting a field restores the schema default, and a write the Host refuses leaves the stored value untouched while the row says so.

Tables and pasted spreadsheets are never read, whichever way Skip code is set. That switch decides only whether fenced and inline code are read: with it off, the code itself is spoken and just the fences go. Links keep their label and lose their target; emoji, quotes, and standalone symbols are dropped. Sentence punctuation is kept, because the voice uses it for pauses.

How it works

browser                    host                        service
───────                    ────                        ───────
click ─ ▶ POST /speech/speak { text }
                           select provider from
                           its own entry config
                           ────────────────────────── ▶ synthesize
        ◀ ─ audio bytes stream back ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
play from the first 1.5 s, keep appending behind it

在 GitHub 閱讀完整 README →

DSH Plugins 是獨立的 DeepSeek Harness 外掛目錄,與 DeepSeek 官方無關,也不代表官方背書。第三方外掛未經安全稽核,安裝前請審查原始碼。

每週取得最新的 DeepSeek Harness 外掛,絕不濫發。