@openviking/dsh-memory-plugin 0.5.1 → 0.5.3
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 +4 -1
- package/capture.mjs +25 -10
- package/config.mjs +1 -1
- package/package.json +1 -1
- package/runtime.mjs +3 -3
- package/shared/config-schema.mjs +11 -0
package/README.md
CHANGED
|
@@ -103,7 +103,10 @@ the stock `web` profile, not a subcommand to append after `--profile`.
|
|
|
103
103
|
### Why injection uses pre-step user messages, not the system prompt
|
|
104
104
|
|
|
105
105
|
Recall and profile context enter through the `agent/pre-step` waterfall as
|
|
106
|
-
durable, source-attributed user messages
|
|
106
|
+
durable, source-attributed user messages
|
|
107
|
+
(`source: { kind: 'plugin:openviking-memory', … }`). The producer-owned kind is
|
|
108
|
+
required by DSH session format v4; the plugin still recognizes legacy
|
|
109
|
+
`kind: 'plugin'` messages while older sessions are replayed.
|
|
107
110
|
They are deliberately **not** added to the system prompt: a DSH preset whose
|
|
108
111
|
persona declares `complete: true` (the stock `minimal` preset does) restores
|
|
109
112
|
that persona as the sole prompt section after assembly, silently discarding
|
package/capture.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "./shared/capture-utils.mjs";
|
|
7
7
|
|
|
8
8
|
export const OPENVIKING_PLUGIN_SOURCE = "openviking-memory";
|
|
9
|
+
export const OPENVIKING_PLUGIN_KIND = `plugin:${OPENVIKING_PLUGIN_SOURCE}`;
|
|
9
10
|
|
|
10
11
|
export function pluginMessage(content, source) {
|
|
11
12
|
// dsh's own constructor: identity, normalization, and any future Message
|
|
@@ -13,13 +14,31 @@ export function pluginMessage(content, source) {
|
|
|
13
14
|
return createUserMessage({
|
|
14
15
|
content: [{ type: "text", text: content }],
|
|
15
16
|
source: {
|
|
16
|
-
kind:
|
|
17
|
+
kind: OPENVIKING_PLUGIN_KIND,
|
|
17
18
|
plugin: OPENVIKING_PLUGIN_SOURCE,
|
|
18
19
|
...source,
|
|
19
20
|
},
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
export function isOpenVikingPluginMessage(message) {
|
|
25
|
+
const source = message?.source;
|
|
26
|
+
return source?.kind === OPENVIKING_PLUGIN_KIND
|
|
27
|
+
|| (source?.kind === "plugin" && source.plugin === OPENVIKING_PLUGIN_SOURCE);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isSyntheticUserMessage(message) {
|
|
31
|
+
const kind = message?.source?.kind;
|
|
32
|
+
if (kind === "plugin") return true;
|
|
33
|
+
if (typeof kind === "string" && kind.startsWith("plugin:")) return true;
|
|
34
|
+
// DSH's v4 migration gives first-party context producers their own kinds
|
|
35
|
+
// (for example, "time-context") instead of the retired plugin wrapper.
|
|
36
|
+
return message?.role === "user"
|
|
37
|
+
&& typeof kind === "string"
|
|
38
|
+
&& kind !== "user"
|
|
39
|
+
&& kind !== "tool";
|
|
40
|
+
}
|
|
41
|
+
|
|
23
42
|
export function captureEvent(event, config, toolNames = new Map()) {
|
|
24
43
|
if (!event || typeof event !== "object") return null;
|
|
25
44
|
if (event.type === "tool/call") {
|
|
@@ -42,11 +61,10 @@ export function captureEvent(event, config, toolNames = new Map()) {
|
|
|
42
61
|
}
|
|
43
62
|
|
|
44
63
|
function captureMessage(event, message, config, toolNames) {
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
if (message.source?.kind === "plugin") return null;
|
|
64
|
+
// DSH v4 gives producer-owned context messages their own kind. Treat
|
|
65
|
+
// user-role messages with an explicit non-user/tool kind as synthetic;
|
|
66
|
+
// untagged legacy messages stay capturable for backward compatibility.
|
|
67
|
+
if (isSyntheticUserMessage(message)) return null;
|
|
50
68
|
if (message.role === "assistant" && config.captureAssistantTurns === false) {
|
|
51
69
|
return null;
|
|
52
70
|
}
|
|
@@ -85,10 +103,7 @@ function captureMessage(event, message, config, toolNames) {
|
|
|
85
103
|
|
|
86
104
|
export function promptText(messages) {
|
|
87
105
|
return (messages || [])
|
|
88
|
-
.filter(message => !(
|
|
89
|
-
message?.source?.kind === "plugin"
|
|
90
|
-
&& message.source.plugin === OPENVIKING_PLUGIN_SOURCE
|
|
91
|
-
))
|
|
106
|
+
.filter(message => !isOpenVikingPluginMessage(message))
|
|
92
107
|
.map(message => extractTextFromPayload(message))
|
|
93
108
|
.filter(Boolean)
|
|
94
109
|
.join("\n\n")
|
package/config.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { buildPluginConfig } from "./shared/plugin-config.mjs";
|
|
2
2
|
import { loadCredentialFiles } from "./shared/credentials.mjs";
|
|
3
3
|
|
|
4
|
-
export const PLUGIN_VERSION = "0.5.
|
|
4
|
+
export const PLUGIN_VERSION = "0.5.3";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Namespace for the bridged OpenViking MCP tools. DSH publishes every MCP tool
|
package/package.json
CHANGED
package/runtime.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { isRetryableFailure } from "./shared/retryable.mjs";
|
|
|
12
12
|
import { resolveEffectivePeerId } from "./shared/workspace-peer.mjs";
|
|
13
13
|
import {
|
|
14
14
|
captureEvent,
|
|
15
|
-
|
|
15
|
+
isOpenVikingPluginMessage,
|
|
16
16
|
pluginMessage,
|
|
17
17
|
promptText,
|
|
18
18
|
} from "./capture.mjs";
|
|
@@ -139,6 +139,7 @@ export class OpenVikingRuntime {
|
|
|
139
139
|
actorPeerId: state.config.peerId,
|
|
140
140
|
legacyPeerId: state.config.legacyPeerId,
|
|
141
141
|
sessionId: state.ovSessionId,
|
|
142
|
+
excludeUris: state.config.recallExcludeUris,
|
|
142
143
|
log: (stage, data) => this.log(stage, data),
|
|
143
144
|
},
|
|
144
145
|
);
|
|
@@ -420,7 +421,6 @@ function hasStartupProfile(agent) {
|
|
|
420
421
|
}
|
|
421
422
|
|
|
422
423
|
function isStartupProfile(message) {
|
|
423
|
-
return message
|
|
424
|
-
&& message.source.plugin === OPENVIKING_PLUGIN_SOURCE
|
|
424
|
+
return isOpenVikingPluginMessage(message)
|
|
425
425
|
&& message.source.form === "instructions";
|
|
426
426
|
}
|
package/shared/config-schema.mjs
CHANGED
|
@@ -93,6 +93,17 @@ export const KNOBS = [
|
|
|
93
93
|
{ name: "logRankingDetails", type: "bool", default: false, env: "OPENVIKING_LOG_RANKING_DETAILS", capability: "recall" },
|
|
94
94
|
{ name: "recallLedger", type: "bool", default: true, env: "OPENVIKING_RECALL_LEDGER", capability: "recall" },
|
|
95
95
|
{ name: "recallQueryFilters", type: "list", default: [], env: "OPENVIKING_RECALL_QUERY_FILTERS", capability: "recall" },
|
|
96
|
+
// Subtree URIs the recall search must never return. Without this there is no
|
|
97
|
+
// way to keep generated directory files (viking://user/<space>/skills,
|
|
98
|
+
// viking://user/<space>/resources, viking://agent/skills) out of the hits:
|
|
99
|
+
// they match like ordinary content and carry only boilerplate text.
|
|
100
|
+
{
|
|
101
|
+
name: "recallExcludeUris",
|
|
102
|
+
type: "list",
|
|
103
|
+
default: [],
|
|
104
|
+
env: "OPENVIKING_RECALL_EXCLUDE_URIS",
|
|
105
|
+
capability: "recall",
|
|
106
|
+
},
|
|
96
107
|
|
|
97
108
|
// Digest compression. Claude Code reads this as the tri-state
|
|
98
109
|
// off/client/server/auto through `normalizeRewriteMode`; Codex reads the same
|