stratagate-dsh 0.2.67 → 0.2.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/dist/plugin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
2
  import { mkdir as mkdir2 } from "node:fs/promises";
3
- import { dirname as dirname2 } from "node:path";
3
+ import { dirname as dirname3 } from "node:path";
4
4
  import { createUserMessage as createUserMessage3 } from "@deepseek-ai/dsh-llm";
5
5
 
6
6
  // src/config.ts
@@ -5414,8 +5414,9 @@ function isOffRejection(error) {
5414
5414
  // src/runtime.ts
5415
5415
  import { createHash } from "node:crypto";
5416
5416
  import { existsSync } from "node:fs";
5417
- import { resolve } from "node:path";
5417
+ import { dirname, resolve } from "node:path";
5418
5418
  import { createUserMessage as createUserMessage2 } from "@deepseek-ai/dsh-llm";
5419
+ import { openNativePath } from "@deepseek-ai/dsh-native-command";
5419
5420
 
5420
5421
  // src/fold.ts
5421
5422
  function renderBlocks(blocks) {
@@ -5758,12 +5759,13 @@ function feedbackDraftUrl(namespace, origin) {
5758
5759
  var StrataGateRuntime = class {
5759
5760
  constructor(config, models, onIngestError = () => {
5760
5761
  }, flushNativeSession = async () => {
5761
- }, feedbackOrigin = () => void 0) {
5762
+ }, feedbackOrigin = () => void 0, openPath = openNativePath) {
5762
5763
  this.config = config;
5763
5764
  this.models = models;
5764
5765
  this.onIngestError = onIngestError;
5765
5766
  this.flushNativeSession = flushNativeSession;
5766
5767
  this.feedbackOrigin = feedbackOrigin;
5768
+ this.openPath = openPath;
5767
5769
  this.blockTurnSize = config.blockTurnSize;
5768
5770
  this.blockDecayLambda = config.blockDecayLambda;
5769
5771
  this.scheduleBackgroundWorker(BACKGROUND_WORKER_INITIAL_DELAY_MS);
@@ -5773,6 +5775,7 @@ var StrataGateRuntime = class {
5773
5775
  onIngestError;
5774
5776
  flushNativeSession;
5775
5777
  feedbackOrigin;
5778
+ openPath;
5776
5779
  folder = new TurnFolder();
5777
5780
  spaces = /* @__PURE__ */ new Map();
5778
5781
  batches = /* @__PURE__ */ new Map();
@@ -6214,6 +6217,11 @@ var StrataGateRuntime = class {
6214
6217
  retrievedMemories,
6215
6218
  incremented: eventIds.size + elementIds.size,
6216
6219
  evidenceRefs: selectedRefs,
6220
+ ...assessment === void 0 ? {} : {
6221
+ verdict: assessment.verdict,
6222
+ missing: assessment.missing,
6223
+ nextStrategy: assessment.nextStrategy
6224
+ },
6217
6225
  duplicateEvidenceRefs,
6218
6226
  eventIds: [...eventIds],
6219
6227
  elementIds: [...elementIds],
@@ -6838,6 +6846,16 @@ var StrataGateRuntime = class {
6838
6846
  await update;
6839
6847
  return value;
6840
6848
  }
6849
+ adminDataDirectory() {
6850
+ if (this.config.database === ":memory:") return null;
6851
+ return dirname(resolve(this.config.database));
6852
+ }
6853
+ async adminOpenDataDirectory(signal) {
6854
+ const path = this.adminDataDirectory();
6855
+ if (!path) throw new Error("StrataGate is using in-memory storage, so no data directory is available");
6856
+ await this.openPath(path, signal);
6857
+ return { opened: true, path };
6858
+ }
6841
6859
  async adminExpandBlock(namespace, id, target) {
6842
6860
  const key = namespace.trim();
6843
6861
  if (!key) throw new TypeError("StrataGate admin namespace must not be empty");
@@ -7895,7 +7913,81 @@ Tags: ${block.l0Tags.join(", ") || "none"}` },
7895
7913
  { level: 5, content: formatRawTranscript(block.l5Raw) }
7896
7914
  ]);
7897
7915
  }
7898
- function eventSummary(event) {
7916
+ function sampledEventWeight(event, turn, lastAdoptedTurn, mentionCount) {
7917
+ return memoryWeightAt({
7918
+ status: event.status,
7919
+ weight: { ...event.weight, lastAdoptedTurn, mentionCount }
7920
+ }, turn);
7921
+ }
7922
+ function appendWeightSegment(points, event, fromTurn, toTurn, mentionCount) {
7923
+ if (toTurn < fromTurn) return;
7924
+ if (toTurn === fromTurn) return;
7925
+ const span = toTurn - fromTurn;
7926
+ const step = Math.max(1, Math.ceil(span / 32));
7927
+ for (let turn = fromTurn; turn < toTurn; turn += step) {
7928
+ points.push({ turn, weight: sampledEventWeight(event, turn, fromTurn, mentionCount), kind: "sample" });
7929
+ }
7930
+ points.push({ turn: toTurn, weight: sampledEventWeight(event, toTurn, fromTurn, mentionCount), kind: "sample" });
7931
+ }
7932
+ function eventWeightTrajectory(snapshot, event) {
7933
+ const currentTurn = snapshot.currentTurn;
7934
+ const effectiveAdoptions = Math.max(0, event.weight.mentionCount - 1);
7935
+ const adoptionReceipts = snapshot.usageReceipts.filter(({ eventIds }) => eventIds.includes(event.id));
7936
+ const adoptionTurns = adoptionReceipts.map(({ audit: audit2 }) => audit2?.turn).filter((turn) => Number.isSafeInteger(turn) && turn >= 0).sort((left, right) => left - right);
7937
+ const historyComplete = adoptionReceipts.length === effectiveAdoptions && adoptionTurns.length === adoptionReceipts.length && (effectiveAdoptions === 0 || adoptionTurns.at(-1) === event.weight.lastAdoptedTurn);
7938
+ const canInterpolate = event.status !== "forgotten" && event.status !== "archived" && event.weight.forcedCap === null && !event.weight.pinned;
7939
+ const points = [];
7940
+ if (canInterpolate && effectiveAdoptions === 0) {
7941
+ appendWeightSegment(points, event, event.weight.lastAdoptedTurn, currentTurn, 1);
7942
+ if (points.length > 0) {
7943
+ const first = points[0];
7944
+ points[0] = { turn: first.turn, weight: first.weight, kind: "creation", label: "\u521B\u5EFA" };
7945
+ }
7946
+ } else if (canInterpolate && historyComplete && adoptionTurns.length > 0) {
7947
+ let anchorTurn = adoptionTurns[0];
7948
+ let mentionCount = 2;
7949
+ points.push({ turn: anchorTurn, weight: 1, kind: "adoption", label: "\u91C7\u7528" });
7950
+ for (const [index, turn] of adoptionTurns.slice(1).entries()) {
7951
+ appendWeightSegment(points, event, anchorTurn, turn, mentionCount);
7952
+ points.push({ turn, weight: 1, kind: "adoption", label: index === adoptionTurns.length - 2 ? "\u518D\u6B21\u91C7\u7528" : "\u91C7\u7528" });
7953
+ anchorTurn = turn;
7954
+ mentionCount += 1;
7955
+ }
7956
+ appendWeightSegment(points, event, anchorTurn, currentTurn, mentionCount);
7957
+ } else if (canInterpolate) {
7958
+ appendWeightSegment(points, event, event.weight.lastAdoptedTurn, currentTurn, event.weight.mentionCount);
7959
+ if (effectiveAdoptions > 0 && points.length > 0) {
7960
+ const first = points[0];
7961
+ points[0] = { turn: first.turn, weight: first.weight, kind: "adoption", label: "\u6700\u8FD1\u91C7\u7528" };
7962
+ }
7963
+ }
7964
+ const currentWeight = memoryWeightAt(event, currentTurn);
7965
+ if (points.length === 0 || points.at(-1)?.turn !== currentTurn) {
7966
+ points.push({ turn: currentTurn, weight: currentWeight, kind: "current", label: "\u5F53\u524D" });
7967
+ } else if (points.at(-1)?.kind === "creation" || points.at(-1)?.kind === "adoption") {
7968
+ points[points.length - 1] = {
7969
+ ...points[points.length - 1],
7970
+ weight: currentWeight,
7971
+ label: `${points[points.length - 1].label} \xB7 \u5F53\u524D`
7972
+ };
7973
+ } else {
7974
+ points[points.length - 1] = { ...points[points.length - 1], weight: currentWeight, kind: "current", label: "\u5F53\u524D" };
7975
+ }
7976
+ return {
7977
+ scale: "conversation_turn",
7978
+ currentTurn,
7979
+ currentWeight,
7980
+ effectiveAdoptions,
7981
+ latestAdoptionTurn: effectiveAdoptions > 0 ? event.weight.lastAdoptedTurn : null,
7982
+ turnsSinceLatestAdoption: effectiveAdoptions > 0 ? Math.max(0, currentTurn - event.weight.lastAdoptedTurn) : null,
7983
+ lastRetrievedAt: event.weight.lastRetrievedAt,
7984
+ recordedAdoptionTurns: adoptionTurns,
7985
+ historyComplete,
7986
+ points,
7987
+ note: !canInterpolate ? "\u56FA\u5B9A\u3001\u5C01\u5B58\u6216\u72B6\u6001\u4E0A\u9650\u7684\u53D8\u66F4\u8F6E\u6B21\u6CA1\u6709\u5386\u53F2\u8BB0\u5F55\uFF0C\u56E0\u6B64\u4EC5\u663E\u793A\u5F53\u524D\u771F\u5B9E\u6743\u91CD\u3002" : effectiveAdoptions > 0 && !historyComplete ? "\u90E8\u5206\u65E9\u671F\u91C7\u7528\u8BB0\u5F55\u7F3A\u5C11\u8F6E\u6B21\uFF1B\u66F2\u7EBF\u4EC5\u4ECE\u6700\u8FD1\u4E00\u6B21\u53EF\u786E\u8BA4\u7684\u5F3A\u5316\u5F00\u59CB\u3002" : effectiveAdoptions > 0 ? "\u91C7\u7528\u8F6E\u6B21\u6765\u81EA\u4F7F\u7528\u56DE\u6267\uFF1B\u521B\u5EFA\u8F6E\u6B21\u672A\u5355\u72EC\u4FDD\u5B58\uFF0C\u56E0\u6B64\u4E0D\u63A8\u6D4B\u521B\u5EFA\u8282\u70B9\u3002" : "\u5C1A\u672A\u53D1\u751F\u6709\u6548\u91C7\u7528\uFF1B\u521B\u5EFA\u951A\u70B9\u6765\u81EA Event \u5F53\u524D\u6743\u91CD\u72B6\u6001\u3002"
7988
+ };
7989
+ }
7990
+ function eventSummary(event, snapshot) {
7899
7991
  return {
7900
7992
  id: event.id,
7901
7993
  title: event.title,
@@ -7911,6 +8003,7 @@ function eventSummary(event) {
7911
8003
  status: event.status,
7912
8004
  supersededBy: event.supersededBy,
7913
8005
  weight: event.weight,
8006
+ ...snapshot ? { weightTrajectory: eventWeightTrajectory(snapshot, event) } : {},
7914
8007
  createdAt: event.createdAt,
7915
8008
  updatedAt: event.updatedAt
7916
8009
  };
@@ -8071,6 +8164,7 @@ async function overview(runtime, cachedEntries) {
8071
8164
  return {
8072
8165
  readonly: true,
8073
8166
  settingsWritable: true,
8167
+ dataDirectory: runtime.adminDataDirectory?.() ?? null,
8074
8168
  pluginVersion: STRATAGATE_DSH_VERSION,
8075
8169
  harnessVersion: installedPackageVersion(["@deepseek-ai/dsh", "@deepseek-ai/dsh-session"]),
8076
8170
  namespaces: rows
@@ -8359,7 +8453,7 @@ async function memories(runtime, url) {
8359
8453
  const time = (event) => event.temporal.happenedStart ?? event.temporal.happenedEnd ?? event.temporal.mentionedAt ?? event.createdAt;
8360
8454
  return time(right).localeCompare(time(left));
8361
8455
  }).map((event) => ({
8362
- ...eventSummary(event),
8456
+ ...eventSummary(event, snapshot),
8363
8457
  relatedNodes: snapshot.graphNodes.filter(({ id, sourceEventIds }) => sourceEventIds.includes(event.id) || (event.temporal.participantNodeIds ?? []).includes(id)).map(({ id, name: name2, type }) => ({ id, name: name2, type })),
8364
8458
  relatedElements: snapshot.elements.filter(({ sourceEventIds }) => sourceEventIds.includes(event.id)).map(({ id, name: name2 }) => ({ id, name: name2 }))
8365
8459
  }));
@@ -8371,7 +8465,7 @@ async function memories(runtime, url) {
8371
8465
  projectorVersion: KNOWLEDGE_GRAPH_PROJECTOR_VERSION,
8372
8466
  nodes: snapshot.graphNodes.map((node) => ({
8373
8467
  ...node,
8374
- supportingEvents: node.sourceEventIds.flatMap((id) => eventMap.get(id) ?? []).map(eventSummary)
8468
+ supportingEvents: node.sourceEventIds.flatMap((id) => eventMap.get(id) ?? []).map((event) => eventSummary(event))
8375
8469
  })),
8376
8470
  edges: snapshot.graphEdges,
8377
8471
  clusters: clusterKnowledgeGraph(snapshot.graphNodes, snapshot.graphEdges),
@@ -8460,7 +8554,7 @@ async function memories(runtime, url) {
8460
8554
  jobs: projections.length,
8461
8555
  lastError: failedProjection?.lastError ?? null
8462
8556
  } : null,
8463
- relatedEvents: relatedEvents.map(eventSummary),
8557
+ relatedEvents: relatedEvents.map((event) => eventSummary(event)),
8464
8558
  relatedNodes
8465
8559
  };
8466
8560
  });
@@ -8519,7 +8613,7 @@ async function sources(runtime, url) {
8519
8613
  node,
8520
8614
  nodes: snapshot.graphNodes.filter(({ id }) => relatedNodeIds.has(id)),
8521
8615
  edges,
8522
- events: events.map(eventSummary),
8616
+ events: events.map((event) => eventSummary(event)),
8523
8617
  messages: sourceMessages(snapshot, ids)
8524
8618
  };
8525
8619
  } else if (elementId) {
@@ -8539,7 +8633,7 @@ async function sources(runtime, url) {
8539
8633
  elements = snapshot.elements.filter(({ sourceEventIds }) => sourceEventIds.some((id) => eventIds.has(id)));
8540
8634
  return {
8541
8635
  namespace,
8542
- events: events.map(eventSummary),
8636
+ events: events.map((event) => eventSummary(event)),
8543
8637
  elements: elements.map(elementSummary),
8544
8638
  messages: sourceMessages(snapshot, ids),
8545
8639
  layers: displayBlock ? virtualBlockLayers(displayBlock) : blockLayers(block),
@@ -8550,7 +8644,7 @@ async function sources(runtime, url) {
8550
8644
  }
8551
8645
  return {
8552
8646
  namespace,
8553
- events: events.map(eventSummary),
8647
+ events: events.map((event) => eventSummary(event, eventId ? snapshot : void 0)),
8554
8648
  elements: elements.map(elementSummary),
8555
8649
  blocks: events.map((event) => snapshot.blocks.find(({ id }) => id === event.sourceBlockId)).filter((block) => Boolean(block)).map((block) => ({ id: block.id, title: block.l0Title, createdAt: block.createdAt })),
8556
8650
  messages: sourceMessages(snapshot, ids)
@@ -8610,7 +8704,7 @@ function receiptSources(snapshot, receipt) {
8610
8704
  const messageIds = new Set(supportingEvents.flatMap(({ sourceMessageIds }) => sourceMessageIds));
8611
8705
  return {
8612
8706
  ...receipt,
8613
- events: events.map(eventSummary),
8707
+ events: events.map((event) => eventSummary(event)),
8614
8708
  elements: elements.map(elementSummary),
8615
8709
  sourceMessages: sourceMessages(snapshot, messageIds)
8616
8710
  };
@@ -8711,6 +8805,9 @@ async function handleAdminRequest(runtime, req, res) {
8711
8805
  } else if (path === "/api/stratagate/settings") {
8712
8806
  if (req.method !== "PATCH") throw new AdminHttpError(405, "StrataGate settings require PATCH");
8713
8807
  sendJson(res, 200, await updateSettings(runtime, url));
8808
+ } else if (path === "/api/stratagate/storage/open-directory") {
8809
+ if (req.method !== "POST") throw new AdminHttpError(405, "StrataGate data directory open requires POST");
8810
+ sendJson(res, 200, await runtime.adminOpenDataDirectory(AbortSignal.timeout(15e3)));
8714
8811
  } else if (path === "/api/stratagate/blocks/expand") {
8715
8812
  if (req.method !== "PATCH") throw new AdminHttpError(405, "StrataGate Block expansion requires PATCH");
8716
8813
  sendJson(res, 200, await expandBlock(runtime, url));
@@ -8770,7 +8867,7 @@ import {
8770
8867
  unlink,
8771
8868
  writeFile
8772
8869
  } from "node:fs/promises";
8773
- import { basename, dirname, join } from "node:path";
8870
+ import { basename, dirname as dirname2, join } from "node:path";
8774
8871
  import { createHash as createHash3, randomUUID } from "node:crypto";
8775
8872
  import { encodeSeqRanges } from "@deepseek-ai/dsh-session";
8776
8873
  var LEGACY_EVENT_TYPE = "stratagate/memory-citations";
@@ -8982,8 +9079,8 @@ async function exists(path) {
8982
9079
  }
8983
9080
  }
8984
9081
  async function publishExclusive(path, bytes) {
8985
- await mkdir(dirname(path), { recursive: true });
8986
- const temporary = join(dirname(path), `.${basename(path)}.stratagate-${randomUUID()}.tmp`);
9082
+ await mkdir(dirname2(path), { recursive: true });
9083
+ const temporary = join(dirname2(path), `.${basename(path)}.stratagate-${randomUUID()}.tmp`);
8987
9084
  const handle = await open(temporary, "wx", 384);
8988
9085
  try {
8989
9086
  await handle.writeFile(bytes);
@@ -9109,7 +9206,7 @@ async function apply(ctx, config) {
9109
9206
  if (legacyMigration.migrated > 0) {
9110
9207
  ctx.logger.info(`stratagate-memory prepared ${legacyMigration.migrated} legacy Session generation(s) for DSH 0.1.5`);
9111
9208
  }
9112
- await mkdir2(dirname2(resolved.database), { recursive: true });
9209
+ await mkdir2(dirname3(resolved.database), { recursive: true });
9113
9210
  const models = new DshModelBridge(ctx, resolved);
9114
9211
  const runtime = new StrataGateRuntime(resolved, models, (error) => {
9115
9212
  ctx.logger.error(`stratagate-memory ingestion failed: ${renderError(error)}`);