dsh-record: Add a recording button to the DSH input box, attach the recording directly to the prompt after recording.

Preface

When implementing voice input for DSH / Agent clients, the common practice is to attach an external recording tool, export the file manually, and upload it. This involves switching windows, finding paths, and waiting for APIs. dsh-record consolidates this process into the input box: add a microphone button in the composer. Click to start recording, click again to stop. The recording is attached directly to the current prompt as a conversation attachment and sent with the normal upload queue. The output format is selected in the plugin settings page, supporting MP3 (default), WAV, and WebM.

Below is an introduction to this plugin. It is maintained by most-silence, under the MIT open-source license. The repository is https://github.com/most-silence/dsh-record, and the community directory page is https://www.skillhub.cn/plugins/most-silence/dsh-record.

What it can do

One-sentence positioning: A client-side plugin that adds a recording button to DSH’s composer, attaching the audio file as a conversation attachment to the current prompt after recording. It is only responsible for recording, transcoding, and mounting; it does not write disk files or perform speech recognition—if text conversion is needed, a separate speech-to-text plugin is required (README suggests dsh-stt).

Verified capabilities:

  • The button is registered in the conversation.input.right slot, before the submit action, with no popup window, and can coexist with other composer controls.
  • Output formats mp3 / wav / webm, default mp3, selectable in Settings → Plugins → dsh-record.
  • Hover tooltips follow the interface language: Chinese shows “录音”, English shows “Record”. The button registers zh / en dictionaries with the host locale service; after switching languages, tooltips, aria-labels, and status notifications update accordingly.
  • Recording uses the browser’s MediaRecorder, prioritizing webm/opus with fallbacks based on capability. There is a timer and filename preview during recording (rec-YYYYMMDD-HHMMSS-<n>s.mp3).
  • All three formats are processed in the browser: MP3 is encoded by lamejs (128 kbps CBR), WAV is a lossless re-wrap of 16-bit PCM, and WebM is the browser’s native Opus container without transcoding.
  • Mounting uses the host draft-attachment channel (conversation.createDrafts + inputActions.addAttachments), displayed as a file card in the input box with upload progress.
  • If transcoding fails (e.g., OfflineAudioContext unavailable), the original WebM is mounted directly to ensure the recording is not lost.

Installation and Enablement

The installation command provided in the README is to add it by file path after local building, not to pull a package from the registry:

git clone https://github.com/most-silence/dsh-record
cd dsh-record && npm install && npm run build
dsh plugin --profile <your-profile> add file:$PWD

After installation, restart the DSH host and refresh the webpage. You can rebuild using npm run build (tsdown produces lib/index.js and lib/client.js), and run npm test to execute 14 node:test cases (9 client factory contracts, 5 encoders). Tests run on Node 24 and do not require a browser.

Configuration

There is only one configuration field, changed in Settings → Plugins → dsh-record:

Field Value Meaning
format mp3 (default) · wav · webm Output container. MP3 / WAV are transcoded in the browser after recording stops, WebM is mounted as-is. Changes take effect on the next page load, as the browser-side configuration is only read once at startup.

The browser reads this configuration via GET /dsh-record/config on startup; if the route is unreachable, it falls back to mp3.

Architecture and Two Pitfalls

The plugin follows a typical frontend + host two-part architecture:

browser half (lib/client.js)               host half (lib/index.js)
├─ mic button @ conversation.input.right   ├─ Config schema { format: mp3 | wav | webm }
├─ zh/en dictionaries → locale service     └─ GET /dsh-record/config → serves resolved config
├─ MediaRecorder → webm/opus                  (same-origin guarded)
├─ decode → lamejs (mp3) / PCM wrap (wav)
└─ attach via createDrafts + addAttachments

The README specifically notes two reinforcement rules learned from real crashes, which are worth copying for similar plugins:

  1. @breezystack/lamejs must be bundled inline. DSH’s module table is frozen and does not contain lamejs. If treated as an external build dependency, require("@breezystack/lamejs") will fail to find the module table and cause the entire web startup to crash. The build tool tsdown uses noExternal to force inlining.
  2. The host’s Config uses z.union([...]) and cannot use z.enum([...]), while schemastery is kept external. The host’s built-in schemastery version does not have the enum method, and the private copy of schemastery bundled with the plugin is incompatible with the host’s validator. Either of these will throw an error during the import phase, flagging this plugin as required and crashing the entire profile.

Notes

  • This plugin runs with the permissions of the current DSH process. It is recommended to read the source code before installing third-party plugins, and pay attention to its open-source license (this project is MIT).
  • The attachment channel depends on the host client contract; the README verified version is dsh 0.2.1-rc.2 (conversation.input.right slot, createDrafts / addAttachments). It may degrade to inline error messages after changes to upstream interfaces.
  • Transcoding happens after recording stops, not in real-time during recording, so very long recordings will have a short encoding wait.
  • Recording requires browser microphone permission, and the page must run on HTTPS or localhost.
  • The output format is placed in the host profile configuration, not in the browser, so changes take effect only after refreshing the page.

Summary

dsh-record solves a very specific pipeline problem: record in the input box → transcode in the browser → upload as a prompt attachment, without touching disk or performing recognition. If you are already using DSH for client-side voice input, you can first install it in a test profile to try it out, confirm that the attachment channel and format meet expectations, and then consider integrating it into the formal process.

  • Directory page: https://www.skillhub.cn/plugins/most-silence/dsh-record
  • Code repository: https://github.com/most-silence/dsh-record
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye