stratagate-dsh 0.2.46 → 0.2.48

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/index.js CHANGED
@@ -5735,6 +5735,7 @@ var StrataGateRuntime = class {
5735
5735
  batchStatus: batch.status,
5736
5736
  recorded: true,
5737
5737
  namespace,
5738
+ retrievalSequence: batch.sequence,
5738
5739
  retrievedCount: batch.refs.size,
5739
5740
  retrievedMemories,
5740
5741
  incremented: eventIds.size + elementIds.size,
@@ -6484,7 +6485,8 @@ var StrataGateRuntime = class {
6484
6485
  if (responses.length > 0) await memory.recordSuccessfulModelResponses(responses);
6485
6486
  }
6486
6487
  batch(session, evidence, results, metadata = {}) {
6487
- const id = `batch_${++this.batchSequence}`;
6488
+ const sequence = ++this.batchSequence;
6489
+ const id = `batch_${sequence}`;
6488
6490
  const refs = new Map(evidence.map(({ ref, target }) => [ref, target]));
6489
6491
  const key = String(session.id);
6490
6492
  let sessionBatches = this.batches.get(key);
@@ -6492,7 +6494,7 @@ var StrataGateRuntime = class {
6492
6494
  sessionBatches = /* @__PURE__ */ new Map();
6493
6495
  this.batches.set(key, sessionBatches);
6494
6496
  }
6495
- sessionBatches.set(id, { id, refs, status: "unresolved" });
6497
+ sessionBatches.set(id, { id, sequence, refs, status: "unresolved" });
6496
6498
  this.latestBatchIds.set(key, id);
6497
6499
  return { batchId: id, evidenceRefs: [...refs.keys()], results, ...metadata };
6498
6500
  }
@@ -7097,7 +7099,7 @@ function clusterKnowledgeGraph(rawNodes, rawEdges) {
7097
7099
  }
7098
7100
 
7099
7101
  // src/web.ts
7100
- var STRATAGATE_DSH_VERSION = "0.2.36";
7102
+ var STRATAGATE_DSH_VERSION = "0.2.48";
7101
7103
  var LEGACY_THREAD_ID = "__legacy__";
7102
7104
  var nodeRequire = createRequire(import.meta.url);
7103
7105
  function installedPackageVersion(names) {
@@ -7152,23 +7154,32 @@ function sourceMessages(snapshot, ids) {
7152
7154
  }
7153
7155
  return output;
7154
7156
  }
7157
+ function withLayerMetrics(layers) {
7158
+ const tokenCounts = new Map(layers.map(({ level, content }) => [level, estimateTokens(content)]));
7159
+ const l5Tokens = tokenCounts.get(5) ?? 0;
7160
+ return layers.map((layer) => {
7161
+ const tokens = tokenCounts.get(layer.level) ?? 0;
7162
+ const percentOfL5 = layer.level === 5 ? 100 : l5Tokens > 0 ? Math.round(tokens / l5Tokens * 100) : 0;
7163
+ return { ...layer, tokens, percentOfL5 };
7164
+ });
7165
+ }
7155
7166
  function blockLayers(block) {
7156
7167
  if (block.processingStatus !== "ready" || !block.l0Title || !block.l0Tags || !block.l1Summary || !block.l2Keypoints) {
7157
- return [
7168
+ return withLayerMetrics([
7158
7169
  { level: 3, content: block.l3Condensed },
7159
7170
  { level: 4, content: block.l4Readable },
7160
7171
  { level: 5, content: block.l5Raw.map((message) => `${message.role}: ${message.content}`).join("\n\n") }
7161
- ];
7172
+ ]);
7162
7173
  }
7163
- return [
7174
+ return withLayerMetrics([
7164
7175
  { level: 0, content: `${block.l0Title}
7165
- \u6807\u7B7E\uFF1A${block.l0Tags.join("\u3001") || "\u65E0"}` },
7176
+ Tags: ${block.l0Tags.join(", ") || "none"}` },
7166
7177
  { level: 1, content: block.l1Summary || block.l0Title },
7167
- { level: 2, content: block.l2Keypoints.map((point) => `\u2022 ${point}`).join("\n") || block.l1Summary || block.l0Title },
7178
+ { level: 2, content: block.l2Keypoints.map((point) => `- ${point}`).join("\n") || block.l1Summary || block.l0Title },
7168
7179
  { level: 3, content: block.l3Condensed || block.l2Keypoints.join("\n") || block.l1Summary },
7169
7180
  { level: 4, content: block.l4Readable || block.l3Condensed },
7170
7181
  { level: 5, content: block.l5Raw.map((message) => `${message.role}: ${message.content}`).join("\n\n") }
7171
- ];
7182
+ ]);
7172
7183
  }
7173
7184
  function eventSummary(event) {
7174
7185
  return {
@@ -7391,6 +7402,15 @@ function receiptThreadId(id) {
7391
7402
  const match = /^dsh:(.+):turn:\d+$/.exec(id);
7392
7403
  return match?.[1]?.trim() || null;
7393
7404
  }
7405
+ function receiptTurnNumber(id) {
7406
+ const match = /^dsh:(.+):turn:(\d+)$/.exec(id);
7407
+ if (!match) return null;
7408
+ const turn = Number(match[2]);
7409
+ return Number.isSafeInteger(turn) ? turn : null;
7410
+ }
7411
+ function receiptTurnKey(threadId, createdAt) {
7412
+ return `${threadId}\0${timestampKey(createdAt)}`;
7413
+ }
7394
7414
  function timestampKey(value) {
7395
7415
  const parsed = Date.parse(value);
7396
7416
  return Number.isFinite(parsed) ? String(parsed) : value;
@@ -7398,11 +7418,14 @@ function timestampKey(value) {
7398
7418
  function recoverSnapshotView(snapshot) {
7399
7419
  const receiptThreads = /* @__PURE__ */ new Map();
7400
7420
  const receiptActivity = /* @__PURE__ */ new Map();
7421
+ const receiptTurns = /* @__PURE__ */ new Map();
7401
7422
  const receiptCandidates = /* @__PURE__ */ new Map();
7402
7423
  for (const receipt of snapshot.ingestionReceipts) {
7403
7424
  const threadId = receiptThreadId(receipt.id);
7404
7425
  if (!threadId) continue;
7405
7426
  receiptThreads.set(receipt.id, threadId);
7427
+ const turn = receiptTurnNumber(receipt.id);
7428
+ if (turn !== null) receiptTurns.set(receiptTurnKey(threadId, receipt.createdAt), turn);
7406
7429
  const currentActivity = receiptActivity.get(threadId);
7407
7430
  if (!currentActivity || receipt.createdAt > currentActivity) receiptActivity.set(threadId, receipt.createdAt);
7408
7431
  const key = timestampKey(receipt.createdAt);
@@ -7447,8 +7470,10 @@ function recoverSnapshotView(snapshot) {
7447
7470
  const turnCounters = /* @__PURE__ */ new Map();
7448
7471
  for (const block of blocks) {
7449
7472
  if (block.source.threadId) {
7450
- block.turnRange = [block.source.startTurn, block.source.endTurn];
7451
- turnCounters.set(block.threadId, Math.max(turnCounters.get(block.threadId) ?? 0, block.source.endTurn));
7473
+ const turnMessages = block.messages.filter(({ role }) => role === "user");
7474
+ const dshTurns = turnMessages.map((message) => receiptTurns.get(receiptTurnKey(block.threadId, message.createdAt)));
7475
+ block.turnRange = dshTurns.length > 0 && dshTurns.every((turn) => turn !== void 0) ? [Math.min(...dshTurns), Math.max(...dshTurns)] : [block.source.startTurn, block.source.endTurn];
7476
+ turnCounters.set(block.threadId, Math.max(turnCounters.get(block.threadId) ?? 0, block.turnRange[1]));
7452
7477
  continue;
7453
7478
  }
7454
7479
  const turns = Math.max(1, block.messages.filter(({ role }) => role === "user").length);
@@ -7460,7 +7485,8 @@ function recoverSnapshotView(snapshot) {
7460
7485
  blocks,
7461
7486
  openMessages: recoverMessages(snapshot.openTail),
7462
7487
  receiptThreads,
7463
- receiptActivity
7488
+ receiptActivity,
7489
+ receiptTurns
7464
7490
  };
7465
7491
  }
7466
7492
  function virtualBlockLayers(block) {
@@ -7471,14 +7497,14 @@ function virtualBlockLayers(block) {
7471
7497
  const title = firstUser?.content.replace(/\s+/g, " ").trim().slice(0, 80) || "\u65E7\u4F1A\u8BDD\u7247\u6BB5";
7472
7498
  const summary = natural.map(({ content }) => content.replace(/\s+/g, " ").trim()).filter(Boolean).join(" ").slice(0, 500);
7473
7499
  const keypoints = natural.filter(({ role }) => role === "user").map(({ content }) => content.replace(/\s+/g, " ").trim().slice(0, 160));
7474
- return [
7500
+ return withLayerMetrics([
7475
7501
  { level: 0, content: title },
7476
7502
  { level: 1, content: summary || title },
7477
7503
  { level: 2, content: keypoints.map((point) => `\u2022 ${point}`).join("\n") || summary || title },
7478
7504
  { level: 3, content: deterministic.l3Condensed },
7479
7505
  { level: 4, content: deterministic.l4Readable },
7480
7506
  { level: 5, content: block.messages.map((message) => `${message.role}: ${message.content}`).join("\n\n") }
7481
- ];
7507
+ ]);
7482
7508
  }
7483
7509
  function conversationRows(snapshot, view = recoverSnapshotView(snapshot)) {
7484
7510
  const ids = /* @__PURE__ */ new Set([
@@ -7557,7 +7583,10 @@ async function memories(runtime, url) {
7557
7583
  const scopedBlocks = activeThreadId ? recovered.blocks.filter((block) => block.threadId === activeThreadId) : [];
7558
7584
  values = scopedBlocks.map((block) => {
7559
7585
  const source = block.source;
7586
+ const layers = virtualBlockLayers(block);
7587
+ const layerTokens = layers.map(({ level, tokens, percentOfL5 }) => ({ level, tokens, percentOfL5 }));
7560
7588
  const extraction = snapshot.extractionJobs.find(({ blockId }) => blockId === source.id);
7589
+ const summary = snapshot.summaryJobs.find(({ blockId }) => blockId === source.id);
7561
7590
  const blockMessageIds = new Set(block.messages.map(({ id }) => id));
7562
7591
  const relatedEvents = snapshot.events.filter((event) => event.sourceBlockId === source.id && (!block.virtual || event.sourceMessageIds.some((id) => blockMessageIds.has(id))));
7563
7592
  const eventIds = new Set(relatedEvents.map(({ id }) => id));
@@ -7575,23 +7604,37 @@ async function memories(runtime, url) {
7575
7604
  latestBlockPosition,
7576
7605
  snapshot.blockDecayLambda
7577
7606
  );
7607
+ const currentMetrics = layerTokens.find(({ level }) => level === currentLevel);
7608
+ const l5Tokens = layerTokens.find(({ level }) => level === 5)?.tokens ?? 0;
7578
7609
  return {
7579
7610
  id: block.id,
7580
7611
  sourceBlockId: source.id,
7581
7612
  threadId: block.threadId,
7582
7613
  sequence: source.sequence,
7614
+ blockIndex: blockPosition,
7583
7615
  turnRange: block.turnRange,
7584
7616
  title: block.virtual && block.messages.length !== source.l5Raw.length ? block.messages.find(({ role }) => role === "user")?.content.replace(/\s+/g, " ").trim().slice(0, 80) || "\u65E7\u4F1A\u8BDD\u7247\u6BB5" : source.l0Title,
7585
7617
  tags: source.l0Tags,
7586
7618
  summary: source.l1Summary,
7587
7619
  keypoints: source.l2Keypoints,
7588
7620
  currentLevel,
7621
+ currentTokens: currentMetrics?.tokens ?? 0,
7622
+ l5Tokens,
7623
+ compressionPercent: currentMetrics?.percentOfL5 ?? (currentLevel === 5 ? 100 : 0),
7624
+ layerTokens,
7589
7625
  distanceFromLatest: Math.max(0, latestBlockPosition - blockPosition),
7590
7626
  expansionSource: source.lastLiftedAt ? source.lastLiftedBy ?? "legacy" : null,
7591
7627
  lastLiftedAt: source.lastLiftedAt,
7592
7628
  sourceMessages: block.messages.length,
7593
7629
  createdAt: source.createdAt,
7594
7630
  virtual: block.virtual,
7631
+ processingStatus: source.processingStatus,
7632
+ summaryJob: summary ? {
7633
+ status: summary.status,
7634
+ attempts: summary.attempts,
7635
+ nextRetryAt: summary.nextRetryAt,
7636
+ updatedAt: summary.updatedAt
7637
+ } : null,
7595
7638
  status,
7596
7639
  eventExtraction: extraction ? {
7597
7640
  status: extraction.status,
@@ -7612,6 +7655,7 @@ async function memories(runtime, url) {
7612
7655
  const latestSealedTurn = scopedBlocks.reduce((latest, block) => Math.max(latest, block.turnRange[1]), 0);
7613
7656
  const openMessages = activeThreadId ? recovered.openMessages.filter((message) => message.threadId === activeThreadId).map(({ message }) => message) : [];
7614
7657
  const openTurns = openMessages.filter(({ role }) => role === "user").length;
7658
+ const openDshTurns = activeThreadId ? openMessages.filter(({ role }) => role === "user").map((message) => recovered.receiptTurns.get(receiptTurnKey(activeThreadId, message.createdAt))) : [];
7615
7659
  return {
7616
7660
  namespace,
7617
7661
  kind,
@@ -7620,10 +7664,13 @@ async function memories(runtime, url) {
7620
7664
  limit,
7621
7665
  items: filtered2.slice(offset, offset + limit),
7622
7666
  openBlock: {
7623
- turnRange: openTurns > 0 ? [latestSealedTurn + 1, latestSealedTurn + openTurns] : null,
7667
+ turnRange: openTurns > 0 ? openDshTurns.length > 0 && openDshTurns.every((turn) => turn !== void 0) ? [Math.min(...openDshTurns), Math.max(...openDshTurns)] : [latestSealedTurn + 1, latestSealedTurn + openTurns] : null,
7624
7668
  messages: openMessages.length,
7669
+ turns: openTurns,
7670
+ capacity: snapshot.blockTurnSize,
7625
7671
  status: "open"
7626
7672
  },
7673
+ blockTurnSize: snapshot.blockTurnSize,
7627
7674
  conversations,
7628
7675
  activeThreadId
7629
7676
  };