- Home
- Plugins
- Integrations & Remote
- dsh-assistant-profile
dsh-assistant-profile
istarrydust/dsh-assistant-profile
Agent persona: gives DSH one global persona (name, language, persona prompt) that every new session carries at the front of its system prompt; personas can be defined and saved, with three Big fat fish personas included by default. A Big fat fish persona is active right after install.
Install
dsh plugin --profile web add github:istarrydust/dsh-assistant-profileREADME
Agent助理 · dsh-assistant-profile
给 DeepSeek Harness 一份全局人格和一份长期记忆:名称、语言、人格提示词三段,装一次,之后每个新会话的系统提示最前面都从它开始;记忆紧跟在人格后面,聊天里点一下就能把选中的对话提炼进去。侧栏「新会话」上方会显示这份档案的助理名。
一个档案,四个模式通用(标准 / PTC / 极简 / 创造)。不需要复制预设,也不需要改模式选择器。
它做了什么
宿主半端只做一件事:每个对话 agent 创建时(以及空白会话换模式重新绑定预设时),在这个 agent 自己的作用域里注册一段 deployment:persona-prefix。作用域链上最近的同名段胜出,于是预设自带的身份句被档案替换,而工具、流程、模式语义一律不动。
这正是官方给子代理发独立人格用的那条路径(dsh-subagent 的 applyChildComposition),所以它对四种预设都成立。
注入文本长这样(空行分隔,缺哪段就少哪段):
Your name is 大肥鱼.
Reply in 简体中文 throughout.
<你写的人格提示词…>
- 极简模式的预设把人格当作「整段系统提示只有这一句」(
complete: true)。遮蔽段会镜像这个标记——极简模式下系统提示就只有你的档案,仍然没有工具说明,符合那个模式原本的设计。 - 四段全空时回落到预设原文,等于原生行为。
- 子智能体不注入:委派出去的孩子保留它自己的人格。
助理记忆
单档案所以单记忆:一份 markdown(一行一条 - [YYYY-MM-DD HH:mm] 内容),随档案存在 profile 的同一份配置里,所有会话共享。
注入位置:memory:assistant 段,order 500 —— 排在人格(0)之后、工具目录(1000)之前。记忆描述的是「用户和我是什么关系」,工具说明会引用这些前提。
三个入口:
- 聊天里的「记住」按钮:每条助手消息的动作行上(官方的点赞/点踩旁边)多一个 ✨。点开是一个勾选弹窗,列出这个会话里可提炼的用户/助手消息;勾选后提交,宿主用该会话自己的模型跑一次独立请求,把选中的对话压成几条稳定事实,逐条追加(同义条目只刷新时间戳,不重复堆积)。
- 设置 → Agent记忆:两个开关(启用记忆 / 自动记忆)+ 一个编辑框。手工写、改、删都在这儿,保存即落盘。
memory_add工具:只在「启用记忆 + 自动记忆」都打开时注册,模型可以在对话中自己决定记什么。
提炼是 fail-closed 的:会话不在线、取不到这个会话的模型配置、模型没吐出一条可用条目,都不会写任何东西,只把原因回显在弹窗里。
三个实现上的坑(改这个功能前先看)
- 宿主不能直接写自己的配置。
Volatile只暴露get(),写入必须经设置服务(settings.update(ns, patch)),它才会落进 profile 的 patch 并由加载器提交回运行时引用。 - 写回要挪出 HMR 事务。设置写入本身跑在
hmr.runExclusive里,而写回结果又要经设置服务再开一个事务——直接调用会抛HMR transactions cannot be nested。所以所有触发点都过一层setTimeout(0)。 - 设置写入不会触发
loader/volatile-update(实测;值会提交进引用,但没有那次事件)。信箱因此靠 700ms 轮询:每次只读一个字符串字段,没有新请求时就是一次 JSON 判定。
因为插件目录里解析不到 @deepseek-ai/dsh-tools / dsh-llm / dsh-session(只有 cordis 由宿主提供),工具定义与提炼用的消息都按官方线上形状手搭,不 import 这几个包。
删除会话
侧栏任意会话行的「…」菜单里多一行删除(红色,带分隔线,排在「复制 Session ID」之后)。确认后删的是这个会话本身:
- 磁盘:
<DSH_HOME>/sessions/<项目>/<会话 id>/整个目录(日志、分代文件一起), - 索引:会话查询里那一行(下次搜索不会再出现),
- 登记:工作区里对这个会话的记账,
- 界面:宿主发
api-session/removed,官方 session-controller 收到后把行从侧栏移除。
正在运行的会话会被拒绝(先停止),空闲但还开着的会话会先被摘下再删。
为什么不是调一个 remove() 就完事
这一版 harness 的 sessionPersistence 没有删除方法,locate / listArtifacts 的第一个参数又是 options(里面装 signal)——把会话 id 传进去会走进 signal?.throwIfAborted(),直接把宿主带崩(实测 fatal load failure)。所以删除按目录布局自己做,只认 <root>/<项目>/<会话 id> 这一种形状;命中不到就返回「找不到」,宁可不动手。
改人格不会重算历史
DeepSeek 的上下文缓存是前缀缓存:系统提示在最前面,直接改写开头那条会让后面全部失效。
档案的文本是每次组装提示词时求值的,所以保存后下一个请求的提示词就变了,而历史一个字节都不动。剩下的交给宿主判定:模型路由声明了 systemPromptUpdate: 'in-history'(DSH 默认的 deepseek-flash 条目就声明了)时,变化的系统提示会被追加在已缓存的历史之后,历史那段前缀仍然命中,只有新增的这一小段按普通输入计费。
会话日志里的 request/context 会写明当前路由的模式:
{"provider":"deepseek-official","model":"deepseek-flash","systemPromptUpdate":"in-history"}
路由不支持这个模式时(例如默认的 deepseek-v4-pro 条目),改人格会让下一次请求从开头失效一次——那是路由能力问题,不是插件的选择。介意的话,把改动留到新会话。
界面
- 侧栏「插件」下面多一行Agent助理(行序 5,夹在插件与自动化任务之间)。
- 点开是主区的一个页面:名称、语言、人格提示词,右下角实时字数(超过 2000 字转成提醒色)。
- 「保存」行左侧是人格预设:默认一 / 默认二 / 默认三(点击只把三段文本填进表单,落盘仍按「保存」)加「另存」出来的自定义(名字取自「名称」,胶囊右侧带小删除钮);装好默认用默认三,放不下横向滚动。
- 「新会话」按钮上方一行小字 + 首字方块显示助理名;侧栏收成 56px 图标栏时自动隐藏;改完名称保存后立刻变。
- 名称默认
大肥鱼、语言默认中文。
数据存在哪
四个字段就是本插件在 profile 里的配置,由官方设置通道读写,落进 profile 的 cordis.patch.yml:
- id: assistant-profile
name: '@istarry/dsh-assistant-profile'
config:
name: 小星
language: 简体中文
persona: 你是一个只讲证据的助理。不确定就说不确定。
所以它跟着 profile 走:换 profile 就是另一份档案;备份 profile 就备份了人格。
安装
dsh plugin --profile <profile> add @istarry/dsh-assistant-profile
# 本地包:
dsh plugin --profile <profile> add E:/Plugin/发布版/dsh-assistant-profile/dist/istarry-dsh-assistant-profile-0.2.1.tgz
重启 DSH 后生效。卸载:
dsh plugin --profile <profile> remove @istarry/dsh-assistant-profile
profile 里残留的四行配置不会影响原生行为(插件不在了,没人读它),手工删掉更干净。
与 dsh-agent-suite 的关系
两者遮蔽的是同一个段(deployment:persona-prefix),不要同时启用:后加载的会赢,人格会互相覆盖。需要多个 agent 各自的人格请用 agent-suite;只要一个随身人格就用这个。
构建
cd tooling && pnpm install # 首次:tsdown + lightningcss + typescript + js-yaml
cd .. && node build.mjs # src/ → dist/(含清单与静态文件)
node build.mjs --staging # 只构建到 .build/out
node build.mjs --check # 构建 + 依赖契约校验,不写 dist/
宿主产物把 js-yaml 内联进去,运行时只依赖 @deepseek-ai/schemastery(声明在 dependencies,由 pnpm 装进插件自己的 node_modules)。浏览器半端只 require 模块表里的条目(react / ui-primitives)。
改代码只改 src/,产物由构建生成。
已知边界
- 只注入顶层会话,子代理不注入(记忆段是全局的,子代理读得到)。
- 没有远程调用:记忆、信箱、归档全都走设置通道与配置字段,所以不需要 typert 生成物。
- 读不到预设定义时(注册表异常)降级为普通注入,不镜像
complete,也不报错。 - 三栏全部清空再保存 = 什么都不注入(回到原生身份句);装好时默认是默认三的内容。
- 侧栏名plate 是插在「新会话」按钮前的 DOM 节点(外壳没给这个位置留 slot),React 重渲染把它冲掉时会自动补回。
安装后如果插件没出现
DSH 的插件安装器会用 pnpm 的 isolated 布局装包(包在 node_modules/.pnpm/,
顶层 node_modules/<包名> 为空),而 loader 从顶层解析,于是「装了但界面里没有」。
遇到这种情况,在 profile 目录执行一次:
然后重启 DSH 即可。
Related plugins
dsh-web (dsh-ssh)
zhu1090093659/dsh-web
dsh-web (dsh-remote-web-ui)
zhu1090093659/dsh-web
dsh-web-ui (dsh-ssh)
zhu1090093659/dsh-web-ui
dsh-web-ui (dsh-remote-web-ui)
zhu1090093659/dsh-web-ui