dsh-mnemon-source-memory-spaces 0.5.21 → 0.5.23

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/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { findMnemonCommand, isMnemonExecutable, resolveMnemonInvocation } from "./native-cli.js";
2
- import { CATEGORIES as CATEGORIES$1, EDGE_TYPES, INTENTS as INTENTS$1, MNEMON_EMBEDDING_PROTOCOLS, SOURCES as SOURCES$1, normalizeEntityKey } from "./contracts.js";
3
- import { a as MemoryProviderCatalog, i as EMPTY_MEMORY_PROVIDER_CATALOG, n as PrivateMemorySpaceProviderHost, r as MemoryProviderAdapterRegistry, t as createMemorySpaceProviderPlugin } from "./plugin-DlsNeZbQ.js";
2
+ import { CATEGORIES, EDGE_TYPES, INTENTS, MEMORY_PLACEMENT_CAPABILITIES, MEMORY_PROVIDER_REGISTRY_FILE, MEMORY_SPACES_DIRECTORY, MEMORY_SPACE_DATABASE_FILE, MEMORY_SPACE_DESCRIPTION_MAX_LENGTH, MEMORY_SPACE_ID_PATTERN, MEMORY_SPACE_REGISTRY_FILE, MNEMON_ACTIVE_STORE_FILE, MNEMON_EMBEDDING_PROTOCOLS, NATIVE_PROVIDER_ID, SOURCES, isNativeProvider, normalizeEntityKey } from "./contracts.js";
3
+ import { a as MemoryProviderCatalog, i as EMPTY_MEMORY_PROVIDER_CATALOG, n as PrivateMemorySpaceProviderHost, r as MemoryProviderAdapterRegistry, t as createMemorySpaceProviderPlugin } from "./plugin-m1PeU1IE.js";
4
4
  import { i as runProcess, r as ProcessError } from "./adapter-D-BnWkko.js";
5
5
  import { r as defineMemorySpaceProvider } from "./definitions-DfmOqJjR.js";
6
6
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
@@ -104,7 +104,6 @@ function modelJson(value, maximum) {
104
104
  //#region src/memory-spaces.ts
105
105
  const NATIVE_REGISTRY_VERSION = 1;
106
106
  const PROVIDER_REGISTRY_VERSION = 4;
107
- const ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
108
107
  const PROVIDER_ID_PATTERN = /^[a-z][a-z0-9-]{0,127}$/u;
109
108
  const DISCONNECTS_VERSION = 1;
110
109
  /** Settings whose value can name a namespace: a bank, workspace, user, tag, URI or folder. */
@@ -191,10 +190,10 @@ function providerProjectionMetadata(providerCatalog, providerId, candidate) {
191
190
  const nearestName = PROVIDER_METADATA_KEYS.map((key) => compactProviderMetadataValue(candidate.connection[key])).find((value) => value !== void 0);
192
191
  const fallbackId = compactProviderMetadataValue(externalId) ?? externalId;
193
192
  const name = (mappedName || nearestName || `${descriptor.label} ${fallbackId}`).slice(0, 100);
194
- const description = (String(candidate.description ?? "").trim() || `${descriptor.label} memory namespace mapped from ${externalId}.`).slice(0, 1e3);
193
+ const description = (String(candidate.description ?? "").trim() || `${descriptor.label} memory namespace mapped from ${externalId}.`).slice(0, MEMORY_SPACE_DESCRIPTION_MAX_LENGTH);
195
194
  return {
196
195
  name: requiredText(name, "name", 100),
197
- description: optionalText$1(description, "description", 1e3)
196
+ description: optionalText$1(description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH)
198
197
  };
199
198
  }
200
199
  function providerDisplayLocation(descriptor, connection) {
@@ -232,7 +231,7 @@ function normalizePlacementDecision(value, providerId, providerCatalog = EMPTY_M
232
231
  }
233
232
  function validateMemorySpaceId(value) {
234
233
  const normalized = value.trim();
235
- if (!ID_PATTERN.test(normalized)) throw new Error("memoryBodyId must match [a-zA-Z0-9][a-zA-Z0-9_-]*");
234
+ if (!MEMORY_SPACE_ID_PATTERN.test(normalized)) throw new Error("memoryBodyId must match [a-zA-Z0-9][a-zA-Z0-9_-]*");
236
235
  return normalized;
237
236
  }
238
237
  /**
@@ -265,9 +264,9 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
265
264
  serviceEnabled: {},
266
265
  disconnected: {}
267
266
  };
268
- this.directory = join(runner.effectiveDataDir(), "data");
269
- this.registryPath = join(this.directory, ".dsh-memory-bodies.json");
270
- this.providerRegistryPath = join(runner.effectiveDataDir(), "state", "memory-providers.json");
267
+ this.directory = join(runner.effectiveDataDir(), MEMORY_SPACES_DIRECTORY);
268
+ this.registryPath = join(this.directory, MEMORY_SPACE_REGISTRY_FILE);
269
+ this.providerRegistryPath = join(runner.effectiveDataDir(), "state", MEMORY_PROVIDER_REGISTRY_FILE);
271
270
  this.disconnectsPath = join(runner.effectiveDataDir(), "state", "memory-provider-disconnects.json");
272
271
  if (sharedState === void 0) this.reload();
273
272
  }
@@ -300,7 +299,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
300
299
  return new MemorySpaceRegistry(this.runner, this.persistent, this.now, providerCatalog, this.state);
301
300
  }
302
301
  isNative(providerId) {
303
- return this.providerTypeId(providerId) === "mnemon-native";
302
+ return this.providerTypeId(providerId) === NATIVE_PROVIDER_ID;
304
303
  }
305
304
  providerTypeId(providerId) {
306
305
  const descriptor = this.providerCatalog.descriptor(providerId);
@@ -355,7 +354,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
355
354
  }
356
355
  providerServices(options = {}) {
357
356
  this.refreshIfChanged();
358
- const providers = this.providerCatalog.providers.filter((provider) => (provider.typeId ?? provider.id) !== "mnemon-native");
357
+ const providers = this.providerCatalog.providers.filter((provider) => !isNativeProvider(provider));
359
358
  const items = providers.map((provider) => {
360
359
  const connection = this.services[provider.id];
361
360
  const publicConnection = this.providerCatalog.publicScoped(provider.id, "service", connection ?? {});
@@ -647,7 +646,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
647
646
  }
648
647
  async create(request, signal, placement) {
649
648
  const name = requiredText(request.name, "name", 100);
650
- const description = requiredText(request.description, "description", 1e3);
649
+ const description = requiredText(request.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH);
651
650
  if (request.placement !== void 0 && placement === void 0) throw new Error("automatic provider placement must be resolved before creating a Memory Space");
652
651
  if (placement !== void 0 && request.providerId !== void 0 && request.providerId !== placement.providerId) throw new Error("resolved provider placement conflicts with providerId");
653
652
  const providerId = placement?.providerId ?? request.providerId ?? this.defaultProviderId();
@@ -734,7 +733,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
734
733
  const body = {
735
734
  ...currentBody,
736
735
  ...request.name === void 0 ? {} : { name: requiredText(request.name, "name", 100) },
737
- ...request.description === void 0 ? {} : { description: optionalText$1(request.description, "description", 1e3) },
736
+ ...request.description === void 0 ? {} : { description: optionalText$1(request.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH) },
738
737
  ...request.active === void 0 ? {} : { active: request.active },
739
738
  ...nativeProvider || request.name === void 0 && request.description === void 0 ? {} : { metadataSource: "manual" },
740
739
  ...connection === void 0 ? {} : { connection },
@@ -874,14 +873,14 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
874
873
  const parsed = JSON.parse(readFileSync(this.registryPath, "utf8"));
875
874
  if ((parsed.version === NATIVE_REGISTRY_VERSION || parsed.version === 2) && Array.isArray(parsed.bodies)) {
876
875
  migratedProviderRegistry = parsed.version === 2;
877
- this.spaces = parsed.bodies.filter((body) => ID_PATTERN.test(body.id)).map((body) => {
876
+ this.spaces = parsed.bodies.filter((body) => MEMORY_SPACE_ID_PATTERN.test(body.id)).map((body) => {
878
877
  const syntheticDefault = body.id === "default" && body.name === "默认记忆体" && body.description === "从现有 Mnemon Store 自动接入。";
879
878
  migratedSyntheticDefault ||= syntheticDefault;
880
- const providerId = "providerId" in body && storedProviderId(body.providerId) ? body.providerId : "mnemon-native";
879
+ const providerId = "providerId" in body && storedProviderId(body.providerId) ? body.providerId : NATIVE_PROVIDER_ID;
881
880
  if (!this.providerCatalog.has(providerId)) return {
882
881
  id: body.id,
883
882
  name: requiredText(body.name || body.id, "name", 100),
884
- description: optionalText$1(body.description, "description", 1e3),
883
+ description: optionalText$1(body.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH),
885
884
  active: body.active === true,
886
885
  providerId,
887
886
  connection: storedProviderConnection("connection" in body ? body.connection : void 0),
@@ -903,7 +902,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
903
902
  return {
904
903
  id: body.id,
905
904
  name: requiredText(syntheticDefault ? body.id : body.name || body.id, "name", 100),
906
- description: optionalText$1(syntheticDefault ? "Existing Mnemon Store discovered on disk." : body.description, "description", 1e3),
905
+ description: optionalText$1(syntheticDefault ? "Existing Mnemon Store discovered on disk." : body.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH),
907
906
  active: body.active === true,
908
907
  providerId,
909
908
  ...placement === void 0 ? {} : { placement },
@@ -927,12 +926,12 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
927
926
  if ((parsed.version === 1 || parsed.version === 2 || parsed.version === 3 || parsed.version === PROVIDER_REGISTRY_VERSION) && Array.isArray(parsed.bodies)) {
928
927
  migratedProviderRegistry ||= parsed.version !== PROVIDER_REGISTRY_VERSION;
929
928
  const existingIds = new Set(this.spaces.map((body) => body.id));
930
- this.spaces.push(...parsed.bodies.filter((body) => storedProviderId(body.providerId) && (!this.providerCatalog.has(body.providerId) || !this.isNative(body.providerId)) && ID_PATTERN.test(body.id) && !existingIds.has(body.id)).map((body) => {
929
+ this.spaces.push(...parsed.bodies.filter((body) => storedProviderId(body.providerId) && (!this.providerCatalog.has(body.providerId) || !this.isNative(body.providerId)) && MEMORY_SPACE_ID_PATTERN.test(body.id) && !existingIds.has(body.id)).map((body) => {
931
930
  const providerId = body.providerId;
932
931
  if (!this.providerCatalog.has(providerId)) return {
933
932
  id: body.id,
934
933
  name: requiredText(body.name || body.id, "name", 100),
935
- description: optionalText$1(body.description, "description", 1e3),
934
+ description: optionalText$1(body.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH),
936
935
  active: body.active === true,
937
936
  providerId,
938
937
  ...typeof body.externalId !== "string" || body.externalId.trim() === "" ? {} : { externalId: body.externalId.trim() },
@@ -959,7 +958,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
959
958
  return {
960
959
  id: body.id,
961
960
  name: requiredText(body.name || body.id, "name", 100),
962
- description: optionalText$1(body.description, "description", 1e3),
961
+ description: optionalText$1(body.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH),
963
962
  active: body.active === true,
964
963
  providerId,
965
964
  ...typeof body.externalId !== "string" || body.externalId.trim() === "" ? {} : { externalId: body.externalId.trim() },
@@ -994,14 +993,14 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
994
993
  let changed = false;
995
994
  const knownIds = new Set(this.spaces.map((body) => body.id));
996
995
  for (const entry of readdirSync(this.directory, { withFileTypes: true })) {
997
- if (!entry.isDirectory() || !ID_PATTERN.test(entry.name) || !existsSync(join(this.directory, entry.name, "mnemon.db"))) continue;
996
+ if (!entry.isDirectory() || !MEMORY_SPACE_ID_PATTERN.test(entry.name) || !existsSync(join(this.directory, entry.name, "mnemon.db"))) continue;
998
997
  if (knownIds.has(entry.name)) continue;
999
998
  this.spaces.push({
1000
999
  id: entry.name,
1001
1000
  name: entry.name,
1002
1001
  description: "Existing Mnemon Store discovered on disk.",
1003
1002
  active: this.spaces.length === 0 || entry.name === legacyActive,
1004
- providerId: "mnemon-native",
1003
+ providerId: NATIVE_PROVIDER_ID,
1005
1004
  createdAt: timestamp,
1006
1005
  updatedAt: timestamp
1007
1006
  });
@@ -1012,7 +1011,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
1012
1011
  }
1013
1012
  nativeStoreIds() {
1014
1013
  if (!existsSync(this.directory)) return [];
1015
- return readdirSync(this.directory, { withFileTypes: true }).filter((entry) => entry.isDirectory() && ID_PATTERN.test(entry.name)).map((entry) => entry.name).sort();
1014
+ return readdirSync(this.directory, { withFileTypes: true }).filter((entry) => entry.isDirectory() && MEMORY_SPACE_ID_PATTERN.test(entry.name)).map((entry) => entry.name).sort();
1016
1015
  }
1017
1016
  nextTimestamp(previous, candidate = this.now().toISOString()) {
1018
1017
  if (previous === void 0) return candidate;
@@ -1027,7 +1026,7 @@ var MemorySpaceRegistry = class MemorySpaceRegistry {
1027
1026
  const connection = nativeProvider ? {} : this.connectionFor(body);
1028
1027
  const effectivePublicConnection = this.providerCatalog.public(body.providerId, connection);
1029
1028
  const publicConnection = nativeProvider ? effectivePublicConnection : this.providerCatalog.publicScoped(body.providerId, "memory", body.connection ?? {});
1030
- const location = nativeProvider ? join(this.directory, body.id, "mnemon.db") : providerDisplayLocation(descriptor, connection);
1029
+ const location = nativeProvider ? join(this.directory, body.id, MEMORY_SPACE_DATABASE_FILE) : providerDisplayLocation(descriptor, connection);
1031
1030
  const provider = {
1032
1031
  id: descriptor.id,
1033
1032
  ...descriptor.typeId === void 0 || descriptor.typeId === descriptor.id ? {} : { typeId: descriptor.typeId },
@@ -1156,10 +1155,10 @@ function createRunner(config, processRunner = runProcess) {
1156
1155
  };
1157
1156
  const effectiveDataDir = () => config.dataDir;
1158
1157
  const persistedStore = () => {
1159
- const active = join(effectiveDataDir(), "active");
1158
+ const active = join(effectiveDataDir(), MNEMON_ACTIVE_STORE_FILE);
1160
1159
  if (existsSync(active)) try {
1161
1160
  const value = readFileSync(active, "utf8").trim();
1162
- if (/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value)) return value;
1161
+ if (MEMORY_SPACE_ID_PATTERN.test(value)) return value;
1163
1162
  } catch {}
1164
1163
  return "default";
1165
1164
  };
@@ -1473,6 +1472,11 @@ function scoreDecision(candidate, context, lowScoreAction, nonPositiveAction) {
1473
1472
  tier: "unknown",
1474
1473
  reason: "invalid-score"
1475
1474
  };
1475
+ if (candidate.scoreSemantics?.kind === "provider-native") return {
1476
+ action: "keep",
1477
+ tier: "ranked",
1478
+ reason: "native-score"
1479
+ };
1476
1480
  if (candidate.scoreSemantics?.kind !== "normalized-relevance") return {
1477
1481
  action: "keep",
1478
1482
  tier: "unknown",
@@ -1486,8 +1490,8 @@ function scoreDecision(candidate, context, lowScoreAction, nonPositiveAction) {
1486
1490
  };
1487
1491
  if (score > 1) return {
1488
1492
  action: "keep",
1489
- tier: "unknown",
1490
- reason: "unscaled-score"
1493
+ tier: "ranked",
1494
+ reason: "out-of-range-score"
1491
1495
  };
1492
1496
  if (score < context.config.lowScoreThreshold) return {
1493
1497
  action: lowScoreAction,
@@ -1517,9 +1521,12 @@ const STRICT_RECALL_QUALITY_POLICY = {
1517
1521
  evaluate: (candidate, context) => scoreDecision(candidate, context, "drop", "drop"),
1518
1522
  select(candidates, context) {
1519
1523
  const kept = candidates.filter((candidate) => candidate.decision.action === "keep");
1524
+ let medium = 0;
1525
+ let ranked = 0;
1526
+ const scored = kept.filter(({ decision }) => decision.tier === "medium" ? medium++ < context.config.maxMediumResults : decision.tier === "ranked" && ranked++ < context.config.maxRankedResults);
1520
1527
  return [
1521
1528
  ...kept.filter((candidate) => candidate.decision.tier === "high"),
1522
- ...kept.filter((candidate) => candidate.decision.tier === "medium").slice(0, context.config.maxMediumResults),
1529
+ ...scored,
1523
1530
  ...kept.filter((candidate) => candidate.decision.tier === "unknown").slice(0, context.config.maxUnknownResults)
1524
1531
  ].slice(0, context.requestedLimit);
1525
1532
  }
@@ -1548,6 +1555,7 @@ const ACTIONS = /* @__PURE__ */ new Set(["keep", "drop"]);
1548
1555
  const TIERS = /* @__PURE__ */ new Set([
1549
1556
  "high",
1550
1557
  "medium",
1558
+ "ranked",
1551
1559
  "low",
1552
1560
  "unknown"
1553
1561
  ]);
@@ -1557,6 +1565,8 @@ const REASONS = /* @__PURE__ */ new Set([
1557
1565
  "low-score",
1558
1566
  "non-positive-score",
1559
1567
  "invalid-score",
1568
+ "native-score",
1569
+ "out-of-range-score",
1560
1570
  "unscaled-score",
1561
1571
  "unscored"
1562
1572
  ]);
@@ -1946,11 +1956,11 @@ var MemorySpacesService = class {
1946
1956
  const descriptor = catalog.descriptor(providerId);
1947
1957
  return descriptor.typeId ?? descriptor.id;
1948
1958
  }
1949
- isNativeProvider(providerId) {
1950
- return this.providerTypeId(providerId) === "mnemon-native";
1959
+ isNativeProviderId(providerId) {
1960
+ return this.providerTypeId(providerId) === NATIVE_PROVIDER_ID;
1951
1961
  }
1952
1962
  isNativeSpace(body) {
1953
- return (body.provider.typeId ?? body.provider.id) === "mnemon-native";
1963
+ return isNativeProvider(body.provider);
1954
1964
  }
1955
1965
  constructor(runner, config, memorySpaces, recallQualityPolicyRegistry = recallQualityPolicies, providerAdapterRegistry = new MemoryProviderAdapterRegistry(), providerCatalog = EMPTY_MEMORY_PROVIDER_CATALOG) {
1956
1966
  this.runner = runner;
@@ -2040,7 +2050,7 @@ var MemorySpacesService = class {
2040
2050
  items,
2041
2051
  providers: this.providerCatalog.providers.map((provider) => ({
2042
2052
  ...provider,
2043
- serviceConfigured: (provider.typeId ?? provider.id) === "mnemon-native" ? this.runner.commandFound : enabled.has(provider.id)
2053
+ serviceConfigured: isNativeProvider(provider) ? this.runner.commandFound : enabled.has(provider.id)
2044
2054
  })),
2045
2055
  persistenceStrategy: {
2046
2056
  mode: this.config.persistenceStrategy.mode,
@@ -2131,6 +2141,7 @@ var MemorySpacesService = class {
2131
2141
  timeoutMs: this.config.timeoutMs,
2132
2142
  defaultRecallLimit: this.config.defaultRecallLimit,
2133
2143
  recallQuality: this.config.recallQuality,
2144
+ embeddingManaged: this.config.embedding.enabled,
2134
2145
  memoryBodyDirectory: catalog.directory,
2135
2146
  memoryBodies: catalog.items,
2136
2147
  providerServices,
@@ -2310,6 +2321,7 @@ var MemorySpacesService = class {
2310
2321
  timeoutMs: this.config.timeoutMs,
2311
2322
  defaultRecallLimit: this.config.defaultRecallLimit,
2312
2323
  recallQuality: this.config.recallQuality,
2324
+ embeddingManaged: this.config.embedding.enabled,
2313
2325
  memoryBodyDirectory: catalog.directory,
2314
2326
  memoryBodies: catalog.items,
2315
2327
  providerServices
@@ -2388,9 +2400,9 @@ var MemorySpacesService = class {
2388
2400
  "keyword",
2389
2401
  "basic"
2390
2402
  ], "mode") ?? "smart";
2391
- const category = allowed(request.category, CATEGORIES$1, "category");
2392
- const source = allowed(request.source, SOURCES$1, "source");
2393
- const intent = allowed(request.intent, INTENTS$1, "intent");
2403
+ const category = allowed(request.category, CATEGORIES, "category");
2404
+ const source = allowed(request.source, SOURCES, "source");
2405
+ const intent = allowed(request.intent, INTENTS, "intent");
2394
2406
  const spaces = this.readSpaces(request.memoryBodyIds);
2395
2407
  const normalizedRequest = {
2396
2408
  query,
@@ -2448,7 +2460,8 @@ var MemorySpacesService = class {
2448
2460
  }
2449
2461
  const heterogeneous = new Set(spaces.map((body) => body.provider.id)).size > 1;
2450
2462
  if (heterogeneous) for (const candidate of candidates) candidate.insight.federatedScore = 1 / (60 + candidate.providerRank);
2451
- candidates.sort((left, right) => heterogeneous ? (right.insight.federatedScore ?? 0) - (left.insight.federatedScore ?? 0) || left.bodyOrder - right.bodyOrder : (right.insight.score ?? 0) - (left.insight.score ?? 0));
2463
+ const useProviderOrder = heterogeneous || candidates.some((candidate) => candidate.scoreSemantics?.kind === "provider-native");
2464
+ candidates.sort((left, right) => useProviderOrder ? left.providerRank - right.providerRank || left.bodyOrder - right.bodyOrder : (right.insight.score ?? 0) - (left.insight.score ?? 0));
2452
2465
  return {
2453
2466
  hints,
2454
2467
  quality: applyRecallQualityPolicy(preparedPolicy, candidates, qualityContext)
@@ -2508,6 +2521,8 @@ var MemorySpacesService = class {
2508
2521
  }
2509
2522
  if (decision.reason === "unscored") stats.unscored += 1;
2510
2523
  if (decision.reason === "unscaled-score") stats.unscaled += 1;
2524
+ if (decision.tier === "ranked") stats.ranked = (stats.ranked ?? 0) + 1;
2525
+ if (decision.reason === "out-of-range-score") stats.outOfRange = (stats.outOfRange ?? 0) + 1;
2511
2526
  }
2512
2527
  for (const { candidate } of quality.selected) {
2513
2528
  const stats = qualityStats.get(candidate.memoryBodyId);
@@ -2647,7 +2662,7 @@ var MemorySpacesService = class {
2647
2662
  const rawQuery = request.query?.trim() ?? "";
2648
2663
  const query = rawQuery.toLocaleLowerCase();
2649
2664
  if (rawQuery.length > 500) throw new Error("query is too long (max 500 characters)");
2650
- const category = allowed(request.category, CATEGORIES$1, "category");
2665
+ const category = allowed(request.category, CATEGORIES, "category");
2651
2666
  const limit = memoryInputInteger(request.limit, 200, 1, 1e3);
2652
2667
  const spaces = this.readSpaces(request.memoryBodyIds);
2653
2668
  const batches = await Promise.all(spaces.map(async (body) => {
@@ -3023,7 +3038,7 @@ var MemorySpacesService = class {
3023
3038
  return this.createSpace({
3024
3039
  ...body,
3025
3040
  ...providerId === void 0 ? {} : { providerId },
3026
- ...providerId === void 0 || this.isNativeProvider(providerId) || connection === void 0 ? {} : { connection }
3041
+ ...providerId === void 0 || this.isNativeProviderId(providerId) || connection === void 0 ? {} : { connection }
3027
3042
  }, signal);
3028
3043
  }
3029
3044
  const request = {
@@ -3050,7 +3065,7 @@ var MemorySpacesService = class {
3050
3065
  }
3051
3066
  async updateProviderService(providerId, settings, clearSecrets = [], enabled = true, signal) {
3052
3067
  this.assertWritable();
3053
- if (this.isNativeProvider(providerId)) throw new Error("Mnemon Native service settings are managed by the native configuration");
3068
+ if (this.isNativeProviderId(providerId)) throw new Error("Mnemon Native service settings are managed by the native configuration");
3054
3069
  if (!enabled) return this.memorySpaces.updateProviderService(providerId, settings, clearSecrets, false);
3055
3070
  const connection = this.memorySpaces.resolveProviderService(providerId, settings, clearSecrets);
3056
3071
  const provider = this.providers.get(providerId);
@@ -3090,7 +3105,7 @@ var MemorySpacesService = class {
3090
3105
  }
3091
3106
  }
3092
3107
  async runRediscovery(trigger, signal, providerTimeoutMs) {
3093
- const services = this.memorySpaces.providerServices().items.filter((item) => item.enabled && !this.isNativeProvider(item.providerId));
3108
+ const services = this.memorySpaces.providerServices().items.filter((item) => item.enabled && !this.isNativeProviderId(item.providerId));
3094
3109
  const results = await Promise.all(services.map(async (item) => {
3095
3110
  const provider = this.providers.get(item.providerId);
3096
3111
  if (provider?.discover === void 0) return void 0;
@@ -3290,16 +3305,16 @@ var MemorySpacesService = class {
3290
3305
  const body = destinations?.get(key) ?? this.writeSpace(request.memoryBodyId);
3291
3306
  destinations?.set(key, body);
3292
3307
  const content = required(request.content, "content", 8192);
3293
- const importance = memoryInputInteger(request.importance, 3, 1, 5);
3294
- const category = allowed(request.category, CATEGORIES$1, "category") ?? "general";
3295
- const source = allowed(request.source, SOURCES$1, "source") ?? "user";
3308
+ const importance = request.importance === void 0 ? void 0 : memoryInputInteger(request.importance, 3, 1, 5);
3309
+ const category = allowed(request.category, CATEGORIES, "category") ?? "general";
3310
+ const source = allowed(request.source, SOURCES, "source") ?? "user";
3296
3311
  const tags = commaList(request.tags, "tags", 20)?.split(",");
3297
3312
  const entities = commaList(request.entities, "entities", 50)?.split(",");
3298
3313
  return {
3299
3314
  body,
3300
3315
  request: {
3301
3316
  content,
3302
- importance,
3317
+ ...importance === void 0 ? {} : { importance },
3303
3318
  category,
3304
3319
  source,
3305
3320
  memoryBodyId: body.id,
@@ -3355,14 +3370,7 @@ function optionalText(value) {
3355
3370
  return value?.trim() || void 0;
3356
3371
  }
3357
3372
  const MEMORY_PROVIDER_ID = /^[a-z][a-z0-9-]{0,127}$/u;
3358
- const MEMORY_PLACEMENT_CAPABILITY_SET = /* @__PURE__ */ new Set([
3359
- "graph",
3360
- "entities",
3361
- "related",
3362
- "exact-write",
3363
- "link",
3364
- "forget"
3365
- ]);
3373
+ const MEMORY_PLACEMENT_CAPABILITY_SET = new Set(MEMORY_PLACEMENT_CAPABILITIES);
3366
3374
  const MEMORY_PLACEMENT_PREFERENCE_SET = /* @__PURE__ */ new Set([
3367
3375
  "balanced",
3368
3376
  "local-first",
@@ -3376,7 +3384,7 @@ function resolvePersistenceStrategy(value) {
3376
3384
  const prompt = value?.prompt?.trim() ?? "";
3377
3385
  if (prompt.length > 4e3) throw new Error("dsh-mnemon: persistence strategy prompt is too long (max 4000 characters)");
3378
3386
  const configuredProviderIds = value?.rules?.allowedProviderIds;
3379
- const allowedProviderIds = [...new Set(configuredProviderIds === void 0 || configuredProviderIds.length === 0 && mode === "manual" ? ["mnemon-native"] : configuredProviderIds)];
3387
+ const allowedProviderIds = [...new Set(configuredProviderIds === void 0 || configuredProviderIds.length === 0 && mode === "manual" ? [NATIVE_PROVIDER_ID] : configuredProviderIds)];
3380
3388
  if (allowedProviderIds.length === 0) throw new Error("dsh-mnemon: persistence strategy requires at least one allowed provider");
3381
3389
  for (const id of allowedProviderIds) if (!MEMORY_PROVIDER_ID.test(id)) throw new Error(`dsh-mnemon: invalid persistence strategy provider: ${String(id)}`);
3382
3390
  const dataBoundary = value?.rules?.dataBoundary ?? "allow-remote";
@@ -3439,12 +3447,14 @@ function resolveRecallQuality(value) {
3439
3447
  const highScoreThreshold = value?.highScoreThreshold ?? .6;
3440
3448
  const candidateMultiplier = value?.candidateMultiplier ?? 3;
3441
3449
  const maxMediumResults = value?.maxMediumResults ?? 4;
3450
+ const maxRankedResults = value?.maxRankedResults ?? 4;
3442
3451
  const maxUnknownResults = value?.maxUnknownResults ?? 2;
3443
3452
  if (!Number.isFinite(lowScoreThreshold) || lowScoreThreshold < 0 || lowScoreThreshold > 1) throw new Error("dsh-mnemon: recall low score threshold must be within 0..1");
3444
3453
  if (!Number.isFinite(highScoreThreshold) || highScoreThreshold < 0 || highScoreThreshold > 1) throw new Error("dsh-mnemon: recall high score threshold must be within 0..1");
3445
3454
  if (lowScoreThreshold >= highScoreThreshold) throw new Error("dsh-mnemon: recall low score threshold must be less than the high score threshold");
3446
3455
  if (!Number.isInteger(candidateMultiplier) || candidateMultiplier < 1 || candidateMultiplier > 5) throw new Error("dsh-mnemon: recall candidate multiplier must be an integer within 1..5");
3447
3456
  if (!Number.isInteger(maxMediumResults) || maxMediumResults < 0 || maxMediumResults > 50) throw new Error("dsh-mnemon: recall max medium results must be an integer within 0..50");
3457
+ if (!Number.isInteger(maxRankedResults) || maxRankedResults < 0 || maxRankedResults > 50) throw new Error("dsh-mnemon: recall max ranked results must be an integer within 0..50");
3448
3458
  if (!Number.isInteger(maxUnknownResults) || maxUnknownResults < 0 || maxUnknownResults > 50) throw new Error("dsh-mnemon: recall max unknown results must be an integer within 0..50");
3449
3459
  return {
3450
3460
  policy,
@@ -3452,6 +3462,7 @@ function resolveRecallQuality(value) {
3452
3462
  highScoreThreshold,
3453
3463
  candidateMultiplier,
3454
3464
  maxMediumResults,
3465
+ maxRankedResults,
3455
3466
  maxUnknownResults
3456
3467
  };
3457
3468
  }
@@ -3462,7 +3473,7 @@ function resolveMemorySpacesConfig(value = {}, sourceInstanceKey = "standalone")
3462
3473
  const dataDir = requested === void 0 ? join(homedir(), ".mnemon", "sources", encodeURIComponent(sourceInstanceKey)) : requested === "~" ? homedir() : requested.startsWith("~/") ? join(homedir(), requested.slice(2)) : requested;
3463
3474
  if (!isAbsolute(dataDir)) throw new Error("Memory Spaces dataDir must be absolute or start with ~/");
3464
3475
  const store = optionalText(config.store);
3465
- if (store !== void 0 && !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/u.test(store)) throw new Error("Memory Spaces store has an invalid identifier");
3476
+ if (store !== void 0 && !MEMORY_SPACE_ID_PATTERN.test(store)) throw new Error("Memory Spaces store has an invalid identifier");
3466
3477
  const cliPath = optionalText(config.cliPath);
3467
3478
  return {
3468
3479
  storageScope: "custom",
@@ -3479,31 +3490,10 @@ function resolveMemorySpacesConfig(value = {}, sourceInstanceKey = "standalone")
3479
3490
  }
3480
3491
  //#endregion
3481
3492
  //#region src/source.ts
3482
- const CATEGORIES = /* @__PURE__ */ new Set([
3483
- "preference",
3484
- "decision",
3485
- "fact",
3486
- "insight",
3487
- "context",
3488
- "general"
3489
- ]);
3490
- const SOURCES = /* @__PURE__ */ new Set([
3491
- "user",
3492
- "agent",
3493
- "external"
3494
- ]);
3495
- const INTENTS = /* @__PURE__ */ new Set([
3496
- "WHY",
3497
- "WHEN",
3498
- "ENTITY",
3499
- "GENERAL"
3500
- ]);
3501
- const EDGES = /* @__PURE__ */ new Set([
3502
- "temporal",
3503
- "semantic",
3504
- "causal",
3505
- "entity"
3506
- ]);
3493
+ const CATEGORY_SET = new Set(CATEGORIES);
3494
+ const SOURCE_SET = new Set(SOURCES);
3495
+ const INTENT_SET = new Set(INTENTS);
3496
+ const EDGE_SET = new Set(EDGE_TYPES);
3507
3497
  function grantIds(grant) {
3508
3498
  return memoryInputStringArray(memoryInputRecord(grant.value, "Memory Spaces ReadGrant").memoryBodyIds, "memoryBodyIds", 1e4) ?? [];
3509
3499
  }
@@ -3544,7 +3534,7 @@ function createSpaceRequest(value) {
3544
3534
  };
3545
3535
  return {
3546
3536
  name: memoryInputText(input.name, "name", 100),
3547
- description: memoryInputText(input.description, "description", 1e3),
3537
+ description: memoryInputText(input.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH),
3548
3538
  ...typeof input.active !== "boolean" ? {} : { active: input.active },
3549
3539
  ...providerId === void 0 ? {} : { providerId },
3550
3540
  ...connection === void 0 ? {} : { connection },
@@ -3559,7 +3549,7 @@ function updateSpaceRequest(value) {
3559
3549
  memoryBodyId: memoryInputText(input.memoryBodyId, "memoryBodyId", 300),
3560
3550
  request: {
3561
3551
  ...memoryInputText(input.name, "name", 100, false) === void 0 ? {} : { name: memoryInputText(input.name, "name", 100, false) },
3562
- ...memoryInputText(input.description, "description", 1e3, false) === void 0 ? {} : { description: memoryInputText(input.description, "description", 1e3, false) },
3552
+ ...memoryInputText(input.description, "description", 1e3, false) === void 0 ? {} : { description: memoryInputText(input.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH, false) },
3563
3553
  ...typeof input.active !== "boolean" ? {} : { active: input.active },
3564
3554
  ...connection === void 0 ? {} : { connection },
3565
3555
  ...memoryInputStringArray(input.clearSecrets, "clearSecrets", 100) === void 0 ? {} : { clearSecrets: memoryInputStringArray(input.clearSecrets, "clearSecrets", 100) }
@@ -3595,7 +3585,7 @@ function outsideView(service, memoryBodyId) {
3595
3585
  if (!body.active) return `${space} is switched off, so this turn's View does not read it and cannot forget from it. Whether it is on is the user's choice, on the Memory Spaces page; once it is on, a forget there works from the next turn`;
3596
3586
  if (body.providerEnabled === false) return `${space} uses ${body.provider.label}, which is turned off on the dsh-mnemon page under Plugins`;
3597
3587
  const provider = catalog.providers.find((candidate) => candidate.id === body.provider.id);
3598
- if (provider?.serviceConfigured === false) return `${space} uses ${body.provider.label}, which is not available here${(provider.typeId ?? provider.id) === "mnemon-native" ? ": the Mnemon CLI is not installed" : ""}`;
3588
+ if (provider?.serviceConfigured === false) return `${space} uses ${body.provider.label}, which is not available here${isNativeProvider(provider) ? ": the Mnemon CLI is not installed" : ""}`;
3599
3589
  return `${space} was switched on after this turn began, so this turn's View does not read it yet; a forget there works from the next turn`;
3600
3590
  }
3601
3591
  /** The switched-off spaces a forget cannot reach this turn, named only when there are some (#390). */
@@ -4096,9 +4086,9 @@ function createMemorySpacesSource(providerSnapshot, config = {}) {
4096
4086
  const category = memoryInputText(input.category, "category", 30, false);
4097
4087
  const source = memoryInputText(input.source, "source", 30, false);
4098
4088
  const intent = memoryInputText(input.intent, "intent", 30, false);
4099
- if (category !== void 0 && !CATEGORIES.has(category)) throw new Error(`unsupported category: ${category}`);
4100
- if (source !== void 0 && !SOURCES.has(source)) throw new Error(`unsupported source: ${source}`);
4101
- if (intent !== void 0 && !INTENTS.has(intent)) throw new Error(`unsupported intent: ${intent}`);
4089
+ if (category !== void 0 && !CATEGORY_SET.has(category)) throw new Error(`unsupported category: ${category}`);
4090
+ if (source !== void 0 && !SOURCE_SET.has(source)) throw new Error(`unsupported source: ${source}`);
4091
+ if (intent !== void 0 && !INTENT_SET.has(intent)) throw new Error(`unsupported intent: ${intent}`);
4102
4092
  const requestedSpaces = memoryInputStringArray(input.memoryBodyIds, "memoryBodyIds", 1e4) ?? allowedBodies;
4103
4093
  if (requestedSpaces.some((id) => !allowedBodies.includes(id))) throw new Error("Recall requested a Memory Space outside this View ReadGrant");
4104
4094
  const mode = memoryInputText(input.mode, "mode", 20, false);
@@ -4120,7 +4110,7 @@ function createMemorySpacesSource(providerSnapshot, config = {}) {
4120
4110
  if (owner === void 0) throw new Error("related-memory traversal requires evidence already admitted by this View, or an id found in a Memory Space it can read");
4121
4111
  if (!allowedBodies.includes(owner)) throw new Error("related-memory owner is outside this View ReadGrant");
4122
4112
  const edge = memoryInputText(input.edge, "edge", 30, false);
4123
- if (edge !== void 0 && !EDGES.has(edge)) throw new Error(`unsupported edge: ${edge}`);
4113
+ if (edge !== void 0 && !EDGE_SET.has(edge)) throw new Error(`unsupported edge: ${edge}`);
4124
4114
  const results = await service.related(id, memoryInputInteger(input.depth, 2, 1, 5), edge, request.signal, owner);
4125
4115
  return evidence(request, results);
4126
4116
  }
@@ -4160,7 +4150,7 @@ function createMemorySpacesSource(providerSnapshot, config = {}) {
4160
4150
  if (!writableBodies.includes(bodyId)) throw new Error("Memory Space update is outside this View scope");
4161
4151
  const body = service.updateSpace(bodyId, {
4162
4152
  ...input.name === void 0 ? {} : { name: memoryInputText(input.name, "name", 100) },
4163
- ...input.description === void 0 ? {} : { description: memoryInputText(input.description, "description", 1e3) },
4153
+ ...input.description === void 0 ? {} : { description: memoryInputText(input.description, "description", MEMORY_SPACE_DESCRIPTION_MAX_LENGTH) },
4164
4154
  ...typeof input.active === "boolean" ? { active: input.active } : {}
4165
4155
  });
4166
4156
  result = {
@@ -4187,8 +4177,8 @@ function createMemorySpacesSource(providerSnapshot, config = {}) {
4187
4177
  if (!writableBodies.includes(bodyId)) throw new Error("remember destination is outside this View scope");
4188
4178
  const category = memoryInputText(input.category, "category", 30, false);
4189
4179
  const source = memoryInputText(input.source, "source", 30, false);
4190
- if (category !== void 0 && !CATEGORIES.has(category)) throw new Error(`unsupported category: ${category}`);
4191
- if (source !== void 0 && !SOURCES.has(source)) throw new Error(`unsupported source: ${source}`);
4180
+ if (category !== void 0 && !CATEGORY_SET.has(category)) throw new Error(`unsupported category: ${category}`);
4181
+ if (source !== void 0 && !SOURCE_SET.has(source)) throw new Error(`unsupported source: ${source}`);
4192
4182
  result = await service.remember({
4193
4183
  content: memoryInputText(input.content, "content", 1e5),
4194
4184
  ...category === void 0 ? {} : { category },
@@ -4206,7 +4196,7 @@ function createMemorySpacesSource(providerSnapshot, config = {}) {
4206
4196
  if (sourceSpace === void 0 || targetSpace === void 0 || sourceSpace !== targetSpace || !allowedBodies.includes(sourceSpace)) throw new Error("link requires two evidence items admitted by this View from the same Memory Space, or two ids found in one Memory Space it can read");
4207
4197
  bodyId = sourceSpace;
4208
4198
  const edge = memoryInputText(input.type, "type", 30, false);
4209
- if (edge !== void 0 && !EDGES.has(edge)) throw new Error(`unsupported edge: ${edge}`);
4199
+ if (edge !== void 0 && !EDGE_SET.has(edge)) throw new Error(`unsupported edge: ${edge}`);
4210
4200
  const weight = typeof input.weight === "number" ? input.weight : .5;
4211
4201
  result = await service.link(sourceId, targetId, edge, weight, memoryInputText(input.reason, "reason", 1e3, false), request.signal, bodyId);
4212
4202
  } else if (request.offer.sourceActionId === "forget") {
@@ -1,3 +1,4 @@
1
+ import { isNativeProvider } from "./contracts.js";
1
2
  import { a as digest, i as defineMemorySpaceProviderDefinition, o as requiredId } from "./definitions-DfmOqJjR.js";
2
3
  //#region src/providers/catalog.ts
3
4
  function memoryProviderDescriptor(id, catalog = []) {
@@ -35,7 +36,7 @@ function validateFieldBounds(field, value) {
35
36
  }
36
37
  function normalizeScopedProviderConnection(providerId, scope, input, previous = {}, clearSecrets = [], catalog = []) {
37
38
  const descriptor = memoryProviderDescriptor(providerId, catalog);
38
- if ((descriptor.typeId ?? descriptor.id) === "mnemon-native") return {};
39
+ if (isNativeProvider(descriptor)) return {};
39
40
  const fields = descriptor.fields.filter((item) => item.scope === scope);
40
41
  const allowed = new Set(fields.map((item) => item.key));
41
42
  for (const key of Object.keys(input ?? {})) if (!allowed.has(key)) throw new Error(`unsupported ${descriptor.label} ${scope} setting: ${key}`);
@@ -88,7 +89,7 @@ function normalizeProviderMemoryConnection(providerId, input, previous = {}, cat
88
89
  }
89
90
  function normalizeProviderConnection(providerId, input, previous = {}, clearSecrets = [], catalog = []) {
90
91
  const descriptor = memoryProviderDescriptor(providerId, catalog);
91
- if ((descriptor.typeId ?? descriptor.id) === "mnemon-native") return {};
92
+ if (isNativeProvider(descriptor)) return {};
92
93
  const allowed = new Set(descriptor.fields.map((item) => item.key));
93
94
  for (const key of Object.keys(input ?? {})) if (!allowed.has(key)) throw new Error(`unsupported ${descriptor.label} setting: ${key}`);
94
95
  for (const key of clearSecrets) if (descriptor.fields.find((item) => item.key === key)?.input !== "secret") throw new Error(`cannot clear non-secret ${descriptor.label} setting: ${key}`);
@@ -1,5 +1,5 @@
1
1
  import { CATEGORIES, Category, EDGE_TYPES, EdgeType, INTENTS, Insight, Intent, JsonValue, MemoryBody, MemoryBodyProvider, MemoryBodyStats, MemoryGraphEdge, MemoryGraphNode, MemoryGraphSnapshot, MemoryListRequest, MemoryProviderCapabilities, MemoryProviderConfigField, MemoryProviderConfigOption, MemoryProviderConnection, MemoryProviderConnectionValue, MemoryProviderDescriptor, MemoryProviderIcon, MemoryProviderId, MemorySpace, MemorySpaceProvider, MemorySpaceStats, OpenVikingBodyConnection, OpenVikingSpaceConnection, RememberRequest, SOURCES, SearchRequest, Source } from "./contracts.js";
2
- import { C as ProviderSearchResult, S as ProviderScoreSemantics, _ as MemorySpaceNativeRunner, a as MemorySpaceProviderHost, b as ProviderEntityIndex, c as MemorySpaceProviderRuntimeContext, d as defineMemorySpaceProviderDefinition, f as MemoryProviderAdapter, g as MemorySpaceNativeRunOptions, h as MemorySpaceAuthority, i as MemorySpaceProviderEntry, l as MemorySpaceProviderScoreSemantics, m as MemoryProviderScoreSemantics, n as MemorySpaceProviderDefinition, o as MemorySpaceProviderManifest, p as MemoryProviderAdapterFactoryContext, r as MemorySpaceProviderDisposer, s as MemorySpaceProviderModule, t as MEMORY_SPACE_PROVIDER_API_VERSION, u as defineMemorySpaceProvider, v as NORMALIZED_RELEVANCE_SCORE, w as ProviderSpaceStatus, x as ProviderMemorySpace, y as ProviderBodyStatus } from "./definitions-CtjNSwBS.js";
2
+ import { C as ProviderSearchResult, S as ProviderScoreSemantics, _ as MemorySpaceNativeRunner, a as MemorySpaceProviderHost, b as ProviderEntityIndex, c as MemorySpaceProviderRuntimeContext, d as defineMemorySpaceProviderDefinition, f as MemoryProviderAdapter, g as MemorySpaceNativeRunOptions, h as MemorySpaceAuthority, i as MemorySpaceProviderEntry, l as MemorySpaceProviderScoreSemantics, m as MemoryProviderScoreSemantics, n as MemorySpaceProviderDefinition, o as MemorySpaceProviderManifest, p as MemoryProviderAdapterFactoryContext, r as MemorySpaceProviderDisposer, s as MemorySpaceProviderModule, t as MEMORY_SPACE_PROVIDER_API_VERSION, u as defineMemorySpaceProvider, v as NORMALIZED_RELEVANCE_SCORE, w as ProviderSpaceStatus, x as ProviderMemorySpace, y as ProviderBodyStatus } from "./definitions-BNmfQoWk.js";
3
3
  //#region src/providers/http.d.ts
4
4
  interface HttpProviderOptions {
5
5
  label?: string;
@@ -0,0 +1,20 @@
1
+ //#region src/space-identity.d.ts
2
+ declare class MemorySpaceIdentity {
3
+ #private;
4
+ /** `parent` holds the short-lived copies a store is read from; dispose of the identity when done. */
5
+ constructor(parent: string);
6
+ /** The store's content identity, or the digest of its bytes when its content cannot be read. */
7
+ of(bytes: Uint8Array): string;
8
+ /** Whether `outer` holds every row `inner` holds; `outer` may have columns `inner` lacks. */
9
+ contains(outer: Uint8Array, inner: Uint8Array): boolean;
10
+ /**
11
+ * `local` with the rows only `incoming` holds added to it, or undefined when the two cannot
12
+ * merge: a row both hold differently, a table or column `local` lacks, or a store that cannot
13
+ * be read. `local` itself comes back when it already holds everything.
14
+ */
15
+ merge(local: Uint8Array, incoming: Uint8Array): Uint8Array | undefined;
16
+ /** Remove the short-lived copies the identity made. */
17
+ dispose(): void;
18
+ }
19
+ //#endregion
20
+ export { MemorySpaceIdentity };