前言¶
在 DSH 裏做長循環任務時,經常會遇到一件事:某條要求要跟着整個對話走,比如「只輸出中文」「表格必須帶單位」「這份文檔用 Word 格式輸出」。目前的常見做法是把這類要求寫進第一條消息,或者反覆在後續消息裏重複提醒。第一條做法容易被模型在長對話中遺忘,第二種做法會增加每輪輸入的噪聲。
sunlei1214/dsh-session-requirement(版本 1.1.0,MIT 許可證)就是爲此設計的:它在 DSH 的對話標題欄右側提供一個輸入框,讓你寫下針對「當前這個對話」的整體要求,並可以用 @ 挑選技能,然後由插件把這段內容附加到該對話的每一條消息上。更適合用在工作流類場景。
這是什麼¶
一句話定位:一個掛在對話標題欄上的「對話級約束框」,只負責選擇、存儲和轉發,不負責執行。
它解決的痛點是:把跨多輪的固定要求從消息正文裏抽出來,交給插件統一注入。要求文本和所選技能都按對話維度存儲,切換對話即清空,新對話默認是空的、開關也是關的。
需要注意兩點:
- 本插件運行在當前 DSH 進程的權限下,安裝範圍即意味着信任邊界。
- 技能來源不是本地硬編碼清單,而是通過
ctx.remote.skills.list讀取 harness 的實時技能註冊表,因此沒有可用技能時不會僞造列表,而是提示當前無目錄。
核心功能¶
下面介紹 README 中明確列出的能力。
一個全局開關,控制整個框的顯隱¶
開關位於 Settings → General → 本對話的整體要求,狀態寫在全局 state 文件中。安裝後默認關閉;打開時所有對話的標題行立刻出現輸入框,無需刷新或重啓;關閉時標題行完全沒有預留空位。
兩種尺寸,標題行爲固定高度¶
收起狀態是標題行右側的一行,尺寸固定 380px × 28px,因此標題行不會發生迴流。聚焦時輸入框浮起爲 470px 的浮動卡片,覆蓋在 tab 行上方,標題欄本身不增高。
空白對話場景下,標題行的邊欄原本不渲染,插件會把同一份字段登記到 conversation.input.dock(order: -100),在標題行出現前先顯示在輸入框 dock 中;註冊表保證屏幕上只有一份實例。
要求文本 + @ 技能選擇¶
- 文本框和技能 chips 都是按對話存儲的。
- 在行首或空白後輸入
@打開技能選擇器,按名稱、描述和whenToUse過濾。↑/↓移動,Enter選中,Esc關閉,點擊也可選中;結果爲空或加載失敗時顯示行內提示,不破壞輸入。 - 選中的技能變成不可編輯的
@name ×chip,點擊×移除;輸入框爲空時按Backspace移除最後一個;重複項被忽略;上限爲maxSkills(默認 10)。
按條件附加到每條消息¶
附加動作發生在服務端的 agent/pre-step。客戶端的 conversation.send() 是純透傳,沒有可供鉤掛的發送前轉換,因此持久化、模型可見的接入點選在這一步:噹噹前消息批次裏含真實用戶消息時(也就是新的一次發送,而非工具循環的後續步驟),插件會追加一條 user/message:
<session_requirement>
The user set a standing requirement for this whole conversation. Apply it to every reply until the user changes it.
<requirement>…</requirement>
<selected_skills>office-docx, office-xlsx</selected_skills>
</session_requirement>
<skill_content name="office-docx">…</skill_content>
它走 harness 自己的 surfaceOp: "append" 路徑提交,source.kind = "session-requirement",因此像內置 /skill 調用一樣出現在對話記錄裏,不會僞裝成一次用戶動作。
同時生效的條件是:GUI 開關打開、該對話的開關打開、內容有效(requirementText.trim().length > 0 || skillIds.length > 0)。
整條對話的開關行爲如下:無內容時顯示灰色,點擊會聚焦輸入框;第一次出現有效內容時自動變爲打開;手動關閉後仍保留文本和技能,但不再附加;清空所有內容後開關重新變灰。
插件本身不執行技能,只做選擇、存儲和轉發,模型收到技能正文後自行決定如何處理。
安裝與啓用¶
README 給出的安裝方式是克隆後通過 link: 指向檢出目錄。
git clone https://github.com/sunlei1214/dsh-session-requirement.git
然後改 profile 的 package.json:
// <DSH_HOME>/profiles/<profile>/package.json
"dependencies": { "dsh-session-requirement": "link:C:/path/to/dsh-session-requirement" },
"dsh": { "profile": { "bundles": [ …, "dsh-session-requirement" ] } }
改完後需要重新安裝 profile 並重啓 DeepSeek Harness。瀏覽器那半部分是靜態客戶端 bundle,只刷新頁面是不夠的。
README 特別提醒要用 link: 而不是 file::pnpm 會複製 file: 目錄依賴並做緩存,後續修改不會同步到 profile;link: 創建 junction(Windows)或 symlink,profile 始終讀取當前源碼。
卸載時移除依賴和 bundle 條目,重新安裝並重啓。插件會註銷路由、agent/pre-step 監聽器、文檔監聽器、防抖定時器和緩存,並中止在途請求。刪除 <DSH_HOME>/session-requirement.json 是可選操作。
配置與命令¶
配置項只有兩個:
| 選項 | 默認值 | 含義 |
|---|---|---|
maxSkills |
10 |
單個對話最多可選的技能數 |
maxTextLength |
8000 |
要求文本的最大長度 |
命令有兩個:
/requirement打印當前對話的狀態。/requirement clear清空內容並關閉當前對話的開關。
HTTP 接口與狀態文件¶
| 路由 | 用途 |
|---|---|
GET /api/session-requirement?sessionId=… |
讀取一個對話的狀態(同時返回 visible) |
GET /api/session-requirement?mode=settings |
只讀取 GUI 開關,不涉及對話 |
POST /api/session-requirement |
寫入一個對話的狀態:{ sessionId, requirementText, requirementEnabled, skillIds } |
POST /api/session-requirement { visible } |
單獨翻轉 GUI 開關 |
狀態寫在 <DSH_HOME>/session-requirement.json,採用 .tmp + rename 的原子寫方式:
{
"version": 1,
"settings": { "visible": false },
"sessions": {
"session-…": { "conversationId": "session-…", "requirementText": "", "requirementEnabled": false, "skillIds": [], "updatedAt": 0 }
}
}
當 sessionId 格式非法、文本超過 maxTextLength、或 skillIds 不是去重後且不超過 maxSkills 個技能名時,請求直接返回 400,不做靜默修正。
適用場景與注意¶
適合這幾類情況:
- 需要在一次長對話裏反覆強調固定約束的寫作或表格任務。
- 希望按對話切換約束、而不是一條全局約束覆蓋所有任務的用戶。
- 工作流類場景:把技能挑選和整體要求放在同一處管理。
要求與限制也要說清楚:
- 運行環境要求 DeepSeek Harness 0.2.x(桌面版或 Web 版)、Cordis v4。
- 無任何 npm 依賴,host 端只用 Node 內置模塊,瀏覽器端是手寫 CJS bundle,
react從 harness loader 獲取。 - 插件以當前 DSH 進程權限運行,安裝第三方插件前應先檢查源碼與許可證(本倉庫爲 MIT)。
- 本地跑測試可以直接執行
node test/host-check.mjs和node test/client-check.mjs;如果 PowerShell 執行策略攔截了npm.ps1,按 README 說的直接運行這兩個文件即可。兩個測試都是在真實源碼上搭的離線 harness,不需要安裝 harness。
結尾¶
這個插件的價值不在於新增了什麼執行能力,而在於把「對話級要求」從消息正文中剝離出來,用統一接口注入到每一輪請求,並保留技能引用的可追溯性。如果你在 DSH 裏做長流程任務時需要跨輪約束,可以先把源碼和許可證過一遍再裝。
目錄頁:https://www.skillhub.cn/plugins/sunlei1214/dsh-session-requirement
代碼倉庫:https://github.com/sunlei1214/dsh-session-requirement