Bundle
dsh-persona-anchor
Pin a persona prompt section that never competes for the AGENTS.md instruction budget
- Source
- harmless0819-dev
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# dsh-persona-anchor
把「人设」文本钉进 system prompt,且**不吃 AGENTS.md 的指令预算**。
- 插件类型:DSH host plugin(web profile),无客户端半边
- 依赖:仅 node 内置模块
- 状态:自用插件,已在本机跑通
## 为什么需要它
人设原本写在全局 `~/.dsh/AGENTS.md` 里,由 `@deepseek-ai/dsh-agent-instructions` 注入。
那个插件给「全局 + 项目 AGENTS.md」**总共** 65536 字节(`maxBytes`),渲染规则是
**按最宽泛 → 最具体排序,先整份丢掉最宽泛的**,放不下才截断最具体那份。
人设恰好在最宽泛那份里 ⇒ **项目文件一长大,人设就是第一个被牺牲的**,
而且**不报错**(只在注入块顶部留一行 `Workspace instruction budget …`)。
源码核对(`dsh-agent-instructions/lib/index.js`):`Config` 只有
`maxBytes / maxSourceBytes` / 候选名之类,**没有任何 pin / alwaysInclude / priority
能保住某个文件**。
⇒ 结论:**在 AGENTS.md 这条通道里没有「永不掉」的配置,必须换通道。**
## 为什么不用 `personaPrefix`(最直觉,但会静默失效)
`dsh-system-prompt` 的 `assemble()` 里有这一句:
```js
const sectionByName = this.layers.merge(scope, (layer) => layer.sections)
```
而 `section()` 的文档写着「A scoped section shadows a global section with the same name」。
本机默认 agent preset 是 **`standard`**,它自己就注册了 `deployment:persona-prefix`
⇒ **往跑着的会话上写 `personaPrefix`,会被那个 scoped section 整个盖掉**,且不报错。
这正是本插件存在的理由:**换一个没人会注册的 section 名**。
## 做法
注册一个**独有名字**的 prompt section(默认 `deployment:persona-anchor`),内容从磁盘文件读。
- 名字独有 ⇒ 不可能被 preset shadow
- 通道是 `systemPrompt.section()` ⇒ **完全不经过 65536 预算**
排序借用 `getSectionOrder('DEPLOYMENT_PERSONA_PREFIX')`(= 0),即「部署人设」该在的位置。
## 安装
```sh
dsh plugin --profile web add github:harmless0819-dev/dsh-persona-anchor
```
## 配置
```yaml
- id: dsh-persona-anchor
name: dsh-persona-anchor
config:
file: 'C:/Users/<you>/.dsh/persona.md' # 必填,绝对路径
onError: log # log(默认)| throw
```
| 键 | 默认 | 说明 |
|---|---|---|
| `file` | **必填** | 人设文件绝对路径 |
| `section` | `deployment:persona-anchor` | section 名;改成别的独特名也行 |
| `maxBytes` | `524288` (512 KiB) | 单次读取上限,防手滑指到大文件 |
| `onError` | `'log'` | 读文件失败时:`log` 只告警 / `throw` 硬失败 |
| `order` | 部署人设位 | section 排序 |
| `reloadMs` | `0` | `>0` 时定时重读 |
| `route` | `true` | 是否注册状态路由 |
## 验证它真的生效
改完 `persona.md` 后,**新开一个会话**,问它「你的名字/设定是什么」。
若人设没进来,插件会注册一个状态路由报告 `state.error`,可从那里看到失败原因
(文件不存在 / 太大 / 空文件)。
## 注意
- `inject` 只列了 `systemPrompt`。`webServer` 是**可选**依赖,
代码里用 `ctx.inject([...])` 延迟注册 —— 写进顶层 `inject` 会让
headless profile(没有 webServer)整个加载失败。
- 读文件失败**默认不抛**,只在日志和状态里报告,避免一个人设文件打不开就把整个 profile 搞挂。
## License
MIT
Install
dsh plugin --profile web add github:harmless0819-dev/dsh-persona-anchor#2ca773fb709eee2a451ef8a268eddb4c17f99bf1
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-persona-anchor from the hub