claude-memory-layer 1.0.46 → 1.0.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.
@@ -2569,6 +2569,7 @@ var VectorOutbox = class {
2569
2569
  // src/core/retrieval-debug-lanes.ts
2570
2570
  var RETRIEVAL_DEBUG_LANE_NAMES = [
2571
2571
  "raw_event",
2572
+ "session_event",
2572
2573
  "session_summary",
2573
2574
  "graph_path",
2574
2575
  "facet_match"
@@ -8812,6 +8813,7 @@ var Retriever = class {
8812
8813
  }
8813
8814
  async retrieve(query, options = {}) {
8814
8815
  const opts = { ...DEFAULT_OPTIONS, ...options };
8816
+ const retrievalMode = options.retrievalMode ?? ((options.strategy ?? DEFAULT_OPTIONS.strategy) === "auto" ? "session-event-hybrid" : "event");
8815
8817
  const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;
8816
8818
  const fallbackTrace = [];
8817
8819
  const qualityQuery = buildRetrievalQualityQuery(query);
@@ -8842,6 +8844,7 @@ var Retriever = class {
8842
8844
  decayPolicy: opts.decayPolicy,
8843
8845
  intentRewrite: opts.intentRewrite === true,
8844
8846
  graphHop: opts.graphHop,
8847
+ retrievalMode,
8845
8848
  projectScopeMode: opts.projectScopeMode,
8846
8849
  projectHash: opts.projectHash,
8847
8850
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8860,6 +8863,7 @@ var Retriever = class {
8860
8863
  rerankWeights: opts.rerankWeights,
8861
8864
  decayPolicy: opts.decayPolicy,
8862
8865
  graphHop: opts.graphHop,
8866
+ retrievalMode,
8863
8867
  projectScopeMode: opts.projectScopeMode,
8864
8868
  projectHash: opts.projectHash,
8865
8869
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8879,6 +8883,7 @@ var Retriever = class {
8879
8883
  rerankWeights: opts.rerankWeights,
8880
8884
  decayPolicy: opts.decayPolicy,
8881
8885
  graphHop: opts.graphHop,
8886
+ retrievalMode,
8882
8887
  projectScopeMode: opts.projectScopeMode,
8883
8888
  projectHash: opts.projectHash,
8884
8889
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8899,10 +8904,26 @@ var Retriever = class {
8899
8904
  query,
8900
8905
  minScore: opts.minScore
8901
8906
  });
8907
+ const expandedSummary = retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(filteredSummary, {
8908
+ query: qualityQuery,
8909
+ currentStateQuery: query,
8910
+ limit: opts.topK * 4
8911
+ }) : filteredSummary;
8912
+ const scopedExpandedSummary = retrievalMode === "session-event-hybrid" ? await this.applyScopeFilters(expandedSummary, {
8913
+ scope: opts.scope,
8914
+ projectScopeMode: opts.projectScopeMode,
8915
+ projectHash: opts.projectHash,
8916
+ allowedProjectHashes: opts.allowedProjectHashes,
8917
+ facets: opts.facets
8918
+ }) : expandedSummary;
8919
+ const finalSummary = retrievalMode === "session-event-hybrid" ? this.applyQualityFilters(scopedExpandedSummary, {
8920
+ query,
8921
+ minScore: opts.minScore
8922
+ }) : scopedExpandedSummary;
8902
8923
  current = {
8903
- results: filteredSummary,
8904
- candidateResults: filteredSummary,
8905
- matchResult: this.matcher.matchSearchResults(filteredSummary, () => 0)
8924
+ results: finalSummary,
8925
+ candidateResults: finalSummary,
8926
+ matchResult: this.matcher.matchSearchResults(finalSummary, () => 0)
8906
8927
  };
8907
8928
  fallbackTrace.push("fallback:summary");
8908
8929
  }
@@ -8988,13 +9009,18 @@ var Retriever = class {
8988
9009
  initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);
8989
9010
  }
8990
9011
  }
8991
- const expandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9012
+ const graphExpandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
8992
9013
  query,
8993
9014
  queryGraphEnabled: this.queryGraphExpansionEnabled,
8994
9015
  maxHops: clampGraphHops(input.graphHop?.maxHops ?? 1),
8995
9016
  hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),
8996
9017
  limit: input.topK * 4
8997
9018
  });
9019
+ const expandedResults = input.retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(graphExpandedResults, {
9020
+ query: rerankQuery,
9021
+ currentStateQuery: query,
9022
+ limit: input.topK * 4
9023
+ }) : graphExpandedResults;
8998
9024
  const rerankedResults = input.rerankWithKeyword ? this.rerankByKeywordOverlap(expandedResults, rerankQuery, input.rerankWeights, input.decayPolicy) : expandedResults;
8999
9025
  const filtered = await this.applyScopeFilters(rerankedResults, {
9000
9026
  scope: input.scope,
@@ -9042,6 +9068,47 @@ var Retriever = class {
9042
9068
  }
9043
9069
  return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);
9044
9070
  }
9071
+ async expandSessionEventHybrid(seeds, opts) {
9072
+ if (seeds.length === 0 || opts.limit <= seeds.length) return seeds;
9073
+ const queryTokens = this.tokenize(opts.query);
9074
+ if (queryTokens.length === 0) return seeds;
9075
+ const byId = /* @__PURE__ */ new Map();
9076
+ for (const seed of seeds) byId.set(seed.eventId, seed);
9077
+ const bestSeedBySession = /* @__PURE__ */ new Map();
9078
+ for (const seed of [...seeds].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId))) {
9079
+ if (!seed.sessionId || bestSeedBySession.has(seed.sessionId)) continue;
9080
+ bestSeedBySession.set(seed.sessionId, seed);
9081
+ }
9082
+ const suppressStaleState = isCurrentStateQuery(opts.currentStateQuery);
9083
+ for (const [sessionId, seed] of bestSeedBySession) {
9084
+ const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9085
+ for (const event of [...sessionEvents].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())) {
9086
+ if (byId.has(event.id)) continue;
9087
+ if (isLowSignalContextContent(event.content)) continue;
9088
+ if (suppressStaleState && isStaleOrSupersededContent(event.content)) continue;
9089
+ const lexicalScore = this.keywordOverlap(queryTokens, this.tokenize(event.content));
9090
+ if (lexicalScore <= 0) continue;
9091
+ if (shouldApplyTechnicalGuard(opts.query) && !hasTechnicalTermOverlap(opts.query, event.content)) continue;
9092
+ const score = Math.min(0.95, Math.max(0.35, seed.score * 0.72 + lexicalScore * 0.28));
9093
+ const row = withRetrievalLane({
9094
+ id: `session-event-${seed.eventId}-${event.id}`,
9095
+ eventId: event.id,
9096
+ content: event.content,
9097
+ score,
9098
+ sessionId: event.sessionId,
9099
+ eventType: event.eventType,
9100
+ timestamp: event.timestamp.toISOString(),
9101
+ semanticScore: seed.semanticScore ?? seed.score,
9102
+ lexicalScore,
9103
+ recencyScore: seed.recencyScore
9104
+ }, { lane: "session_event", reason: `same_session:${seed.eventId}`, score });
9105
+ byId.set(row.eventId, row);
9106
+ if (byId.size >= opts.limit) break;
9107
+ }
9108
+ if (byId.size >= opts.limit) break;
9109
+ }
9110
+ return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9111
+ }
9045
9112
  async expandGraphHops(seeds, opts) {
9046
9113
  const byId = /* @__PURE__ */ new Map();
9047
9114
  for (const s of seeds) byId.set(s.eventId, s);