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