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"
@@ -8986,6 +8987,7 @@ var Retriever = class {
8986
8987
  }
8987
8988
  async retrieve(query, options = {}) {
8988
8989
  const opts = { ...DEFAULT_OPTIONS, ...options };
8990
+ const retrievalMode = options.retrievalMode ?? ((options.strategy ?? DEFAULT_OPTIONS.strategy) === "auto" ? "session-event-hybrid" : "event");
8989
8991
  const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;
8990
8992
  const fallbackTrace = [];
8991
8993
  const qualityQuery = buildRetrievalQualityQuery(query);
@@ -9016,6 +9018,7 @@ var Retriever = class {
9016
9018
  decayPolicy: opts.decayPolicy,
9017
9019
  intentRewrite: opts.intentRewrite === true,
9018
9020
  graphHop: opts.graphHop,
9021
+ retrievalMode,
9019
9022
  projectScopeMode: opts.projectScopeMode,
9020
9023
  projectHash: opts.projectHash,
9021
9024
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -9034,6 +9037,7 @@ var Retriever = class {
9034
9037
  rerankWeights: opts.rerankWeights,
9035
9038
  decayPolicy: opts.decayPolicy,
9036
9039
  graphHop: opts.graphHop,
9040
+ retrievalMode,
9037
9041
  projectScopeMode: opts.projectScopeMode,
9038
9042
  projectHash: opts.projectHash,
9039
9043
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -9053,6 +9057,7 @@ var Retriever = class {
9053
9057
  rerankWeights: opts.rerankWeights,
9054
9058
  decayPolicy: opts.decayPolicy,
9055
9059
  graphHop: opts.graphHop,
9060
+ retrievalMode,
9056
9061
  projectScopeMode: opts.projectScopeMode,
9057
9062
  projectHash: opts.projectHash,
9058
9063
  allowedProjectHashes: opts.allowedProjectHashes,
@@ -9073,10 +9078,26 @@ var Retriever = class {
9073
9078
  query,
9074
9079
  minScore: opts.minScore
9075
9080
  });
9081
+ const expandedSummary = retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(filteredSummary, {
9082
+ query: qualityQuery,
9083
+ currentStateQuery: query,
9084
+ limit: opts.topK * 4
9085
+ }) : filteredSummary;
9086
+ const scopedExpandedSummary = retrievalMode === "session-event-hybrid" ? await this.applyScopeFilters(expandedSummary, {
9087
+ scope: opts.scope,
9088
+ projectScopeMode: opts.projectScopeMode,
9089
+ projectHash: opts.projectHash,
9090
+ allowedProjectHashes: opts.allowedProjectHashes,
9091
+ facets: opts.facets
9092
+ }) : expandedSummary;
9093
+ const finalSummary = retrievalMode === "session-event-hybrid" ? this.applyQualityFilters(scopedExpandedSummary, {
9094
+ query,
9095
+ minScore: opts.minScore
9096
+ }) : scopedExpandedSummary;
9076
9097
  current = {
9077
- results: filteredSummary,
9078
- candidateResults: filteredSummary,
9079
- matchResult: this.matcher.matchSearchResults(filteredSummary, () => 0)
9098
+ results: finalSummary,
9099
+ candidateResults: finalSummary,
9100
+ matchResult: this.matcher.matchSearchResults(finalSummary, () => 0)
9080
9101
  };
9081
9102
  fallbackTrace.push("fallback:summary");
9082
9103
  }
@@ -9162,13 +9183,18 @@ var Retriever = class {
9162
9183
  initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);
9163
9184
  }
9164
9185
  }
9165
- const expandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9186
+ const graphExpandedResults = input.graphHop?.enabled === false ? initialResults : await this.expandGraphHops(initialResults, {
9166
9187
  query,
9167
9188
  queryGraphEnabled: this.queryGraphExpansionEnabled,
9168
9189
  maxHops: clampGraphHops(input.graphHop?.maxHops ?? 1),
9169
9190
  hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),
9170
9191
  limit: input.topK * 4
9171
9192
  });
9193
+ const expandedResults = input.retrievalMode === "session-event-hybrid" ? await this.expandSessionEventHybrid(graphExpandedResults, {
9194
+ query: rerankQuery,
9195
+ currentStateQuery: query,
9196
+ limit: input.topK * 4
9197
+ }) : graphExpandedResults;
9172
9198
  const rerankedResults = input.rerankWithKeyword ? this.rerankByKeywordOverlap(expandedResults, rerankQuery, input.rerankWeights, input.decayPolicy) : expandedResults;
9173
9199
  const filtered = await this.applyScopeFilters(rerankedResults, {
9174
9200
  scope: input.scope,
@@ -9216,6 +9242,47 @@ var Retriever = class {
9216
9242
  }
9217
9243
  return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);
9218
9244
  }
9245
+ async expandSessionEventHybrid(seeds, opts) {
9246
+ if (seeds.length === 0 || opts.limit <= seeds.length) return seeds;
9247
+ const queryTokens = this.tokenize(opts.query);
9248
+ if (queryTokens.length === 0) return seeds;
9249
+ const byId = /* @__PURE__ */ new Map();
9250
+ for (const seed of seeds) byId.set(seed.eventId, seed);
9251
+ const bestSeedBySession = /* @__PURE__ */ new Map();
9252
+ for (const seed of [...seeds].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId))) {
9253
+ if (!seed.sessionId || bestSeedBySession.has(seed.sessionId)) continue;
9254
+ bestSeedBySession.set(seed.sessionId, seed);
9255
+ }
9256
+ const suppressStaleState = isCurrentStateQuery(opts.currentStateQuery);
9257
+ for (const [sessionId, seed] of bestSeedBySession) {
9258
+ const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
9259
+ for (const event of [...sessionEvents].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())) {
9260
+ if (byId.has(event.id)) continue;
9261
+ if (isLowSignalContextContent(event.content)) continue;
9262
+ if (suppressStaleState && isStaleOrSupersededContent(event.content)) continue;
9263
+ const lexicalScore = this.keywordOverlap(queryTokens, this.tokenize(event.content));
9264
+ if (lexicalScore <= 0) continue;
9265
+ if (shouldApplyTechnicalGuard(opts.query) && !hasTechnicalTermOverlap(opts.query, event.content)) continue;
9266
+ const score = Math.min(0.95, Math.max(0.35, seed.score * 0.72 + lexicalScore * 0.28));
9267
+ const row = withRetrievalLane({
9268
+ id: `session-event-${seed.eventId}-${event.id}`,
9269
+ eventId: event.id,
9270
+ content: event.content,
9271
+ score,
9272
+ sessionId: event.sessionId,
9273
+ eventType: event.eventType,
9274
+ timestamp: event.timestamp.toISOString(),
9275
+ semanticScore: seed.semanticScore ?? seed.score,
9276
+ lexicalScore,
9277
+ recencyScore: seed.recencyScore
9278
+ }, { lane: "session_event", reason: `same_session:${seed.eventId}`, score });
9279
+ byId.set(row.eventId, row);
9280
+ if (byId.size >= opts.limit) break;
9281
+ }
9282
+ if (byId.size >= opts.limit) break;
9283
+ }
9284
+ return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
9285
+ }
9219
9286
  async expandGraphHops(seeds, opts) {
9220
9287
  const byId = /* @__PURE__ */ new Map();
9221
9288
  for (const s of seeds) byId.set(s.eventId, s);