claude-memory-layer 1.0.35 → 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.
@@ -2321,6 +2321,14 @@ function normalizeQueryRewriteKind(value) {
2321
2321
  return "none";
2322
2322
  }
2323
2323
  var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
2324
+ var DEFAULT_OUTBOX_STUCK_THRESHOLD_MS = 5 * 60 * 1e3;
2325
+ var DEFAULT_OUTBOX_MAX_RETRIES = 3;
2326
+ function emptyOutboxRecoveryResult() {
2327
+ return {
2328
+ embedding: { recoveredProcessing: 0, retriedFailed: 0 },
2329
+ vector: { recoveredProcessing: 0, retriedFailed: 0 }
2330
+ };
2331
+ }
2324
2332
  var SQLiteEventStore = class {
2325
2333
  db;
2326
2334
  initialized = false;
@@ -3071,7 +3079,9 @@ var SQLiteEventStore = class {
3071
3079
  const placeholders = ids.map(() => "?").join(",");
3072
3080
  sqliteRun(
3073
3081
  this.db,
3074
- `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,
3082
+ `UPDATE embedding_outbox
3083
+ SET status = 'processing', processed_at = datetime('now'), error_message = NULL
3084
+ WHERE id IN (${placeholders})`,
3075
3085
  ids
3076
3086
  );
3077
3087
  return pending.map((row) => ({
@@ -3141,6 +3151,58 @@ var SQLiteEventStore = class {
3141
3151
  [error, ...ids]
3142
3152
  );
3143
3153
  }
3154
+ /**
3155
+ * Recover abandoned outbox work after a worker/process crash.
3156
+ *
3157
+ * Rows in `processing` are claimed work. If the process exits before marking
3158
+ * them done/failed, they otherwise remain invisible to future processing.
3159
+ * Recovery is deliberately age-gated so an active worker is not disturbed.
3160
+ */
3161
+ async recoverStuckOutboxItems(options = {}) {
3162
+ await this.initialize();
3163
+ const thresholdMs = Number.isFinite(options.stuckThresholdMs) && (options.stuckThresholdMs ?? 0) >= 0 ? options.stuckThresholdMs : DEFAULT_OUTBOX_STUCK_THRESHOLD_MS;
3164
+ const maxRetries = Number.isFinite(options.maxRetries) && (options.maxRetries ?? 0) > 0 ? options.maxRetries : DEFAULT_OUTBOX_MAX_RETRIES;
3165
+ const now = options.now ?? /* @__PURE__ */ new Date();
3166
+ const threshold = new Date(now.getTime() - thresholdMs).toISOString();
3167
+ const result = emptyOutboxRecoveryResult();
3168
+ const embeddingRecovered = sqliteRun(
3169
+ this.db,
3170
+ `UPDATE embedding_outbox
3171
+ SET status = 'pending', processed_at = NULL, error_message = NULL
3172
+ WHERE status = 'processing'
3173
+ AND datetime(COALESCE(processed_at, created_at)) < datetime(?)`,
3174
+ [threshold]
3175
+ );
3176
+ result.embedding.recoveredProcessing = Number(embeddingRecovered.changes ?? 0);
3177
+ const embeddingRetried = sqliteRun(
3178
+ this.db,
3179
+ `UPDATE embedding_outbox
3180
+ SET status = 'pending', error_message = NULL
3181
+ WHERE status = 'failed'
3182
+ AND retry_count < ?`,
3183
+ [maxRetries]
3184
+ );
3185
+ result.embedding.retriedFailed = Number(embeddingRetried.changes ?? 0);
3186
+ const vectorRecovered = sqliteRun(
3187
+ this.db,
3188
+ `UPDATE vector_outbox
3189
+ SET status = 'pending', updated_at = ?, error = NULL
3190
+ WHERE status = 'processing'
3191
+ AND datetime(updated_at) < datetime(?)`,
3192
+ [now.toISOString(), threshold]
3193
+ );
3194
+ result.vector.recoveredProcessing = Number(vectorRecovered.changes ?? 0);
3195
+ const vectorRetried = sqliteRun(
3196
+ this.db,
3197
+ `UPDATE vector_outbox
3198
+ SET status = 'pending', updated_at = ?, error = NULL
3199
+ WHERE status = 'failed'
3200
+ AND retry_count < ?`,
3201
+ [now.toISOString(), maxRetries]
3202
+ );
3203
+ result.vector.retriedFailed = Number(vectorRetried.changes ?? 0);
3204
+ return result;
3205
+ }
3144
3206
  /**
3145
3207
  * Get embedding/vector outbox health statistics
3146
3208
  */
@@ -4012,6 +4074,7 @@ var VectorStore = class {
4012
4074
  * Get total count of vectors
4013
4075
  */
4014
4076
  async count() {
4077
+ await this.initialize();
4015
4078
  if (!this.table)
4016
4079
  return 0;
4017
4080
  const result = await this.table.countRows();
@@ -4450,6 +4513,10 @@ var MemoryQueryService = class {
4450
4513
  await this.initialize();
4451
4514
  return this.getMaintenanceStore("getOutboxStats").getOutboxStats();
4452
4515
  }
4516
+ async recoverStuckOutboxItems(options) {
4517
+ await this.initialize();
4518
+ return this.getMaintenanceStore("recoverStuckOutboxItems").recoverStuckOutboxItems(options);
4519
+ }
4453
4520
  async getStats() {
4454
4521
  await this.initialize();
4455
4522
  const deps = this.getStatsDeps();
@@ -7743,6 +7810,9 @@ var MemoryService = class {
7743
7810
  async getOutboxStats() {
7744
7811
  return this.queryService.getOutboxStats();
7745
7812
  }
7813
+ async recoverStuckOutboxItems(options) {
7814
+ return this.queryService.recoverStuckOutboxItems(options);
7815
+ }
7746
7816
  async getRetrievalTraceStats() {
7747
7817
  return this.retrievalAnalyticsService.getRetrievalTraceStats();
7748
7818
  }