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.
@@ -2572,6 +2572,7 @@ var VectorOutbox = class {
2572
2572
  // src/core/retrieval-debug-lanes.ts
2573
2573
  var RETRIEVAL_DEBUG_LANE_NAMES = [
2574
2574
  "raw_event",
2575
+ "session_event",
2575
2576
  "session_summary",
2576
2577
  "graph_path",
2577
2578
  "facet_match"
@@ -8832,6 +8833,7 @@ var Retriever = class {
8832
8833
  }
8833
8834
  async retrieve(query, options = {}) {
8834
8835
  const opts = { ...DEFAULT_OPTIONS, ...options };
8836
+ const retrievalMode = options.retrievalMode ?? ((options.strategy ?? DEFAULT_OPTIONS.strategy) === "auto" ? "session-event-hybrid" : "event");
8835
8837
  const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;
8836
8838
  const fallbackTrace = [];
8837
8839
  const qualityQuery = buildRetrievalQualityQuery(query);
@@ -8862,6 +8864,7 @@ var Retriever = class {
8862
8864
  decayPolicy: opts.decayPolicy,
8863
8865
  intentRewrite: opts.intentRewrite === true,
8864
8866
  graphHop: opts.graphHop,
8867
+ retrievalMode,
8865
8868
  projectScopeMode: opts.projectScopeMode,
8866
8869
  projectHash: opts.projectHash,
8867
8870
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8880,6 +8883,7 @@ var Retriever = class {
8880
8883
  rerankWeights: opts.rerankWeights,
8881
8884
  decayPolicy: opts.decayPolicy,
8882
8885
  graphHop: opts.graphHop,
8886
+ retrievalMode,
8883
8887
  projectScopeMode: opts.projectScopeMode,
8884
8888
  projectHash: opts.projectHash,
8885
8889
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8899,6 +8903,7 @@ var Retriever = class {
8899
8903
  rerankWeights: opts.rerankWeights,
8900
8904
  decayPolicy: opts.decayPolicy,
8901
8905
  graphHop: opts.graphHop,
8906
+ retrievalMode,
8902
8907
  projectScopeMode: opts.projectScopeMode,
8903
8908
  projectHash: opts.projectHash,
8904
8909
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -8919,10 +8924,26 @@ var Retriever = class {
8919
8924
  query,
8920
8925
  minScore: opts.minScore
8921
8926
  });
8927
+ const expandedSummary = retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(filteredSummary, {
8928
+ query: qualityQuery,
8929
+ currentStateQuery: query,
8930
+ limit: opts.topK * 4
8931
+ }) : filteredSummary;
8932
+ const scopedExpandedSummary = retrievalMode === "session-event-hybrid" ? await this.applyScopeFilters(expandedSummary, {
8933
+ scope: opts.scope,
8934
+ projectScopeMode: opts.projectScopeMode,
8935
+ projectHash: opts.projectHash,
8936
+ allowedProjectHashes: opts.allowedProjectHashes,
8937
+ facets: opts.facets
8938
+ }) : expandedSummary;
8939
+ const finalSummary = retrievalMode === "session-event-hybrid" ? this.applyQualityFilters(scopedExpandedSummary, {
8940
+ query,
8941
+ minScore: opts.minScore
8942
+ }) : scopedExpandedSummary;
8922
8943
  current = {
8923
- results: filteredSummary,
8924
- candidateResults: filteredSummary,
8925
- matchResult: this.matcher.matchSearchResults(filteredSummary, () => 0)
8944
+ results: finalSummary,
8945
+ candidateResults: finalSummary,
8946
+ matchResult: this.matcher.matchSearchResults(finalSummary, () => 0)
8926
8947
  };
8927
8948
  fallbackTrace.push("fallback:summary");
8928
8949
  }
@@ -9008,13 +9029,18 @@ var Retriever = class {
9008
9029
  initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);
9009
9030
  }
9010
9031
  }
9011
- const expandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9032
+ const graphExpandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9012
9033
  query,
9013
9034
  queryGraphEnabled: this.queryGraphExpansionEnabled,
9014
9035
  maxHops: clampGraphHops(input.graphHop?.maxHops ?? 1),
9015
9036
  hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),
9016
9037
  limit: input.topK * 4
9017
9038
  });
9039
+ const expandedResults = input.retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(graphExpandedResults, {
9040
+ query: rerankQuery,
9041
+ currentStateQuery: query,
9042
+ limit: input.topK * 4
9043
+ }) : graphExpandedResults;
9018
9044
  const rerankedResults = input.rerankWithKeyword ? this.rerankByKeywordOverlap(expandedResults, rerankQuery, input.rerankWeights, input.decayPolicy) : expandedResults;
9019
9045
  const filtered = await this.applyScopeFilters(rerankedResults, {
9020
9046
  scope: input.scope,
@@ -9062,6 +9088,47 @@ var Retriever = class {
9062
9088
  }
9063
9089
  return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);
9064
9090
  }
9091
+ async expandSessionEventHybrid(seeds, opts) {
9092
+ if (seeds.length === 0 || opts.limit <= seeds.length) return seeds;
9093
+ const queryTokens = this.tokenize(opts.query);
9094
+ if (queryTokens.length === 0) return seeds;
9095
+ const byId = /* @__PURE__ */ new Map();
9096
+ for (const seed of seeds) byId.set(seed.eventId, seed);
9097
+ const bestSeedBySession = /* @__PURE__ */ new Map();
9098
+ for (const seed of [...seeds].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId))) {
9099
+ if (!seed.sessionId || bestSeedBySession.has(seed.sessionId)) continue;
9100
+ bestSeedBySession.set(seed.sessionId, seed);
9101
+ }
9102
+ const suppressStaleState = isCurrentStateQuery(opts.currentStateQuery);
9103
+ for (const [sessionId, seed] of bestSeedBySession) {
9104
+ const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9105
+ for (const event of [...sessionEvents].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())) {
9106
+ if (byId.has(event.id)) continue;
9107
+ if (isLowSignalContextContent(event.content)) continue;
9108
+ if (suppressStaleState && isStaleOrSupersededContent(event.content)) continue;
9109
+ const lexicalScore = this.keywordOverlap(queryTokens, this.tokenize(event.content));
9110
+ if (lexicalScore <= 0) continue;
9111
+ if (shouldApplyTechnicalGuard(opts.query) && !hasTechnicalTermOverlap(opts.query, event.content)) continue;
9112
+ const score = Math.min(0.95, Math.max(0.35, seed.score * 0.72 + lexicalScore * 0.28));
9113
+ const row = withRetrievalLane({
9114
+ id: `session-event-${seed.eventId}-${event.id}`,
9115
+ eventId: event.id,
9116
+ content: event.content,
9117
+ score,
9118
+ sessionId: event.sessionId,
9119
+ eventType: event.eventType,
9120
+ timestamp: event.timestamp.toISOString(),
9121
+ semanticScore: seed.semanticScore ?? seed.score,
9122
+ lexicalScore,
9123
+ recencyScore: seed.recencyScore
9124
+ }, { lane: "session_event", reason: `same_session:${seed.eventId}`, score });
9125
+ byId.set(row.eventId, row);
9126
+ if (byId.size >= opts.limit) break;
9127
+ }
9128
+ if (byId.size >= opts.limit) break;
9129
+ }
9130
+ return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9131
+ }
9065
9132
  async expandGraphHops(seeds, opts) {
9066
9133
  const byId = /* @__PURE__ */ new Map();
9067
9134
  for (const s of seeds) byId.set(s.eventId, s);