claude-memory-layer 1.0.46 → 1.0.47

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.
@@ -2563,6 +2563,7 @@ var VectorOutbox = class {
2563
2563
  // src/core/retrieval-debug-lanes.ts
2564
2564
  var RETRIEVAL_DEBUG_LANE_NAMES = [
2565
2565
  "raw_event",
2566
+ "session_event",
2566
2567
  "session_summary",
2567
2568
  "graph_path",
2568
2569
  "facet_match"
@@ -8806,6 +8807,7 @@ var Retriever = class {
8806
8807
  }
8807
8808
  async retrieve(query, options = {}) {
8808
8809
  const opts = { ...DEFAULT_OPTIONS, ...options };
8810
+ const retrievalMode = options.retrievalMode ?? ((options.strategy ?? DEFAULT_OPTIONS.strategy) === "auto" ? "session-event-hybrid" : "event");
8809
8811
  const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;
8810
8812
  const fallbackTrace = [];
8811
8813
  const qualityQuery = buildRetrievalQualityQuery(query);
@@ -8836,6 +8838,7 @@ var Retriever = class {
8836
8838
  decayPolicy: opts.decayPolicy,
8837
8839
  intentRewrite: opts.intentRewrite === true,
8838
8840
  graphHop: opts.graphHop,
8841
+ retrievalMode,
8839
8842
  projectScopeMode: opts.projectScopeMode,
8840
8843
  projectHash: opts.projectHash,
8841
8844
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8854,6 +8857,7 @@ var Retriever = class {
8854
8857
  rerankWeights: opts.rerankWeights,
8855
8858
  decayPolicy: opts.decayPolicy,
8856
8859
  graphHop: opts.graphHop,
8860
+ retrievalMode,
8857
8861
  projectScopeMode: opts.projectScopeMode,
8858
8862
  projectHash: opts.projectHash,
8859
8863
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8873,6 +8877,7 @@ var Retriever = class {
8873
8877
  rerankWeights: opts.rerankWeights,
8874
8878
  decayPolicy: opts.decayPolicy,
8875
8879
  graphHop: opts.graphHop,
8880
+ retrievalMode,
8876
8881
  projectScopeMode: opts.projectScopeMode,
8877
8882
  projectHash: opts.projectHash,
8878
8883
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8893,10 +8898,26 @@ var Retriever = class {
8893
8898
  query,
8894
8899
  minScore: opts.minScore
8895
8900
  });
8901
+ const expandedSummary = retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(filteredSummary, {
8902
+ query: qualityQuery,
8903
+ currentStateQuery: query,
8904
+ limit: opts.topK * 4
8905
+ }) : filteredSummary;
8906
+ const scopedExpandedSummary = retrievalMode === "session-event-hybrid" ? await this.applyScopeFilters(expandedSummary, {
8907
+ scope: opts.scope,
8908
+ projectScopeMode: opts.projectScopeMode,
8909
+ projectHash: opts.projectHash,
8910
+ allowedProjectHashes: opts.allowedProjectHashes,
8911
+ facets: opts.facets
8912
+ }) : expandedSummary;
8913
+ const finalSummary = retrievalMode === "session-event-hybrid" ? this.applyQualityFilters(scopedExpandedSummary, {
8914
+ query,
8915
+ minScore: opts.minScore
8916
+ }) : scopedExpandedSummary;
8896
8917
  current = {
8897
- results: filteredSummary,
8898
- candidateResults: filteredSummary,
8899
- matchResult: this.matcher.matchSearchResults(filteredSummary, () => 0)
8918
+ results: finalSummary,
8919
+ candidateResults: finalSummary,
8920
+ matchResult: this.matcher.matchSearchResults(finalSummary, () => 0)
8900
8921
  };
8901
8922
  fallbackTrace.push("fallback:summary");
8902
8923
  }
@@ -8982,13 +9003,18 @@ var Retriever = class {
8982
9003
  initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);
8983
9004
  }
8984
9005
  }
8985
- const expandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9006
+ const graphExpandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
8986
9007
  query,
8987
9008
  queryGraphEnabled: this.queryGraphExpansionEnabled,
8988
9009
  maxHops: clampGraphHops(input.graphHop?.maxHops ?? 1),
8989
9010
  hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),
8990
9011
  limit: input.topK * 4
8991
9012
  });
9013
+ const expandedResults = input.retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(graphExpandedResults, {
9014
+ query: rerankQuery,
9015
+ currentStateQuery: query,
9016
+ limit: input.topK * 4
9017
+ }) : graphExpandedResults;
8992
9018
  const rerankedResults = input.rerankWithKeyword ? this.rerankByKeywordOverlap(expandedResults, rerankQuery, input.rerankWeights, input.decayPolicy) : expandedResults;
8993
9019
  const filtered = await this.applyScopeFilters(rerankedResults, {
8994
9020
  scope: input.scope,
@@ -9036,6 +9062,47 @@ var Retriever = class {
9036
9062
  }
9037
9063
  return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);
9038
9064
  }
9065
+ async expandSessionEventHybrid(seeds, opts) {
9066
+ if (seeds.length === 0 || opts.limit <= seeds.length) return seeds;
9067
+ const queryTokens = this.tokenize(opts.query);
9068
+ if (queryTokens.length === 0) return seeds;
9069
+ const byId = /* @__PURE__ */ new Map();
9070
+ for (const seed of seeds) byId.set(seed.eventId, seed);
9071
+ const bestSeedBySession = /* @__PURE__ */ new Map();
9072
+ for (const seed of [...seeds].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId))) {
9073
+ if (!seed.sessionId || bestSeedBySession.has(seed.sessionId)) continue;
9074
+ bestSeedBySession.set(seed.sessionId, seed);
9075
+ }
9076
+ const suppressStaleState = isCurrentStateQuery(opts.currentStateQuery);
9077
+ for (const [sessionId, seed] of bestSeedBySession) {
9078
+ const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9079
+ for (const event of [...sessionEvents].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())) {
9080
+ if (byId.has(event.id)) continue;
9081
+ if (isLowSignalContextContent(event.content)) continue;
9082
+ if (suppressStaleState && isStaleOrSupersededContent(event.content)) continue;
9083
+ const lexicalScore = this.keywordOverlap(queryTokens, this.tokenize(event.content));
9084
+ if (lexicalScore <= 0) continue;
9085
+ if (shouldApplyTechnicalGuard(opts.query) && !hasTechnicalTermOverlap(opts.query, event.content)) continue;
9086
+ const score = Math.min(0.95, Math.max(0.35, seed.score * 0.72 + lexicalScore * 0.28));
9087
+ const row = withRetrievalLane({
9088
+ id: `session-event-${seed.eventId}-${event.id}`,
9089
+ eventId: event.id,
9090
+ content: event.content,
9091
+ score,
9092
+ sessionId: event.sessionId,
9093
+ eventType: event.eventType,
9094
+ timestamp: event.timestamp.toISOString(),
9095
+ semanticScore: seed.semanticScore ?? seed.score,
9096
+ lexicalScore,
9097
+ recencyScore: seed.recencyScore
9098
+ }, { lane: "session_event", reason: `same_session:${seed.eventId}`, score });
9099
+ byId.set(row.eventId, row);
9100
+ if (byId.size >= opts.limit) break;
9101
+ }
9102
+ if (byId.size >= opts.limit) break;
9103
+ }
9104
+ return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9105
+ }
9039
9106
  async expandGraphHops(seeds, opts) {
9040
9107
  const byId = /* @__PURE__ */ new Map();
9041
9108
  for (const s of seeds) byId.set(s.eventId, s);