@openviking/dsh-memory-plugin 0.5.0 → 0.5.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.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 (`source: { kind: 'plugin', … }`).
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: "plugin",
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
- // Whitelist by source: plugin-injected user messages (this plugin's recall
46
- // blocks, time-context snapshots, any other plugin's context) are model
47
- // input, not human input — mirroring them would launder synthetic text
48
- // into memory as if a person said it.
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.0";
4
+ export const PLUGIN_VERSION = "0.5.2";
5
5
 
6
6
  /**
7
7
  * Namespace for the bridged OpenViking MCP tools. DSH publishes every MCP tool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openviking/dsh-memory-plugin",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "OpenViking memory and context bundle for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "index.mjs",
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
- OPENVIKING_PLUGIN_SOURCE,
15
+ isOpenVikingPluginMessage,
16
16
  pluginMessage,
17
17
  promptText,
18
18
  } from "./capture.mjs";
@@ -420,7 +420,6 @@ function hasStartupProfile(agent) {
420
420
  }
421
421
 
422
422
  function isStartupProfile(message) {
423
- return message?.source?.kind === "plugin"
424
- && message.source.plugin === OPENVIKING_PLUGIN_SOURCE
423
+ return isOpenVikingPluginMessage(message)
425
424
  && message.source.form === "instructions";
426
425
  }
@@ -243,6 +243,7 @@ export const HARNESS_KEYS = {
243
243
  claudeCode: "claude_code",
244
244
  codex: "codex",
245
245
  cursor: "cursor",
246
+ kimicode: "kimicode",
246
247
  trae: "trae",
247
248
  traeCn: "trae_cn",
248
249
  zcode: "zcode",