@lmzhen/dsh-memory 0.3.67 → 0.3.69

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
@@ -21,4 +21,4 @@ Independent of request-prefix construction. This package does not alter the asse
21
21
  ## Known Limitations and Deferred Work
22
22
 
23
23
 
24
- - No known durable consumer gaps at this time. Runtime contracts are covered by package and boundary tests.
24
+ - `provider` pins the registry to one provider name (V27 G6.3); empty (the default) serves the FIRST registered provider, so with two providers mounted the choice is row order. A pin that no mounted provider satisfies warns when a differently-named provider registers and then fails the first read/write with the pin named — the registry and the registration API are one service, so there is no earlier point to check it.
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Service } from "@deepseek-ai/cordis";
2
+ import z from "@deepseek-ai/schemastery";
2
3
  //#region lib/types/index.js
3
4
  /**
4
5
  * Memory provider registry for the evolution family.
@@ -6,17 +7,36 @@ import { Service } from "@deepseek-ai/cordis";
6
7
  * @module @lmzhen/dsh-memory
7
8
  */
8
9
  var MemoryRegistry = class extends Service {
10
+ /**
11
+ * V27 G6.3: the same provider-pin contract the io/state seams use. Before
12
+ * this, every delegation called `provider()` with no name, so with two
13
+ * providers mounted the session-visible store was decided by ROW ORDER while
14
+ * `memory-files.providerName` renamed a registration nothing selected — a
15
+ * config no consumer read. Empty keeps the old behavior (first registered).
16
+ */
17
+ static Config = z.object({ provider: z.string().default("") });
9
18
  providers = /* @__PURE__ */ new Map();
10
- constructor(ctx) {
19
+ providerName;
20
+ pinWarned = false;
21
+ constructor(ctx, config = {}) {
11
22
  super(ctx, "memory");
23
+ this.providerName = config.provider ?? "";
12
24
  }
13
25
  registerProvider(provider) {
14
26
  if (this.providers.has(provider.name)) throw new Error(`memory provider "${provider.name}" already registered`);
15
27
  this.providers.set(provider.name, provider);
28
+ if (this.providerName && provider.name !== this.providerName && !this.providers.has(this.providerName) && !this.pinWarned) {
29
+ this.pinWarned = true;
30
+ this.ctx.logger.warn(`memory: config.provider="${this.providerName}" is not registered (mounted: "${provider.name}"); memory reads and writes fail until that provider mounts`);
31
+ }
16
32
  return () => {
17
33
  if (this.providers.get(provider.name) === provider) this.providers.delete(provider.name);
18
34
  };
19
35
  }
36
+ /** Configured provider: the pinned name, or the first registered one. */
37
+ selected() {
38
+ return this.provider(this.providerName || void 0);
39
+ }
20
40
  /** 0.3.17 (E-73): named lookup like the io/state-storage registries; no
21
41
  * name = first registered (backward compatible). A named miss throws (F-333,
22
42
  * 0.3.23) instead of silently falling back to the first provider, so a wrong
@@ -32,10 +52,10 @@ var MemoryRegistry = class extends Service {
32
52
  return first;
33
53
  }
34
54
  read(target) {
35
- return this.provider().read(target);
55
+ return this.selected().read(target);
36
56
  }
37
57
  async applyBatch(target, operations) {
38
- const result = await this.provider().applyBatch(target, operations);
58
+ const result = await this.selected().applyBatch(target, operations);
39
59
  if (result.ok) this.ctx.emit("evolution/memory-applied", {
40
60
  target,
41
61
  chars: result.chars,
@@ -48,10 +68,10 @@ var MemoryRegistry = class extends Service {
48
68
  * consumer (tests inspect the raw snapshot, kept by declaration).
49
69
  * @internal Exported for this package's own tests only. */
50
70
  snapshot() {
51
- return this.provider().snapshot();
71
+ return this.selected().snapshot();
52
72
  }
53
73
  renderContext() {
54
- return this.provider().renderContext();
74
+ return this.selected().renderContext();
55
75
  }
56
76
  };
57
77
  //#endregion
@@ -4,7 +4,13 @@
4
4
  * @module @lmzhen/dsh-memory
5
5
  */
6
6
  import { Context, Service } from '@deepseek-ai/cordis';
7
+ import type Schema from '@deepseek-ai/schemastery';
7
8
  export type MemoryTarget = 'memory' | 'user';
9
+ /** Service config (V27 G6.3): pin one provider by name. */
10
+ export interface Config {
11
+ /** Provider to use; empty = first registered provider (row order). */
12
+ provider?: string;
13
+ }
8
14
  export interface MemoryOperation {
9
15
  action: 'add' | 'replace' | 'remove';
10
16
  facts?: string | undefined;
@@ -51,9 +57,21 @@ declare module '@deepseek-ai/cordis' {
51
57
  }
52
58
  }
53
59
  export declare class MemoryRegistry extends Service {
60
+ /**
61
+ * V27 G6.3: the same provider-pin contract the io/state seams use. Before
62
+ * this, every delegation called `provider()` with no name, so with two
63
+ * providers mounted the session-visible store was decided by ROW ORDER while
64
+ * `memory-files.providerName` renamed a registration nothing selected — a
65
+ * config no consumer read. Empty keeps the old behavior (first registered).
66
+ */
67
+ static Config: Schema<Config>;
54
68
  private readonly providers;
55
- constructor(ctx: Context);
69
+ private readonly providerName;
70
+ private pinWarned;
71
+ constructor(ctx: Context, config?: Config);
56
72
  registerProvider(provider: MemoryProvider): () => void;
73
+ /** Configured provider: the pinned name, or the first registered one. */
74
+ private selected;
57
75
  /** 0.3.17 (E-73): named lookup like the io/state-storage registries; no
58
76
  * name = first registered (backward compatible). A named miss throws (F-333,
59
77
  * 0.3.23) instead of silently falling back to the first provider, so a wrong
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-memory",
3
3
  "description": "Memory provider registry for self-evolution (community build)",
4
- "version": "0.3.67",
4
+ "version": "0.3.69",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -29,7 +29,9 @@
29
29
  "lib/types/**/*.d.ts"
30
30
  ],
31
31
  "license": "MIT",
32
- "dependencies": {},
32
+ "dependencies": {
33
+ "@deepseek-ai/schemastery": "^3.18.1"
34
+ },
33
35
  "peerDependencies": {
34
36
  "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
35
37
  "@deepseek-ai/cordis": "^4.0.1"