dsh-memory-recall 0.2.0 → 0.2.1
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.md +1 -1
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
- package/src/index.js +43 -11
package/README.md
CHANGED
|
@@ -173,7 +173,7 @@ Other guards:
|
|
|
173
173
|
|
|
174
174
|
## Requirements
|
|
175
175
|
|
|
176
|
-
- dsh 0.1.5 or later, with a `web` profile
|
|
176
|
+
- dsh 0.1.5 or later, with a `web` profile — from 0.2.1 also dsh 0.1.7+ and 0.2.x
|
|
177
177
|
- Node 22+
|
|
178
178
|
- No runtime dependencies — the client bundle requires only `react`
|
|
179
179
|
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-memory-recall",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "Persistent memory for dsh in the style of Hermes Agent: a memory tool that keeps a user profile and the model's own notes, delivered to every chat as a logged context message — at the start, after a change and after compaction — and a session_search tool that reads earlier chats only after the user approves, with a Memory panel to see and edit what is kept.",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-memory-recall",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Persistent memory for dsh in the style of Hermes Agent: a memory tool that keeps a user profile and the model's own notes, delivered to every chat as a logged context message — at the start, after a change and after compaction — and a session_search tool that reads earlier chats only after the user approves, with a Memory panel to see and edit what is kept.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/index.js
CHANGED
|
@@ -113,30 +113,62 @@ export async function apply(ctx, config = {}, deps = {}) {
|
|
|
113
113
|
tooling.error = 'this dsh has no tool registry';
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
// ---- each new chat: memory in its prompt, frozen for its
|
|
117
|
-
|
|
116
|
+
// ---- each new chat: memory guidance in its prompt, frozen for its
|
|
117
|
+
// lifetime. dsh 0.1.7 removed `agent/session-start`; `agent/created` and
|
|
118
|
+
// `agent/disposed` exist on every dsh from 0.1.0-rc.7 through 0.2.x, so
|
|
119
|
+
// they are the seam — session-start stays wired as a back-compat path,
|
|
120
|
+
// deduped by the same map.
|
|
121
|
+
/** Agent contexts already carrying the section -> the registering fiber. */
|
|
122
|
+
const briefed = new WeakMap();
|
|
118
123
|
// sessionId -> what that chat's prompt was given, for the composer chip.
|
|
119
124
|
const briefings = createBriefings();
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
|
|
126
|
+
const installGuidance = (agent) => {
|
|
122
127
|
const agentCtx = agent?.ctx;
|
|
123
128
|
if (!agentCtx || briefed.has(agentCtx) || !isTopLevel(agent)) return;
|
|
124
|
-
briefed.add(agentCtx);
|
|
125
129
|
try {
|
|
126
|
-
const prompt = service(agentCtx, 'systemPrompt');
|
|
127
|
-
if (typeof prompt?.section !== 'function') return;
|
|
128
130
|
// Read now, once: this text is what the chat keeps, so a save made later
|
|
129
131
|
// in it never rewrites its prompt (which would cost the cached prefix).
|
|
130
132
|
// The guidance only: fixed text, so the cached prompt prefix holds.
|
|
131
133
|
const text = renderSection(null, store.limits, { tools: tooling.ok });
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
// `inject` rather than `get`: at agent/created the prompt service may not
|
|
135
|
+
// be resolvable yet; the callback runs once it is, and the fiber's
|
|
136
|
+
// dispose() takes the section back out.
|
|
137
|
+
const fiber = agentCtx.inject?.(['systemPrompt'], (scope) => {
|
|
138
|
+
if (!isTopLevel(agent)) return; // the header may have attached since created
|
|
139
|
+
try {
|
|
140
|
+
scope.systemPrompt?.section?.({ name: SECTION_NAME, order: SECTION_ORDER, text });
|
|
141
|
+
} catch {
|
|
142
|
+
// Already registered (e.g. after a plugin reload): a duplicate name throws.
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
if (fiber) briefed.set(agentCtx, fiber);
|
|
135
146
|
} catch (error) {
|
|
136
|
-
// Losing the
|
|
147
|
+
// Losing the guidance costs this chat its memory, never the chat.
|
|
137
148
|
ctx.logger?.warn?.(`[dsh-memory-recall] no memory for this chat: ${error?.message ?? error}`);
|
|
138
149
|
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const uninstallGuidance = (agent) => {
|
|
153
|
+
const agentCtx = agent?.ctx;
|
|
154
|
+
const fiber = agentCtx && briefed.get(agentCtx);
|
|
155
|
+
if (!fiber) return;
|
|
156
|
+
briefed.delete(agentCtx);
|
|
157
|
+
try {
|
|
158
|
+
fiber.dispose?.();
|
|
159
|
+
} catch {
|
|
160
|
+
// Teardown must not throw.
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Agents that already exist when this plugin mounts (a reload).
|
|
165
|
+
ctx.inject?.(['agents'], (scope) => {
|
|
166
|
+
for (const agent of scope.agents?.list?.() ?? []) installGuidance(agent);
|
|
139
167
|
});
|
|
168
|
+
ctx.on?.('agent/created', (payload) => installGuidance(payload?.agent));
|
|
169
|
+
ctx.on?.('agent/disposed', (payload) => uninstallGuidance(payload?.agent));
|
|
170
|
+
// Older hosts fire this instead of agent/created; the map dedupes.
|
|
171
|
+
ctx.on?.('agent/session-start', (payload) => installGuidance(payload?.agent));
|
|
140
172
|
|
|
141
173
|
// ---- the memory itself: a logged context message, whenever the chat
|
|
142
174
|
// cannot see the current version (start, after compaction, after a change).
|