@istarry/dsh-assistant-profile 0.6.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +124 -0
- package/README.md +17 -2
- package/cordis.patch.yml +2 -2
- package/package.json +15 -6
- package/lib/client.js +0 -1482
- package/lib/client.js.map +0 -1
- package/lib/index.js +0 -3040
package/README.en.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Assistant Profile · dsh-assistant-profile
|
|
2
|
+
|
|
3
|
+
One **global persona** and one **long-term memory** for DeepSeek Harness: name, language, persona prompt, and a memory that rides right behind the persona in every system prompt. Install it once and every new session opens with it at the very top of the system prompt. The sidebar shows the assistant's name above New Session.
|
|
4
|
+
|
|
5
|
+
One profile, all four modes (standard / PTC / minimal / creator). No preset duplication, no mode-picker override.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
The host half does exactly one thing: when a chat agent is created (and when a blank session is re-bound to another preset), it registers a `deployment:persona-prefix` section in that agent's **own scope**. The nearest same-named section wins, so the preset's identity line is replaced while tools, flow, and mode semantics stay untouched.
|
|
10
|
+
|
|
11
|
+
That is the same path the official subagent runtime uses for per-child personas (`dsh-subagent`'s `applyChildComposition`), which is why it works for all four presets.
|
|
12
|
+
|
|
13
|
+
The injected text looks like this (blank-line separated, each part optional):
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Your name is 大肥鱼.
|
|
17
|
+
|
|
18
|
+
Reply in 简体中文 throughout.
|
|
19
|
+
|
|
20
|
+
<your persona prompt…>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- **Minimal mode** treats the persona as the complete system prompt (`complete: true`). The shadowing section mirrors that flag, so minimal mode's prompt becomes *only* your persona — still no tool instructions, exactly as that mode is designed.
|
|
24
|
+
- With all four fields empty it falls back to the preset's own text, i.e. native behaviour.
|
|
25
|
+
- **Subagents are left alone**: a delegated child keeps its own persona.
|
|
26
|
+
|
|
27
|
+
## Assistant memory
|
|
28
|
+
|
|
29
|
+
One profile means one memory: a markdown document (one `- [YYYY-MM-DD HH:mm] content` line per fact) stored with the profile alongside the persona, shared by every session.
|
|
30
|
+
|
|
31
|
+
**Where it lands**: section `memory:assistant`, order 500 — after the persona (0), before the tool catalog (1000). Memory states who the user and the assistant are, which the tool descriptions then assume.
|
|
32
|
+
|
|
33
|
+
**Three ways in**:
|
|
34
|
+
|
|
35
|
+
- **The Remember button in chat**: every assistant message's action strip (beside the official like/dislike pair) gains a ✨. It opens a picker listing the session's user/assistant messages; submit and the host runs **that session's own model** once to condense the selection into a few stable facts, appending each (an identical fact only refreshes its stamp instead of piling up).
|
|
36
|
+
- **Settings → Agent memory**: two switches (memory / auto memory) and an editor. Hand-written edits land on save.
|
|
37
|
+
- **The `memory_add` tool**: registered only while both switches are on, letting the model decide what to remember mid-conversation.
|
|
38
|
+
|
|
39
|
+
Extraction is fail-closed: an offline session, a missing model configuration, or a model that returns nothing writable leaves the store untouched and reports the reason in the dialog.
|
|
40
|
+
|
|
41
|
+
### Three pitfalls worth knowing before touching this
|
|
42
|
+
|
|
43
|
+
1. **A plugin cannot write its own config.** `Volatile` exposes `get()` only; writes must go through the settings service (`settings.update(ns, patch)`), which persists to the profile patch and lets the loader commit the new value back into the runtime reference.
|
|
44
|
+
2. **Write-backs must escape the HMR transaction.** A settings write runs inside `hmr.runExclusive`, and writing the result back opens another transaction — calling it inline throws `HMR transactions cannot be nested`. Every trigger therefore goes through `setTimeout(0)`.
|
|
45
|
+
3. **Settings writes do not emit `loader/volatile-update`** (measured: the value commits into the reference, the event never fires). The mailbox is polled every 700 ms instead — one string read, one JSON check when idle.
|
|
46
|
+
|
|
47
|
+
Because `@deepseek-ai/dsh-tools` / `dsh-llm` / `dsh-session` do not resolve from the plugin directory (only `cordis` is host-provided), the tool definition and the extraction messages are hand-built to the official wire shapes rather than imported.
|
|
48
|
+
|
|
49
|
+
## Editing the persona does not recompute history
|
|
50
|
+
|
|
51
|
+
DeepSeek context caching is prefix caching: the system prompt sits at the front, so rewriting the leading system message invalidates everything after it.
|
|
52
|
+
|
|
53
|
+
The persona text is **evaluated at every assembly**, so saving a new one changes the next request's prompt while **not touching a single byte of history**. The rest is the host's call: on a model route declaring `systemPromptUpdate: 'in-history'` (the default `deepseek-flash` entry does), the changed prompt is **appended after the cached history**, so the prefix through that history stays reusable and only the new snippet is billed as ordinary input.
|
|
54
|
+
|
|
55
|
+
The session log states the mode in `request/context`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{"provider":"deepseek-official","model":"deepseek-flash","systemPromptUpdate":"in-history"}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
On a route without it (the default `deepseek-v4-pro` entry, for example) a mid-session edit costs one full cache miss from the first token. That is a route capability, not a plugin choice; if it matters, make the edit between sessions.
|
|
62
|
+
|
|
63
|
+
## UI
|
|
64
|
+
|
|
65
|
+
- A new **Assistant Profile** row in the sidebar, right below Plugins (order 5).
|
|
66
|
+
- It opens a main-area page: name, language, persona prompt, a live character counter (turns warning-coloured past 2000).
|
|
67
|
+
- Left of Save sits the persona row: **Default 1 / 2 / 3** (a click only fills the three fields; Save still decides what sticks) plus "Save as" copies (named after the Name field, each with a small delete button); a fresh install starts on Default 3, and the row scrolls horizontally when it overflows.
|
|
68
|
+
- Above the New Session button: a quiet name row (first-character chip + name). It hides when the sidebar collapses to the 56px rail and updates as soon as a new name is saved.
|
|
69
|
+
- Defaults: name `大肥鱼`, language `中文`.
|
|
70
|
+
|
|
71
|
+
## Where the data lives
|
|
72
|
+
|
|
73
|
+
The four fields are this plugin's profile config, read and written through the official settings channel, persisted into the profile's `cordis.patch.yml`:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
- id: assistant-profile
|
|
77
|
+
name: '@istarry/dsh-assistant-profile'
|
|
78
|
+
config:
|
|
79
|
+
name: 小星
|
|
80
|
+
language: 简体中文
|
|
81
|
+
persona: 你是一个只讲证据的助理。不确定就说不确定。
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
It travels with the profile: another profile is another persona; backing up the profile backs up the persona.
|
|
85
|
+
|
|
86
|
+
## Install
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
dsh plugin --profile <profile> add @istarry/dsh-assistant-profile
|
|
90
|
+
# local tarball:
|
|
91
|
+
dsh plugin --profile <profile> add E:/Plugin/发布版/dsh-assistant-profile/dist/istarry-dsh-assistant-profile-0.2.1.tgz
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Restart DSH. To remove:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
dsh plugin --profile <profile> remove @istarry/dsh-assistant-profile
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Leftover config lines are harmless (nothing reads them), but deleting them is tidier.
|
|
101
|
+
|
|
102
|
+
## Relationship to dsh-agent-suite
|
|
103
|
+
|
|
104
|
+
Both shadow the same section (`deployment:persona-prefix`); **do not enable both** — the later load wins and the personas fight. Use agent-suite when you need several agents with their own personas; use this one for a single persona you carry everywhere.
|
|
105
|
+
|
|
106
|
+
## Build
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd tooling && pnpm install # once: tsdown + lightningcss + typescript + js-yaml
|
|
110
|
+
cd .. && node build.mjs # src/ → dist/ (manifest and static files included)
|
|
111
|
+
node build.mjs --staging # build to .build/out only
|
|
112
|
+
node build.mjs --check # build + dependency-contract check, no dist/ writes
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The host bundle inlines `js-yaml`; at runtime it only depends on `@deepseek-ai/schemastery` (declared in `dependencies`, installed into the plugin's own node_modules by pnpm). The browser bundle only `require`s module-table entries (react / ui-primitives).
|
|
116
|
+
|
|
117
|
+
Edit `src/` only; artifacts are generated.
|
|
118
|
+
|
|
119
|
+
## Known edges
|
|
120
|
+
|
|
121
|
+
- Top-level sessions only; subagents are never injected.
|
|
122
|
+
- When the preset registry cannot be read, injection degrades to a plain section (no `complete` mirroring) and logs nothing.
|
|
123
|
+
- Saving with all three fields cleared injects nothing (native identity); a fresh install carries the Default 3 content.
|
|
124
|
+
- The nameplate is a DOM node inserted before the New Session button (the shell exposes no slot there); a MutationObserver puts it back if a re-render drops it.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent助理 · dsh-assistant-profile
|
|
2
2
|
|
|
3
3
|
给 DeepSeek Harness 一份**全局人格**和**一份长期记忆**:名称、语言、人格提示词三段,装一次,之后每个新会话的系统提示最前面都从它开始;记忆紧跟在人格后面,聊天里点一下就能把选中的对话提炼进去。侧栏「新会话」上方会显示这份档案的助理名。
|
|
4
4
|
|
|
@@ -46,6 +46,21 @@ Reply in 简体中文 throughout.
|
|
|
46
46
|
|
|
47
47
|
因为插件目录里解析不到 `@deepseek-ai/dsh-tools` / `dsh-llm` / `dsh-session`(只有 `cordis` 由宿主提供),工具定义与提炼用的消息都按官方线上形状**手搭**,不 import 这几个包。
|
|
48
48
|
|
|
49
|
+
## 删除会话
|
|
50
|
+
|
|
51
|
+
侧栏任意会话行的「…」菜单里多一行**删除**(红色,带分隔线,排在「复制 Session ID」之后)。确认后删的是这个会话本身:
|
|
52
|
+
|
|
53
|
+
- **磁盘**:`<DSH_HOME>/sessions/<项目>/<会话 id>/` 整个目录(日志、分代文件一起),
|
|
54
|
+
- **索引**:会话查询里那一行(下次搜索不会再出现),
|
|
55
|
+
- **登记**:工作区里对这个会话的记账,
|
|
56
|
+
- **界面**:宿主发 `api-session/removed`,官方 session-controller 收到后把行从侧栏移除。
|
|
57
|
+
|
|
58
|
+
正在运行的会话会被拒绝(先停止),空闲但还开着的会话会先被摘下再删。
|
|
59
|
+
|
|
60
|
+
### 为什么不是调一个 `remove()` 就完事
|
|
61
|
+
|
|
62
|
+
这一版 harness 的 `sessionPersistence` **没有**删除方法,`locate` / `listArtifacts` 的第一个参数又是 options(里面装 `signal`)——把会话 id 传进去会走进 `signal?.throwIfAborted()`,直接把宿主带崩(实测 `fatal load failure`)。所以删除按目录布局自己做,只认 `<root>/<项目>/<会话 id>` 这一种形状;命中不到就返回「找不到」,宁可不动手。
|
|
63
|
+
|
|
49
64
|
## 改人格不会重算历史
|
|
50
65
|
|
|
51
66
|
DeepSeek 的上下文缓存是前缀缓存:系统提示在最前面,直接改写开头那条会让后面全部失效。
|
|
@@ -62,7 +77,7 @@ DeepSeek 的上下文缓存是前缀缓存:系统提示在最前面,直接
|
|
|
62
77
|
|
|
63
78
|
## 界面
|
|
64
79
|
|
|
65
|
-
-
|
|
80
|
+
- 侧栏「插件」下面多一行**Agent助理**(行序 5,夹在插件与自动化任务之间)。
|
|
66
81
|
- 点开是主区的一个页面:名称、语言、人格提示词,右下角实时字数(超过 2000 字转成提醒色)。
|
|
67
82
|
- 「保存」行左侧是人格预设:**默认一 / 默认二 / 默认三**(点击只把三段文本填进表单,落盘仍按「保存」)加「另存」出来的自定义(名字取自「名称」,胶囊右侧带小删除钮);装好默认用**默认三**,放不下横向滚动。
|
|
68
83
|
- 「新会话」按钮上方一行小字 + 首字方块显示助理名;侧栏收成 56px 图标栏时自动隐藏;改完名称保存后立刻变。
|
package/cordis.patch.yml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent助理插件:一行。
|
|
2
2
|
# 宿主半端只做一件事——每个对话 agent 创建时,在它自己的作用域里遮蔽人格那一行
|
|
3
3
|
# (`deployment:persona-prefix`),文本来自本插件的配置;四个模式自动全覆盖,
|
|
4
|
-
#
|
|
4
|
+
# 不需要复制预设、不需要动模式选择器。浏览器半端提供「Agent助理」入口、编辑页,
|
|
5
5
|
# 以及「新会话」按钮上方的助理名。
|
|
6
6
|
- insert:
|
|
7
7
|
- id: assistant-profile
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@istarry/dsh-assistant-profile",
|
|
3
|
-
"description": "助理档案:给 DSH 一份全局人格(名称 / 语言 /
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "助理档案:给 DSH 一份全局人格(名称 / 语言 / 人格提示词)与一份长期记忆,每个新会话的系统提示最前面都带着它;聊天里点一下就能把选中的对话提炼进记忆;侧栏「新会话」上方显示助理名;会话行菜单里可以直接删除一个会话(日志、索引、工作区登记一起)",
|
|
4
|
+
"version": "0.7.2",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -44,14 +44,23 @@
|
|
|
44
44
|
"platform": "web"
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "node build.mjs",
|
|
49
|
+
"check": "node build.mjs --check",
|
|
50
|
+
"staging": "node build.mjs --staging",
|
|
51
|
+
"tooling": "cd tooling && pnpm install"
|
|
52
|
+
},
|
|
47
53
|
"dependencies": {
|
|
48
54
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
49
55
|
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"js-yaml": "4.2.0"
|
|
58
|
+
},
|
|
50
59
|
"peerDependencies": {
|
|
51
60
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
52
|
-
"@deepseek-ai/dsh-agent": "
|
|
53
|
-
"@deepseek-ai/dsh-agent-preset-registry": "
|
|
54
|
-
"@deepseek-ai/dsh-settings": "
|
|
55
|
-
"@deepseek-ai/dsh-system-prompt": "
|
|
61
|
+
"@deepseek-ai/dsh-agent": ">=0.2.1-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-agent-preset-registry": ">=0.2.1-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-settings": ">=0.2.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.2.1-rc.2"
|
|
56
65
|
}
|
|
57
66
|
}
|