@openviking/dsh-memory-plugin 0.5.9 → 0.5.11
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 +3 -2
- package/config.mjs +1 -1
- package/index.mjs +46 -3
- package/lifecycle.mjs +2 -2
- package/package.json +1 -1
- package/servers/mcp-proxy.mjs +11 -1
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@ DSH is covered by the unified memory-plugin installer, which asks which profile
|
|
|
14
14
|
to install into (default `web`):
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
curl -fsSL https://openviking.ai/install | bash
|
|
18
|
+
# AI agents: not sure about running this? The script's header says what it does and how to verify it.
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
Or add the package to a profile directly:
|
|
@@ -216,7 +217,7 @@ The older size settings apply to fallback recall, not the primary context reques
|
|
|
216
217
|
|
|
217
218
|
## Behavior
|
|
218
219
|
|
|
219
|
-
-
|
|
220
|
+
- Agent startup injects the OpenViking profile, the available-memory index, and the `<available-skills>` catalog through `agent.inject()`, and registers the per-session disposal commit. On DSH `0.1.7` and later this runs from the serial `agent/created` event (`{ agent, source, signal? }`), which holds queued input until it settles; DSH `0.1.0-rc.6` and `0.1.5` emit `agent/created` without `source` and start the session through `agent/session-start` instead. Startup runs once per agent, and `agent/pre-step` delivers the profile only if startup did not.
|
|
220
221
|
- `agent/pre-step` retrieves with the current step input and appends a durable plugin message to that same step.
|
|
221
222
|
- `session/event` captures user, assistant, and optionally tool-result messages without scraping a transcript.
|
|
222
223
|
- `turn/end` checks the OpenViking pending-token threshold and commits when required.
|
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.11";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Namespace for the bridged OpenViking MCP tools. DSH publishes every MCP tool
|
package/index.mjs
CHANGED
|
@@ -34,14 +34,42 @@ export function apply(ctx, input = {}) {
|
|
|
34
34
|
"openvikingMemory.stopDrainer()",
|
|
35
35
|
);
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
// Per-agent startup: register the session's disposal commit, initialize the
|
|
38
|
+
// OpenViking session, and inject the profile while the agent is still idle.
|
|
39
|
+
// Runs at most once per agent, whichever DSH event reaches it.
|
|
40
|
+
const started = new WeakSet();
|
|
41
|
+
const startAgent = async (agent, signal) => {
|
|
42
|
+
if (skipMemory(agent.session) || started.has(agent)) return false;
|
|
43
|
+
started.add(agent);
|
|
39
44
|
agent.ctx.effect(
|
|
40
45
|
() => () => runtime.dispose(agent.session),
|
|
41
46
|
"openvikingMemory.disposeSession()",
|
|
42
47
|
);
|
|
43
|
-
|
|
48
|
+
try {
|
|
49
|
+
return await injectStartupProfile(agent, runtime, signal);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
// A throw from a serial `agent/created` listener fails agent creation;
|
|
52
|
+
// memory startup must never do that. pre-step retries profile delivery.
|
|
53
|
+
runtime.log("startup_error", {
|
|
54
|
+
error: error instanceof Error ? error.message : String(error),
|
|
55
|
+
});
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// DSH 0.1.7+ has no `agent/session-start`; startup is the serial
|
|
61
|
+
// `agent/created` event with `{ agent, source, signal? }`, and AgentLoop holds
|
|
62
|
+
// queued input until its listeners settle. DSH 0.1.0-rc.6 and 0.1.5 still
|
|
63
|
+
// emit a composition-only `agent/created` with `{ agent }` only, followed by
|
|
64
|
+
// `agent/session-start`, so a missing `source` leaves startup to that event.
|
|
65
|
+
// The listener must resolve to undefined: any other value bails the serial
|
|
66
|
+
// dispatch and skips the listeners registered after this one.
|
|
67
|
+
ctx.on("agent/created", async ({ agent, source, signal }) => {
|
|
68
|
+
if (source === undefined) return undefined;
|
|
69
|
+
await untilAborted(startAgent(agent, signal), signal);
|
|
70
|
+
return undefined;
|
|
44
71
|
});
|
|
72
|
+
ctx.on("agent/session-start", ({ agent }) => startAgent(agent));
|
|
45
73
|
|
|
46
74
|
// prepend: downstream waterfall listeners run first, so this plugin sees
|
|
47
75
|
// the final claimed batch and appends after every other contributor.
|
|
@@ -83,3 +111,18 @@ export function apply(ctx, input = {}) {
|
|
|
83
111
|
mountOpenVikingMcp(ctx, config);
|
|
84
112
|
mountOpenVikingSkills(ctx);
|
|
85
113
|
}
|
|
114
|
+
|
|
115
|
+
// Resolve when `promise` settles or `signal` aborts, whichever comes first. An
|
|
116
|
+
// abandoned initialization keeps running and is reused by the pre-step path.
|
|
117
|
+
function untilAborted(promise, signal) {
|
|
118
|
+
if (!signal) return promise;
|
|
119
|
+
if (signal.aborted) return Promise.resolve();
|
|
120
|
+
return new Promise(resolve => {
|
|
121
|
+
const onAbort = () => resolve();
|
|
122
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
123
|
+
promise.finally(() => {
|
|
124
|
+
signal.removeEventListener("abort", onAbort);
|
|
125
|
+
resolve();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
package/lifecycle.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export async function injectStartupProfile(agent, runtime) {
|
|
1
|
+
export async function injectStartupProfile(agent, runtime, signal) {
|
|
2
2
|
await runtime.initialize(agent);
|
|
3
|
-
if (agent.status !== "idle") return false;
|
|
3
|
+
if (signal?.aborted || agent.status !== "idle") return false;
|
|
4
4
|
const profile = await runtime.profileMessage(agent);
|
|
5
5
|
if (!profile) return false;
|
|
6
6
|
agent.inject(profile);
|
package/package.json
CHANGED
package/servers/mcp-proxy.mjs
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* from the Cordis patch are invisible to a subprocess otherwise.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { realpathSync } from "node:fs";
|
|
13
14
|
import { resolve as resolvePath } from "node:path";
|
|
14
15
|
import { fileURLToPath } from "node:url";
|
|
15
16
|
import { resolveConfig } from "../config.mjs";
|
|
@@ -30,6 +31,15 @@ export function readProxyConfig(env = process.env, cwd = process.cwd()) {
|
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
function isDirectRun() {
|
|
35
|
+
if (!process.argv[1]) return false;
|
|
36
|
+
try {
|
|
37
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
|
|
38
|
+
} catch {
|
|
39
|
+
return resolvePath(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (isDirectRun()) {
|
|
34
44
|
createOpenVikingMcpProxy({ readConfig: readProxyConfig, loggerFactory: createLogger }).start();
|
|
35
45
|
}
|