WASD258-jpg/dsh-preset-force
Force-switch the agent preset (mode) of a DSH session after it has started, bypassing the blank-only lock. /preset command, set_agent_preset tool, composer dropdown.
これは DeepSeek Harness(DSH)プラグインです。当サイトは GitHub README、インストール情報、メンテナンス状況、公開セキュリティシグナルをまとめています。
dsh-preset-force
English | 中文
强制切换 DSH 会话的 agent preset(模式)——即使会话已经开始。绕过「仅空白会话可切换」的内置锁定,会话中途即可从极简切到标准(或任意 preset)。三个入口:/preset 命令、set_agent_preset 工具、输入框工具行的紧凑模式下拉。
社区项目——非 DeepSeek 官方插件,不代表 DeepSeek 的任何背书。
功能特性
- 任意会话随时可切 —— 不要求会话为空;网关的
agent-preset-locked拒绝被设计性地绕过 /preset命令 —— 在输入框敲/preset列出当前模式与全部可用模式,或/preset <id>强制切换当前会话set_agent_preset工具 —— 模型可应你的要求切换模式;注册在宿主平面,所有 preset 下都可见- 输入框工具行下拉 —— 注入
conversation.input.right槽位的紧凑模式选择器,位于模型选择器旁;每 5 秒自动刷新,选中即切换 - 会话日志一致 —— 追加与网关相同的
agent-preset/selected事件:头部标签刷新、冷读回放按切换后的组装重建(「模型可见 ⟺ 已落日志」不变量) - 安全护栏 —— 只允许切换顶层会话,子代理一律拒绝;HTTP API 仅限回环并做 Host 头校验
安装
需要 DSH web profile(@deepseek-ai/dsh-web-app)。
-
克隆或下载本仓库:
git clone https://github.com/WASD258-jpg/dsh-preset-force.git -
安装进 DSH profile 依赖目录(二选一;Linux/macOS 用
~/.dsh或$DSH_HOME替代$env:USERPROFILE\.dsh):Option A:npm 安装(推荐)
cd "$env:USERPROFILE\.dsh\profiles" npm install @wasd258/dsh-preset-force --no-saveOption B:从源码复制
$src = '.\dsh-preset-force' $dst = "$env:USERPROFILE\.dsh\profiles\node_modules\@wasd258\dsh-preset-force" New-Item -ItemType Directory -Force -Path "$dst\lib" | Out-Null Copy-Item "$src\package.json" $dst -Force Copy-Item "$src\lib\index.js","$src\lib\client.js" "$dst\lib" -Force Copy-Item "$src\LICENSE","$src\NOTICE" $dst -Force -
把包注册为 profile 的 bundle(或运行
dsh plugin --profile web add @wasd258/dsh-preset-force):在$DSH_HOME/profiles/<profile>/package.json的dsh.profile.bundles数组追加包名:{ "name": "dsh-profile-web", "private": true, "dependencies": {}, "dsh": { "profile": { "bundles": [ "@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@wasd258/dsh-preset-force" ] } } } -
重启 DSH web(或热装配 bundle,免重启),然后刷新浏览器页面,让客户端模块(
lib/client.js,web 平台立即加载)生效。
使用
/preset 命令
直接在输入框敲。无参数(/preset、/preset list、/preset ls、/preset ?)时列出当前模式与全部可用模式:
当前模式:standard(标准模式)
可用模式:
minimal(极简模式)
standard(标准模式) ← 当前
code(代码模式)
cordis(创造模式)
my-custom(我的自定义模式)
用法:/preset <模式id> —— 强制切换当前会话的模式(不要求会话为空,工具集立即更换)
带参数:
> /preset code # 切换
已强制切换当前会话模式:standard → code。模型可见的工具与提示词已更换;已产生的历史记录保持原样。
> /preset code # 已经是目标模式
当前会话已经是模式 code。
> /preset bogus # 失败
切换失败:<原因>
set_agent_preset 工具
模型按你的要求调用;工具注册在宿主层,工具注册表按 agent → preset → global 解析,因此每个 preset 下都可见。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
preset | string | 是 | 目标模式 id(standard / minimal / code / cordis,或本地自建 id);传 "" 列出可用项 |
{ "preset": "code" } // → { "ok": true, "from": "standard", "to": "code" }
{ "preset": "" } // → { "ok": true, "unchanged": true, "available": [ { "id": "minimal", "name": "极简模式" }, ... ] }
// 子代理调用 // → { "ok": false, "error": "set_agent_preset 只能切换顶层会话的模式,子代理不可切换。" }
返回结构:{ ok, from?, to?, unchanged?, available?, error? }。
输入框工具行下拉
紧凑模式选择器位于输入工具行(conversation.input.right 槽位,order 10,标签「模式切换」),紧挨模型选择器:
- 点开下拉,所有可用模式以
名称 (id)形式列出。 - 选中即切换,立即生效。
- 失败时弹出浏览器提示,并回退到原模式。
下拉每 5 秒轮询一次 /status(任何入口导致的模式变化都会反映出来);切换进行中、会话不在运行、或未装配 presets 时禁用(无 presets 时显示一个禁用的「模式」项)。
HTTP API
宿主在 /api/dsh-preset-force 前缀下注册路由:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /status | 查询会话当前模式 + 可用列表(?sessionId=) |
| POST | /switch | 强制切换会话,请求体 {"sessionId","preset"} |
GET /api/dsh-preset-force/status?sessionId=xxx
| 参数 | 位置 | 说明 |
|---|---|---|
sessionId | query | 要查询的会话 |
响应——current 为当前组装的 preset id,available 每项携带 { id, name, trust, broken }:
{ "ok": true, "live": true, "sessionId": "s-abc123", "current": "standard",
"available": [ { "id": "standard", "name": "标准模式" }, { "id": "minimal", "name": "极简模式" } ] }
会话不在运行时 live 为 false,省略 current:{ "ok": true, "live": false, "sessionId": "s-ghost", "available": [ ... ] }。
POST /api/dsh-preset-force/switch
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
sessionId | string | 是 | 要切换的会话 |
preset | string | 是 | 目标模式 id |
// 请求
{ "sessionId": "s-abc123", "preset": "minimal" }
// 响应
{ "ok": true, "from": "standard", "to": "minimal", "sessionId": "s-abc123" }
// 已是目标模式
{ "ok": true, "unchanged": true, "from": "minimal", "to": "minimal", "sessionId": "s-abc123" }
错误情况
| 状态码 | 条件 | error 内容 |
|---|---|---|
| 403 | 非回环源地址 | preset-force API is loopback-only |
| 403 | Host 头不是当前端口的 127.0.0.1 / localhost / [::1] | invalid host header |
| 403 | 跨源页面发起的写请求 | cross-origin request rejected |
| 415 | Content-Type 不是 application/json | Content-Type 必须是 application/json |
| 400 | 请求体不是有效 JSON(超过 64 KiB 的请求体会被提前拒绝) | 请求体不是有效 JSON |
| 404 | 会话不在运行中 | 会话 <id> 不在运行中,无法切换 |
| 404 | 未知路由 | unknown route: <route> |
| 500 | 宿主侧意外错误 | 错误消息字符串 |
工作原理
lib/index.js(宿主半部)注入commands, tools, agentPresets, agents, webServer,注册/preset命令、set_agent_preset工具与 HTTP 路由。- 网关 RPC(API 代理里的
agentPresets.select)在传输层做sessionBlank()检查;recompose()服务本身不检查("由调用方负责该检查")。本插件因此在宿主平面直接调用ctx.agentPresets.recompose(agent.ctx, id)并追加agent.session.append("agent-preset/selected", { agentPreset })—— 与网关 RPC 的唯一差别就是跳过空白检查。 dsh-agent-presets把该事件重发为不带 scope 的 cordis 事件:客户端头部标签刷新、冷读回放重建切换后的组装——「模型可见 ⟺ 已落日志」不变量成立。set_agent_preset有守卫:调用方必须是存活 agent、必须是该会话自己的活跃驱动、必须是根会话(ctx.agents.roots());子代理一律拒绝。lib/client.js(web 半部)注入conversation.input.right槽位渲染下拉;每 5 秒轮询/status,选中即 POST/switch。- HTTP 路由仅限回环:源地址必须是
127.0.0.1/::1,Host 头必须是当前端口的回环主机名(防 DNS rebinding,GET/POST 一视同仁);写操作额外要求同源 +application/json。
隐私与安全
- 无外部网络请求、无遥测、不碰凭据;数据不离开本机
- API 仅限回环(源地址 + Host 头双重校验):即使 DSH 绑定
0.0.0.0,本插件的 API 也不会暴露到局域网/公网 - 写操作额外要求
Content-Type: application/json且浏览器请求同源,阻断恶意网页的跨站切换 - 威胁模型:本 API 设计上无鉴权,只服务本机——任何本地进程都能读取并驱动写操作。请在可信的本机环境运行 DSH
兼容性
- DeepSeek Harness web profile,官方仓库 commit
47f9438时代的 bundle 接口 - Node.js >= 22.19.0(
package.jsonengines)
注意事项:
- 会话中途切换会立即改变模型可见的工具 schema:旧 preset 的工具消失、新 preset 的工具出现;历史中新模式不具备的工具调用重放可能失败——建议在轮次之间切换;能力超集方向(
minimal→standard)最安全 - 只允许切换顶层会话,子代理拒绝
- 客户端模块依赖 DSH web UI 槽位体系(
@deepseek-ai/dsh-client-ui-*);安装后需刷新浏览器
官方生态要求
按 DeepSeek Harness CONTRIBUTING,官方仓库不接受外部 PR;社区插件放在各自仓库并添加 dsh-plugin topic 便于发现。本仓库遵循此约定:独立社区项目,与 DeepSeek 无隶属或背书关系。
许可
セキュリティとインストールエビデンス
このスコアは公開リポジトリメタデータと当サイトに登録されたインストールエビデンスのみに基づくもので、コードセキュリティ監査とは異なります。
公開プラグインカタログから取得し、公開 GitHub リポジトリにリンクしています。
GitHub メタデータにライセンスが検出されませんでした。
過去180日以内にコードの更新があります。
再現可能な正確なインストールメタデータはまだ登録されていません。リポジトリの説明に従って手動で確認してください。
確認したパッケージメタデータにインストールライフサイクルスクリプトは宣言されていません。
missing-license