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.
@@ -2584,6 +2584,7 @@ var VectorOutbox = class {
2584
2584
  // src/core/retrieval-debug-lanes.ts
2585
2585
  var RETRIEVAL_DEBUG_LANE_NAMES = [
2586
2586
  "raw_event",
2587
+ "session_event",
2587
2588
  "session_summary",
2588
2589
  "graph_path",
2589
2590
  "facet_match"
@@ -8844,6 +8845,7 @@ var Retriever = class {
8844
8845
  }
8845
8846
  async retrieve(query, options = {}) {
8846
8847
  const opts = { ...DEFAULT_OPTIONS, ...options };
8848
+ const retrievalMode = options.retrievalMode ?? ((options.strategy ?? DEFAULT_OPTIONS.strategy) === "auto" ? "session-event-hybrid" : "event");
8847
8849
  const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;
8848
8850
  const fallbackTrace = [];
8849
8851
  const qualityQuery = buildRetrievalQualityQuery(query);
@@ -8874,6 +8876,7 @@ var Retriever = class {
8874
8876
  decayPolicy: opts.decayPolicy,
8875
8877
  intentRewrite: opts.intentRewrite === true,
8876
8878
  graphHop: opts.graphHop,
8879
+ retrievalMode,
8877
8880
  projectScopeMode: opts.projectScopeMode,
8878
8881
  projectHash: opts.projectHash,
8879
8882
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8892,6 +8895,7 @@ var Retriever = class {
8892
8895
  rerankWeights: opts.rerankWeights,
8893
8896
  decayPolicy: opts.decayPolicy,
8894
8897
  graphHop: opts.graphHop,
8898
+ retrievalMode,
8895
8899
  projectScopeMode: opts.projectScopeMode,
8896
8900
  projectHash: opts.projectHash,
8897
8901
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8911,6 +8915,7 @@ var Retriever = class {
8911
8915
  rerankWeights: opts.rerankWeights,
8912
8916
  decayPolicy: opts.decayPolicy,
8913
8917
  graphHop: opts.graphHop,
8918
+ retrievalMode,
8914
8919
  projectScopeMode: opts.projectScopeMode,
8915
8920
  projectHash: opts.projectHash,
8916
8921
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8931,10 +8936,26 @@ var Retriever = class {
8931
8936
  query,
8932
8937
  minScore: opts.minScore
8933
8938
  });
8939
+ const expandedSummary = retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(filteredSummary, {
8940
+ query: qualityQuery,
8941
+ currentStateQuery: query,
8942
+ limit: opts.topK * 4
8943
+ }) : filteredSummary;
8944
+ const scopedExpandedSummary = retrievalMode === "session-event-hybrid" ? await this.applyScopeFilters(expandedSummary, {
8945
+ scope: opts.scope,
8946
+ projectScopeMode: opts.projectScopeMode,
8947
+ projectHash: opts.projectHash,
8948
+ allowedProjectHashes: opts.allowedProjectHashes,
8949
+ facets: opts.facets
8950
+ }) : expandedSummary;
8951
+ const finalSummary = retrievalMode === "session-event-hybrid" ? this.applyQualityFilters(scopedExpandedSummary, {
8952
+ query,
8953
+ minScore: opts.minScore
8954
+ }) : scopedExpandedSummary;
8934
8955
  current = {
8935
- results: filteredSummary,
8936
- candidateResults: filteredSummary,
8937
- matchResult: this.matcher.matchSearchResults(filteredSummary, () => 0)
8956
+ results: finalSummary,
8957
+ candidateResults: finalSummary,
8958
+ matchResult: this.matcher.matchSearchResults(finalSummary, () => 0)
8938
8959
  };
8939
8960
  fallbackTrace.push("fallback:summary");
8940
8961
  }
@@ -9020,13 +9041,18 @@ var Retriever = class {
9020
9041
  initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);
9021
9042
  }
9022
9043
  }
9023
- const expandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9044
+ const graphExpandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9024
9045
  query,
9025
9046
  queryGraphEnabled: this.queryGraphExpansionEnabled,
9026
9047
  maxHops: clampGraphHops(input.graphHop?.maxHops ?? 1),
9027
9048
  hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),
9028
9049
  limit: input.topK * 4
9029
9050
  });
9051
+ const expandedResults = input.retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(graphExpandedResults, {
9052
+ query: rerankQuery,
9053
+ currentStateQuery: query,
9054
+ limit: input.topK * 4
9055
+ }) : graphExpandedResults;
9030
9056
  const rerankedResults = input.rerankWithKeyword ? this.rerankByKeywordOverlap(expandedResults, rerankQuery, input.rerankWeights, input.decayPolicy) : expandedResults;
9031
9057
  const filtered = await this.applyScopeFilters(rerankedResults, {
9032
9058
  scope: input.scope,
@@ -9074,6 +9100,47 @@ var Retriever = class {
9074
9100
  }
9075
9101
  return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);
9076
9102
  }
9103
+ async expandSessionEventHybrid(seeds, opts) {
9104
+ if (seeds.length === 0 || opts.limit <= seeds.length) return seeds;
9105
+ const queryTokens = this.tokenize(opts.query);
9106
+ if (queryTokens.length === 0) return seeds;
9107
+ const byId = /* @__PURE__ */ new Map();
9108
+ for (const seed of seeds) byId.set(seed.eventId, seed);
9109
+ const bestSeedBySession = /* @__PURE__ */ new Map();
9110
+ for (const seed of [...seeds].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId))) {
9111
+ if (!seed.sessionId || bestSeedBySession.has(seed.sessionId)) continue;
9112
+ bestSeedBySession.set(seed.sessionId, seed);
9113
+ }
9114
+ const suppressStaleState = isCurrentStateQuery(opts.currentStateQuery);
9115
+ for (const [sessionId, seed] of bestSeedBySession) {
9116
+ const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9117
+ for (const event of [...sessionEvents].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())) {
9118
+ if (byId.has(event.id)) continue;
9119
+ if (isLowSignalContextContent(event.content)) continue;
9120
+ if (suppressStaleState && isStaleOrSupersededContent(event.content)) continue;
9121
+ const lexicalScore = this.keywordOverlap(queryTokens, this.tokenize(event.content));
9122
+ if (lexicalScore <= 0) continue;
9123
+ if (shouldApplyTechnicalGuard(opts.query) && !hasTechnicalTermOverlap(opts.query, event.content)) continue;
9124
+ const score = Math.min(0.95, Math.max(0.35, seed.score * 0.72 + lexicalScore * 0.28));
9125
+ const row = withRetrievalLane({
9126
+ id: `session-event-${seed.eventId}-${event.id}`,
9127
+ eventId: event.id,
9128
+ content: event.content,
9129
+ score,
9130
+ sessionId: event.sessionId,
9131
+ eventType: event.eventType,
9132
+ timestamp: event.timestamp.toISOString(),
9133
+ semanticScore: seed.semanticScore ?? seed.score,
9134
+ lexicalScore,
9135
+ recencyScore: seed.recencyScore
9136
+ }, { lane: "session_event", reason: `same_session:${seed.eventId}`, score });
9137
+ byId.set(row.eventId, row);
9138
+ if (byId.size >= opts.limit) break;
9139
+ }
9140
+ if (byId.size >= opts.limit) break;
9141
+ }
9142
+ return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9143
+ }
9077
9144
  async expandGraphHops(seeds, opts) {
9078
9145
  const byId = /* @__PURE__ */ new Map();
9079
9146
  for (const s of seeds) byId.set(s.eventId, s);