claude-memory-layer 1.0.36 → 1.0.37

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.
@@ -2328,6 +2328,14 @@ function normalizeQueryRewriteKind(value) {
2328
2328
  return "none";
2329
2329
  }
2330
2330
  var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
2331
+ var DEFAULT_OUTBOX_STUCK_THRESHOLD_MS = 5 * 60 * 1e3;
2332
+ var DEFAULT_OUTBOX_MAX_RETRIES = 3;
2333
+ function emptyOutboxRecoveryResult() {
2334
+ return {
2335
+ embedding: { recoveredProcessing: 0, retriedFailed: 0 },
2336
+ vector: { recoveredProcessing: 0, retriedFailed: 0 }
2337
+ };
2338
+ }
2331
2339
  var SQLiteEventStore = class {
2332
2340
  db;
2333
2341
  initialized = false;
@@ -3078,7 +3086,9 @@ var SQLiteEventStore = class {
3078
3086
  const placeholders = ids.map(() => "?").join(",");
3079
3087
  sqliteRun(
3080
3088
  this.db,
3081
- `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,
3089
+ `UPDATE embedding_outbox
3090
+ SET status = 'processing', processed_at = datetime('now'), error_message = NULL
3091
+ WHERE id IN (${placeholders})`,
3082
3092
  ids
3083
3093
  );
3084
3094
  return pending.map((row) => ({
@@ -3148,6 +3158,58 @@ var SQLiteEventStore = class {
3148
3158
  [error, ...ids]
3149
3159
  );
3150
3160
  }
3161
+ /**
3162
+ * Recover abandoned outbox work after a worker/process crash.
3163
+ *
3164
+ * Rows in `processing` are claimed work. If the process exits before marking
3165
+ * them done/failed, they otherwise remain invisible to future processing.
3166
+ * Recovery is deliberately age-gated so an active worker is not disturbed.
3167
+ */
3168
+ async recoverStuckOutboxItems(options = {}) {
3169
+ await this.initialize();
3170
+ const thresholdMs = Number.isFinite(options.stuckThresholdMs) && (options.stuckThresholdMs ?? 0) >= 0 ? options.stuckThresholdMs : DEFAULT_OUTBOX_STUCK_THRESHOLD_MS;
3171
+ const maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) > 0 ? options.maxRetries : DEFAULT_OUTBOX_MAX_RETRIES;
3172
+ const now = options.now ?? /* @__PURE__ */ new Date();
3173
+ const threshold = new Date(now.getTime() - thresholdMs).toISOString();
3174
+ const result = emptyOutboxRecoveryResult();
3175
+ const embeddingRecovered = sqliteRun(
3176
+ this.db,
3177
+ `UPDATE embedding_outbox
3178
+ SET status = 'pending', processed_at = NULL, error_message = NULL
3179
+ WHERE status = 'processing'
3180
+ AND datetime(COALESCE(processed_at, created_at)) < datetime(?)`,
3181
+ [threshold]
3182
+ );
3183
+ result.embedding.recoveredProcessing = Number(embeddingRecovered.changes ?? 0);
3184
+ const embeddingRetried = sqliteRun(
3185
+ this.db,
3186
+ `UPDATE embedding_outbox
3187
+ SET status = 'pending', error_message = NULL
3188
+ WHERE status = 'failed'
3189
+ AND retry_count < ?`,
3190
+ [maxRetries]
3191
+ );
3192
+ result.embedding.retriedFailed = Number(embeddingRetried.changes ?? 0);
3193
+ const vectorRecovered = sqliteRun(
3194
+ this.db,
3195
+ `UPDATE vector_outbox
3196
+ SET status = 'pending', updated_at = ?, error = NULL
3197
+ WHERE status = 'processing'
3198
+ AND datetime(updated_at) < datetime(?)`,
3199
+ [now.toISOString(), threshold]
3200
+ );
3201
+ result.vector.recoveredProcessing = Number(vectorRecovered.changes ?? 0);
3202
+ const vectorRetried = sqliteRun(
3203
+ this.db,
3204
+ `UPDATE vector_outbox
3205
+ SET status = 'pending', updated_at = ?, error = NULL
3206
+ WHERE status = 'failed'
3207
+ AND retry_count < ?`,
3208
+ [now.toISOString(), maxRetries]
3209
+ );
3210
+ result.vector.retriedFailed = Number(vectorRetried.changes ?? 0);
3211
+ return result;
3212
+ }
3151
3213
  /**
3152
3214
  * Get embedding/vector outbox health statistics
3153
3215
  */
@@ -4019,6 +4081,7 @@ var VectorStore = class {
4019
4081
  * Get total count of vectors
4020
4082
  */
4021
4083
  async count() {
4084
+ await this.initialize();
4022
4085
  if (!this.table)
4023
4086
  return 0;
4024
4087
  const result = await this.table.countRows();
@@ -4457,6 +4520,10 @@ var MemoryQueryService = class {
4457
4520
  await this.initialize();
4458
4521
  return this.getMaintenanceStore("getOutboxStats").getOutboxStats();
4459
4522
  }
4523
+ async recoverStuckOutboxItems(options) {
4524
+ await this.initialize();
4525
+ return this.getMaintenanceStore("recoverStuckOutboxItems").recoverStuckOutboxItems(options);
4526
+ }
4460
4527
  async getStats() {
4461
4528
  await this.initialize();
4462
4529
  const deps = this.getStatsDeps();
@@ -7725,6 +7792,9 @@ var MemoryService = class {
7725
7792
  async getOutboxStats() {
7726
7793
  return this.queryService.getOutboxStats();
7727
7794
  }
7795
+ async recoverStuckOutboxItems(options) {
7796
+ return this.queryService.recoverStuckOutboxItems(options);
7797
+ }
7728
7798
  async getRetrievalTraceStats() {
7729
7799
  return this.retrievalAnalyticsService.getRetrievalTraceStats();
7730
7800
  }