@anuma/sdk 6.35.0 → 6.36.0

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.
@@ -89,9 +89,9 @@ function createSseClient({
89
89
  if (done) break;
90
90
  buffer += value;
91
91
  buffer = buffer.replace(/\r\n?/g, "\n");
92
- const chunks = buffer.split("\n\n");
93
- buffer = chunks.pop() ?? "";
94
- for (const chunk of chunks) {
92
+ const chunks2 = buffer.split("\n\n");
93
+ buffer = chunks2.pop() ?? "";
94
+ for (const chunk of chunks2) {
95
95
  const lines = chunk.split("\n");
96
96
  const dataLines = [];
97
97
  let eventName;
@@ -4731,14 +4731,14 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
4731
4731
  });
4732
4732
  return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
4733
4733
  }
4734
- async function updateMessageChunksOp(ctx, uniqueId, chunks, embeddingModel) {
4734
+ async function updateMessageChunksOp(ctx, uniqueId, chunks2, embeddingModel) {
4735
4735
  let message;
4736
4736
  try {
4737
4737
  message = await ctx.messagesCollection.find(uniqueId);
4738
4738
  } catch {
4739
4739
  return null;
4740
4740
  }
4741
- const storedChunks = chunks.map(({ text: _text, ...rest }) => rest);
4741
+ const storedChunks = chunks2.map(({ text: _text, ...rest }) => rest);
4742
4742
  await ctx.database.write(async () => {
4743
4743
  await message.update((msg) => {
4744
4744
  msg._setRaw("chunks", JSON.stringify(storedChunks));
@@ -4782,12 +4782,12 @@ async function stripLegacyChunkTextOp(ctx) {
4782
4782
  const messages = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(changedIds))).fetch();
4783
4783
  const updates = messages.flatMap((message) => {
4784
4784
  const raw = message._raw;
4785
- const chunks = chunksWithoutText(raw.chunks);
4786
- if (!chunks) return [];
4785
+ const chunks2 = chunksWithoutText(raw.chunks);
4786
+ if (!chunks2) return [];
4787
4787
  const updatedAt = raw.updated_at;
4788
4788
  return [
4789
4789
  message.prepareUpdate((msg) => {
4790
- msg._setRaw("chunks", JSON.stringify(chunks));
4790
+ msg._setRaw("chunks", JSON.stringify(chunks2));
4791
4791
  msg._setRaw("updated_at", updatedAt);
4792
4792
  })
4793
4793
  ];
@@ -4997,15 +4997,15 @@ async function searchChunksOp(ctx, queryVector, options) {
4997
4997
  }
4998
4998
  continue;
4999
4999
  }
5000
- const chunks = await readRawJsonField(message, "chunks", ctx.walletAddress);
5001
- if (chunks && chunks.length > 0) {
5002
- const vectors = chunks.map(
5000
+ const chunks2 = await readRawJsonField(message, "chunks", ctx.walletAddress);
5001
+ if (chunks2 && chunks2.length > 0) {
5002
+ const vectors = chunks2.map(
5003
5003
  (chunk) => decodeChunkVector(chunk.vector, () => {
5004
5004
  unreadableVectors++;
5005
5005
  })
5006
5006
  );
5007
5007
  chunkCache?.set(message.id, { version, chunks: vectors });
5008
- for (let ci = 0; ci < chunks.length; ci++) {
5008
+ for (let ci = 0; ci < chunks2.length; ci++) {
5009
5009
  const vec = vectors[ci];
5010
5010
  if (vec.length === 0) continue;
5011
5011
  const similarity = cosineSimilarity(queryVector, vec);
@@ -5013,7 +5013,7 @@ async function searchChunksOp(ctx, queryVector, options) {
5013
5013
  candidates.push({
5014
5014
  message,
5015
5015
  similarity,
5016
- chunkTextSource: { kind: "chunk", chunk: chunks[ci], siblings: chunks }
5016
+ chunkTextSource: { kind: "chunk", chunk: chunks2[ci], siblings: chunks2 }
5017
5017
  });
5018
5018
  }
5019
5019
  }
@@ -5190,7 +5190,7 @@ function chunkText(text12, options) {
5190
5190
  ];
5191
5191
  }
5192
5192
  const sentences = splitIntoSentences(text12);
5193
- const chunks = [];
5193
+ const chunks2 = [];
5194
5194
  let currentChunkSentences = [];
5195
5195
  let currentChunkStart = 0;
5196
5196
  let currentOffset = 0;
@@ -5204,7 +5204,7 @@ function chunkText(text12, options) {
5204
5204
  if (sentence.length > chunkSize) {
5205
5205
  if (currentChunkSentences.length > 0) {
5206
5206
  const chunkText2 = currentChunkSentences.join(" ");
5207
- chunks.push({
5207
+ chunks2.push({
5208
5208
  text: chunkText2,
5209
5209
  startOffset: currentChunkStart,
5210
5210
  endOffset: currentOffset
@@ -5215,7 +5215,7 @@ function chunkText(text12, options) {
5215
5215
  const chunkEnd = Math.min(j + chunkSize, sentence.length);
5216
5216
  const chunk = sentence.slice(j, chunkEnd);
5217
5217
  if (chunk.length >= minChunkSize) {
5218
- chunks.push({
5218
+ chunks2.push({
5219
5219
  text: chunk,
5220
5220
  startOffset: sentenceStart + j,
5221
5221
  endOffset: sentenceStart + chunkEnd
@@ -5229,7 +5229,7 @@ function chunkText(text12, options) {
5229
5229
  const currentText = currentChunkSentences.join(" ");
5230
5230
  const potentialLength = currentText.length + (currentText ? 1 : 0) + sentence.length;
5231
5231
  if (potentialLength > chunkSize && currentChunkSentences.length > 0) {
5232
- chunks.push({
5232
+ chunks2.push({
5233
5233
  text: currentText,
5234
5234
  startOffset: currentChunkStart,
5235
5235
  endOffset: currentOffset
@@ -5260,14 +5260,14 @@ function chunkText(text12, options) {
5260
5260
  if (currentChunkSentences.length > 0) {
5261
5261
  const chunkText2 = currentChunkSentences.join(" ");
5262
5262
  if (chunkText2.length >= minChunkSize) {
5263
- chunks.push({
5263
+ chunks2.push({
5264
5264
  text: chunkText2,
5265
5265
  startOffset: currentChunkStart,
5266
5266
  endOffset: text12.length
5267
5267
  });
5268
5268
  }
5269
5269
  }
5270
- if (chunks.length === 0) {
5270
+ if (chunks2.length === 0) {
5271
5271
  const trimmedText = text12.trim();
5272
5272
  if (trimmedText.length > 0) {
5273
5273
  return [
@@ -5279,7 +5279,7 @@ function chunkText(text12, options) {
5279
5279
  ];
5280
5280
  }
5281
5281
  }
5282
- return chunks;
5282
+ return chunks2;
5283
5283
  }
5284
5284
  function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
5285
5285
  return content.length > chunkSize;
@@ -5497,18 +5497,18 @@ async function embedMany(texts, options, outer) {
5497
5497
  outer
5498
5498
  );
5499
5499
  } else {
5500
- const chunks = [];
5500
+ const chunks2 = [];
5501
5501
  for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
5502
- chunks.push(uncachedTexts.slice(i, i + chunkSize));
5502
+ chunks2.push(uncachedTexts.slice(i, i + chunkSize));
5503
5503
  }
5504
- const allEmbeddings = new Array(chunks.length);
5504
+ const allEmbeddings = new Array(chunks2.length);
5505
5505
  let nextIndex = 0;
5506
5506
  const worker = async () => {
5507
- while (nextIndex < chunks.length) {
5507
+ while (nextIndex < chunks2.length) {
5508
5508
  if (outer?.aborted) throw outer.reason;
5509
5509
  const idx = nextIndex++;
5510
5510
  allEmbeddings[idx] = await generateEmbeddingsBatch(
5511
- chunks[idx],
5511
+ chunks2[idx],
5512
5512
  headers,
5513
5513
  baseUrl,
5514
5514
  embeddingModel,
@@ -5520,7 +5520,7 @@ async function embedMany(texts, options, outer) {
5520
5520
  }
5521
5521
  };
5522
5522
  const workers = Array.from(
5523
- { length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks.length) },
5523
+ { length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks2.length) },
5524
5524
  () => worker()
5525
5525
  );
5526
5526
  await Promise.all(workers);
@@ -12863,8 +12863,8 @@ var WatermelonChatStorageAdapter = class {
12863
12863
  updateMessageEmbedding(uniqueId, vector, embeddingModel) {
12864
12864
  return updateMessageEmbeddingOp(this.ctx, uniqueId, vector, embeddingModel);
12865
12865
  }
12866
- updateMessageChunks(uniqueId, chunks, embeddingModel) {
12867
- return updateMessageChunksOp(this.ctx, uniqueId, chunks, embeddingModel);
12866
+ updateMessageChunks(uniqueId, chunks2, embeddingModel) {
12867
+ return updateMessageChunksOp(this.ctx, uniqueId, chunks2, embeddingModel);
12868
12868
  }
12869
12869
  updateMessageError(uniqueId, error) {
12870
12870
  return updateMessageErrorOp(this.ctx, uniqueId, error);
@@ -21169,6 +21169,65 @@ function createLocalMemoryStore(options) {
21169
21169
  };
21170
21170
  }
21171
21171
 
21172
+ // src/lib/memory/store/memoryKeys.ts
21173
+ var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
21174
+ var MemoryKeyError = class extends Error {
21175
+ constructor(message) {
21176
+ super(message);
21177
+ this.name = "MemoryKeyError";
21178
+ }
21179
+ };
21180
+ async function importAesKey(hex) {
21181
+ return crypto.subtle.importKey(
21182
+ "raw",
21183
+ hexToBytes(hex).buffer,
21184
+ { name: "AES-GCM" },
21185
+ false,
21186
+ ["encrypt", "decrypt"]
21187
+ );
21188
+ }
21189
+ async function deriveMemoryKeyRing(signatureHex) {
21190
+ const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
21191
+ const digest = await crypto.subtle.digest(
21192
+ "SHA-256",
21193
+ new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
21194
+ );
21195
+ const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
21196
+ return {
21197
+ keyId,
21198
+ v3: await importAesKey(v3Hex),
21199
+ v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
21200
+ };
21201
+ }
21202
+ async function decryptWith(value, rings) {
21203
+ const version = value.startsWith("enc:v3:") ? "v3" : "v2";
21204
+ for (const ring of rings) {
21205
+ try {
21206
+ return await decryptDataWithKey(value.slice(`enc:${version}:`.length), ring[version]);
21207
+ } catch {
21208
+ continue;
21209
+ }
21210
+ }
21211
+ throw new MemoryKeyError(`No supplied key decrypts this enc:${version} field`);
21212
+ }
21213
+ function memoryCipher(canonical) {
21214
+ return {
21215
+ encrypt: async (plaintext) => `enc:v3:${await encryptDataWithKey(plaintext, canonical.v3)}`,
21216
+ decrypt: async (ciphertext) => {
21217
+ if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
21218
+ throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
21219
+ return decryptWith(ciphertext, [canonical]);
21220
+ }
21221
+ };
21222
+ }
21223
+ async function reencryptMemoryField(value, canonical, fallbacks = []) {
21224
+ const { encrypt } = memoryCipher(canonical);
21225
+ if (!value.startsWith("enc:")) return encrypt(value);
21226
+ if (!isEncrypted(value))
21227
+ throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
21228
+ return encrypt(await decryptWith(value, [canonical, ...fallbacks]));
21229
+ }
21230
+
21172
21231
  // src/lib/memory/store/remotePersistence.ts
21173
21232
  var RemoteMemoryError = class extends Error {
21174
21233
  constructor(message, status, code) {
@@ -21221,6 +21280,30 @@ var candidateListLimits = [
21221
21280
  ["memory_ids", 1e3],
21222
21281
  ["force_ids", 100]
21223
21282
  ];
21283
+ var queryListLimits = [
21284
+ ["scopes", 20],
21285
+ ["fact_types", 20],
21286
+ ["visibility", 20],
21287
+ ["memory_ids", 1e3],
21288
+ ["topics", 100]
21289
+ ];
21290
+ var queryFields = [
21291
+ "include_deleted",
21292
+ "include_archived",
21293
+ "include_quarantined",
21294
+ "include_superseded",
21295
+ "archived_only",
21296
+ "scopes",
21297
+ "fact_types",
21298
+ "visibility",
21299
+ "memory_ids",
21300
+ "topics",
21301
+ "updated_after",
21302
+ "order",
21303
+ "cursor",
21304
+ "limit",
21305
+ "include_embeddings"
21306
+ ];
21224
21307
  function record(value) {
21225
21308
  return typeof value === "object" && value !== null && !Array.isArray(value);
21226
21309
  }
@@ -21555,6 +21638,35 @@ async function createRemoteMemoryPersistence(options) {
21555
21638
  throw new Error("Invalid nearby batch response");
21556
21639
  return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
21557
21640
  },
21641
+ query: async (queryOptions = {}) => {
21642
+ const { signal, ...query } = queryOptions;
21643
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
21644
+ throw new Error("Page limit must be 1\u2013200");
21645
+ for (const [key, max] of queryListLimits) {
21646
+ const values = query[key];
21647
+ if (values && values.length > max)
21648
+ throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
21649
+ }
21650
+ const page = await request(
21651
+ "/memories/query",
21652
+ {
21653
+ method: "POST",
21654
+ body: JSON.stringify(
21655
+ Object.fromEntries(
21656
+ queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
21657
+ )
21658
+ )
21659
+ },
21660
+ signal
21661
+ );
21662
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
21663
+ throw new Error("Invalid nearby private-memory page");
21664
+ return {
21665
+ ...await decodeAll(page.items),
21666
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
21667
+ ...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
21668
+ };
21669
+ },
21558
21670
  candidateSet,
21559
21671
  candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
21560
21672
  };
@@ -21943,6 +22055,489 @@ function createRemoteMemoryPipeline(options) {
21943
22055
  };
21944
22056
  }
21945
22057
 
22058
+ // src/lib/memory/store/remoteStore.ts
22059
+ import { v7 as uuidv76 } from "uuid";
22060
+ function relevant(change, options) {
22061
+ return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
22062
+ }
22063
+ function safely(onChange) {
22064
+ try {
22065
+ onChange();
22066
+ } catch (error) {
22067
+ getLogger().warn("[memory/remote-store] Subscriber threw:", error);
22068
+ }
22069
+ }
22070
+ var MAX_BATCH = 50;
22071
+ var MAX_QUERY_IDS = 1e3;
22072
+ var MAX_QUERY_TOPICS = 100;
22073
+ var MAX_QUERY_FILTER = 20;
22074
+ var RemoteMemoryPartialCreateError = class extends Error {
22075
+ constructor(created, cause) {
22076
+ super(`createMany stored ${created.length} memories before a batch failed`);
22077
+ this.created = created;
22078
+ this.cause = cause;
22079
+ this.name = "RemoteMemoryPartialCreateError";
22080
+ }
22081
+ };
22082
+ function warnFailed(failed) {
22083
+ if (failed.length)
22084
+ getLogger().warn(
22085
+ `[memory/remote-store] Skipping ${failed.length} undecryptable row(s)`,
22086
+ failed.map((failure) => failure.memory_id)
22087
+ );
22088
+ }
22089
+ function bounded(filters, key) {
22090
+ const values = filters[key];
22091
+ if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
22092
+ return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
22093
+ }
22094
+ function chunks(values, size) {
22095
+ const out = [];
22096
+ for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
22097
+ return out;
22098
+ }
22099
+ function stateFilters(options) {
22100
+ return {
22101
+ include_deleted: options.includeDeleted,
22102
+ include_archived: options.includeArchived,
22103
+ include_quarantined: options.includeQuarantined,
22104
+ include_superseded: options.includeSuperseded
22105
+ };
22106
+ }
22107
+ function hidden(memory, options) {
22108
+ if (memory.trust_tier === "quarantined") return true;
22109
+ if (options.includeDeleted) return false;
22110
+ return !!memory.is_deleted || memory.archived_at !== void 0 && memory.archived_at !== null || !!memory.superseded_by;
22111
+ }
22112
+ function subscriptionKey({ memory, version }, options) {
22113
+ if (hidden(memory, options)) return void 0;
22114
+ if (options.includeDeleted) return String(!!memory.is_deleted);
22115
+ return JSON.stringify([
22116
+ options.embeddings ? version : null,
22117
+ memory.content,
22118
+ memory.scope,
22119
+ memory.updated_at,
22120
+ memory.fact_type,
22121
+ memory.event_time_start,
22122
+ memory.event_time_end,
22123
+ memory.event_time_kind,
22124
+ memory.trust_tier,
22125
+ memory.visibility,
22126
+ memory.published_at,
22127
+ memory.geohash,
22128
+ memory.topics,
22129
+ memory.topics_user_managed,
22130
+ memory.media,
22131
+ memory.source
22132
+ ]);
22133
+ }
22134
+ function topicInputs(topics, source) {
22135
+ return topics.flatMap((topic) => {
22136
+ const name = (typeof topic === "string" ? topic : topic.name).trim();
22137
+ const kind = typeof topic === "string" ? void 0 : topic.kind;
22138
+ return name ? [{ name, ...kind && { kind }, source }] : [];
22139
+ });
22140
+ }
22141
+ function mergeTopics(existing, added) {
22142
+ const byName = /* @__PURE__ */ new Map();
22143
+ for (const topic of [...existing, ...added]) {
22144
+ const key = normalizeEntityName(topic.name);
22145
+ if (!byName.has(key)) byName.set(key, topic);
22146
+ }
22147
+ return [...byName.values()];
22148
+ }
22149
+ function canonicalTopics(row) {
22150
+ return new Set((parseTopics(row.topics) ?? []).map((topic) => normalizeEntityName(topic.name)));
22151
+ }
22152
+ function createRemoteMemoryStore(options) {
22153
+ const { persistence, embeddingOptions } = options;
22154
+ const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
22155
+ const pollIntervalMs = options.pollIntervalMs ?? 6e4;
22156
+ const pipeline = createRemoteMemoryPipeline(options);
22157
+ const subscribers = /* @__PURE__ */ new Set();
22158
+ const seen = /* @__PURE__ */ new Map();
22159
+ let timer;
22160
+ const notify = (change, records = []) => {
22161
+ if (timer) for (const record2 of records) seen.set(record2.memory.memory_id, record2);
22162
+ for (const subscriber of [...subscribers])
22163
+ if (relevant(change, subscriber.options)) safely(subscriber.onChange);
22164
+ };
22165
+ const enumerate = async (filters, max = Infinity) => {
22166
+ const records = [];
22167
+ let cursor2;
22168
+ do {
22169
+ const page = await persistence.query({
22170
+ ...filters,
22171
+ limit: Math.min(200, Math.max(1, max - records.length)),
22172
+ ...cursor2 && { cursor: cursor2 }
22173
+ });
22174
+ warnFailed(page.failed);
22175
+ records.push(...page.items);
22176
+ cursor2 = page.next_cursor;
22177
+ } while (cursor2 && records.length < max);
22178
+ return records.slice(0, max);
22179
+ };
22180
+ const enumerateIds = async (ids, filters) => (await Promise.all(
22181
+ chunks([...new Set(ids)], MAX_QUERY_IDS).map(
22182
+ (memory_ids) => enumerate({ ...filters, memory_ids })
22183
+ )
22184
+ )).flat();
22185
+ const queues = /* @__PURE__ */ new Map();
22186
+ const serialized = (id, task) => {
22187
+ const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
22188
+ const settled = run.catch(() => void 0);
22189
+ queues.set(id, settled);
22190
+ void settled.then(() => {
22191
+ if (queues.get(id) === settled) queues.delete(id);
22192
+ });
22193
+ return run;
22194
+ };
22195
+ const live = async (id) => {
22196
+ const record2 = await persistence.get(id);
22197
+ return record2 && !record2.memory.is_deleted ? record2 : null;
22198
+ };
22199
+ const mutate = async (id, change, edit) => serialized(id, async () => {
22200
+ const record2 = await live(id);
22201
+ if (!record2) return null;
22202
+ const next = edit(structuredClone(record2.memory));
22203
+ if (!next) return null;
22204
+ const saved = await persistence.put(next, record2);
22205
+ notify(change, [saved]);
22206
+ return saved;
22207
+ });
22208
+ const embedInBackground = ({ memory: { memory_id: id, content } }) => {
22209
+ generateEmbedding(content, embeddingOptions).then(
22210
+ (vector) => serialized(id, async () => {
22211
+ const current = await live(id);
22212
+ if (!current || current.memory.content !== content || current.memory.embedding?.length)
22213
+ return;
22214
+ const saved = await persistence.put(
22215
+ { ...current.memory, embedding: storedVector(vector), embedding_model: model },
22216
+ current
22217
+ );
22218
+ notify("embedding", [saved]);
22219
+ })
22220
+ ).catch((error) => {
22221
+ getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
22222
+ });
22223
+ };
22224
+ const newRow = (input) => {
22225
+ const now = Date.now();
22226
+ const scope = input.scope ?? "private";
22227
+ return {
22228
+ memory_id: uuidv76(),
22229
+ content: input.content,
22230
+ scope,
22231
+ level: levelFromScope(scope),
22232
+ created_at: now,
22233
+ updated_at: now,
22234
+ is_deleted: false,
22235
+ ...input.embedding !== void 0 && {
22236
+ embedding: storedVector(JSON.parse(input.embedding)),
22237
+ embedding_model: input.embeddingModel ?? model
22238
+ },
22239
+ proof_count: 1,
22240
+ source: "manual",
22241
+ ...input.eventTime && {
22242
+ event_time_start: input.eventTime.start ?? void 0,
22243
+ event_time_end: input.eventTime.end ?? void 0,
22244
+ event_time_kind: input.eventTime.kind ?? void 0
22245
+ },
22246
+ fact_type: input.factType,
22247
+ geohash: input.geohash,
22248
+ visibility: "private",
22249
+ twin_opt_in: false
22250
+ };
22251
+ };
22252
+ const created = (records, inputs) => {
22253
+ records.forEach((record2, i) => {
22254
+ if (inputs[i].embedding === void 0) embedInBackground(record2);
22255
+ });
22256
+ notify("membership", records);
22257
+ return records.map((record2) => stored(record2.memory));
22258
+ };
22259
+ const asStored = (record2) => record2 ? stored(record2.memory) : null;
22260
+ const everyState = {
22261
+ include_deleted: true,
22262
+ include_archived: true,
22263
+ include_quarantined: true,
22264
+ include_superseded: true
22265
+ };
22266
+ const changesSince = async (cursor2, pending2) => {
22267
+ const records = [];
22268
+ const failed = /* @__PURE__ */ new Set();
22269
+ const collect = (page) => {
22270
+ warnFailed(page.failed);
22271
+ records.push(...page.items);
22272
+ for (const failure of page.failed) failed.add(failure.memory_id);
22273
+ };
22274
+ let resume = cursor2;
22275
+ let next;
22276
+ do {
22277
+ const page = await persistence.query({
22278
+ ...everyState,
22279
+ order: "changed",
22280
+ limit: 200,
22281
+ ...(next ?? resume) && { cursor: next ?? resume }
22282
+ });
22283
+ collect(page);
22284
+ resume = page.changes_cursor ?? resume;
22285
+ next = page.next_cursor;
22286
+ } while (next);
22287
+ for (const memory_ids of chunks([...pending2], MAX_QUERY_IDS)) {
22288
+ let retry;
22289
+ do {
22290
+ const page = await persistence.query({
22291
+ ...everyState,
22292
+ memory_ids,
22293
+ limit: 200,
22294
+ ...retry && { cursor: retry }
22295
+ });
22296
+ collect(page);
22297
+ retry = page.next_cursor;
22298
+ } while (retry);
22299
+ }
22300
+ return { records, resume, failed };
22301
+ };
22302
+ let generation = 0;
22303
+ let ready = false;
22304
+ let cursor;
22305
+ let pending = /* @__PURE__ */ new Set();
22306
+ let polling = false;
22307
+ const poll = () => {
22308
+ if (polling) return;
22309
+ polling = true;
22310
+ const current = generation;
22311
+ changesSince(cursor, pending).then(({ records, resume, failed }) => {
22312
+ if (current !== generation) return;
22313
+ const changed = /* @__PURE__ */ new Set();
22314
+ for (const record2 of records) {
22315
+ const id = record2.memory.memory_id;
22316
+ const previous = seen.get(id);
22317
+ seen.set(id, record2);
22318
+ if (!ready) continue;
22319
+ for (const subscriber of subscribers) {
22320
+ const before = previous && subscriptionKey(previous, subscriber.options);
22321
+ if (before !== subscriptionKey(record2, subscriber.options)) changed.add(subscriber);
22322
+ }
22323
+ }
22324
+ ready = true;
22325
+ cursor = resume;
22326
+ pending = failed;
22327
+ for (const subscriber of changed)
22328
+ if (subscribers.has(subscriber)) safely(subscriber.onChange);
22329
+ }).catch((error) => {
22330
+ getLogger().warn("[memory/remote-store] Subscription poll failed:", error);
22331
+ }).finally(() => {
22332
+ polling = false;
22333
+ });
22334
+ };
22335
+ return {
22336
+ list: async (listOptions = {}) => {
22337
+ const order = listOptions.since ? "updated" : "created";
22338
+ const filters = {
22339
+ ...stateFilters(listOptions),
22340
+ include_embeddings: true,
22341
+ order,
22342
+ ...listOptions.scopes?.length && { scopes: listOptions.scopes },
22343
+ ...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
22344
+ ...listOptions.visibility?.length && { visibility: listOptions.visibility },
22345
+ ...listOptions.since && { updated_after: listOptions.since.getTime() }
22346
+ };
22347
+ const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
22348
+ const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
22349
+ if (!listOptions.memoryIds && variants.length === 1)
22350
+ return (await enumerate(filters, max)).map((r) => stored(r.memory));
22351
+ const fetched = await Promise.all(
22352
+ variants.map(
22353
+ (variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
22354
+ )
22355
+ );
22356
+ const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
22357
+ (a, b) => order === "updated" ? b.updatedAt.getTime() - a.updatedAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1) : b.createdAt.getTime() - a.createdAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1)
22358
+ );
22359
+ return rows.slice(0, max);
22360
+ },
22361
+ get: async (id) => asStored(await live(id)),
22362
+ listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
22363
+ (record2) => stored(record2.memory)
22364
+ ),
22365
+ memoriesByTopics: async (names) => {
22366
+ const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
22367
+ const out = /* @__PURE__ */ new Map();
22368
+ const pages = await Promise.all(
22369
+ chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
22370
+ );
22371
+ for (const { memory } of pages.flat()) {
22372
+ const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
22373
+ if (matched.length) out.set(memory.memory_id, new Set(matched));
22374
+ }
22375
+ return out;
22376
+ },
22377
+ topicsByMemories: async (memoryIds) => {
22378
+ const out = /* @__PURE__ */ new Map();
22379
+ for (const { memory } of await enumerateIds(memoryIds, {
22380
+ include_archived: true,
22381
+ include_superseded: true,
22382
+ include_quarantined: true
22383
+ })) {
22384
+ const topics = canonicalTopics(memory);
22385
+ if (topics.size) out.set(memory.memory_id, topics);
22386
+ }
22387
+ return out;
22388
+ },
22389
+ create: async (input) => {
22390
+ const record2 = await persistence.put(newRow(input), 0);
22391
+ return created([record2], [input])[0];
22392
+ },
22393
+ createMany: async (inputs) => {
22394
+ const out = [];
22395
+ for (const batch of chunks(inputs, MAX_BATCH)) {
22396
+ let records;
22397
+ try {
22398
+ records = await persistence.putMany(
22399
+ batch.map((input) => ({ memory: newRow(input), expectedVersion: 0 }))
22400
+ );
22401
+ } catch (error) {
22402
+ if (out.length === 0) throw error;
22403
+ throw new RemoteMemoryPartialCreateError(out, error);
22404
+ }
22405
+ out.push(...created(records, batch));
22406
+ }
22407
+ return out;
22408
+ },
22409
+ update: async (id, patch) => {
22410
+ const saved = await mutate(id, "edit", (memory) => {
22411
+ if (memory.superseded_by) return null;
22412
+ memory.content = patch.content;
22413
+ memory.updated_at = Date.now();
22414
+ if (patch.scope !== void 0) {
22415
+ memory.level = levelForScopeChange(
22416
+ { level: memory.level, scope: memory.scope },
22417
+ patch.scope
22418
+ );
22419
+ memory.scope = patch.scope;
22420
+ }
22421
+ if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
22422
+ if (patch.eventTime !== void 0) {
22423
+ memory.event_time_start = patch.eventTime?.start ?? void 0;
22424
+ memory.event_time_end = patch.eventTime?.end ?? void 0;
22425
+ memory.event_time_kind = patch.eventTime?.kind ?? void 0;
22426
+ }
22427
+ if (patch.embedding === void 0 || patch.embedding === null) {
22428
+ memory.embedding = [];
22429
+ delete memory.embedding_model;
22430
+ } else {
22431
+ memory.embedding = storedVector(JSON.parse(patch.embedding));
22432
+ memory.embedding_model = patch.embeddingModel ?? model;
22433
+ }
22434
+ return memory;
22435
+ });
22436
+ if (saved && patch.embedding === void 0) embedInBackground(saved);
22437
+ return asStored(saved);
22438
+ },
22439
+ delete: async (id) => !!await mutate(id, "membership", (memory) => ({ ...memory, is_deleted: true })),
22440
+ supersede: async (id, supersededById) => {
22441
+ if (id === supersededById) return false;
22442
+ const [first, second] = [id, supersededById].sort();
22443
+ return serialized(
22444
+ first,
22445
+ () => serialized(second, async () => {
22446
+ const [old, next] = await Promise.all([live(id), live(supersededById)]);
22447
+ if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
22448
+ if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
22449
+ const saved = await persistence.putMany([
22450
+ {
22451
+ memory: { ...old.memory, superseded_by: supersededById, superseded_at: Date.now() },
22452
+ expectedVersion: old
22453
+ },
22454
+ { memory: next.memory, expectedVersion: next }
22455
+ ]);
22456
+ notify("membership", saved);
22457
+ return true;
22458
+ })
22459
+ );
22460
+ },
22461
+ archive: async (id) => !!await mutate(
22462
+ id,
22463
+ "edit",
22464
+ (memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
22465
+ ),
22466
+ restore: (id) => serialized(id, async () => {
22467
+ const record2 = await live(id);
22468
+ if (!record2) return false;
22469
+ if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
22470
+ return true;
22471
+ const { archived_at: _archivedAt, ...memory } = record2.memory;
22472
+ notify("edit", [await persistence.put(memory, record2)]);
22473
+ return true;
22474
+ }),
22475
+ setTopics: async (memoryId, topics) => asStored(
22476
+ await mutate(memoryId, "edit", (memory) => ({
22477
+ ...memory,
22478
+ topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
22479
+ topics_user_managed: true,
22480
+ topics_updated_at: Date.now()
22481
+ }))
22482
+ ),
22483
+ addTopics: async (memoryId, topics) => {
22484
+ const added = topicInputs(topics, "auto");
22485
+ const saved = await mutate(memoryId, "edit", (memory) => ({
22486
+ ...memory,
22487
+ topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
22488
+ topics_updated_at: Date.now()
22489
+ }));
22490
+ if (!saved) return [];
22491
+ const now = /* @__PURE__ */ new Date();
22492
+ return mergeTopics([], added).map(
22493
+ (topic) => ({
22494
+ uniqueId: normalizeEntityName(topic.name),
22495
+ canonicalName: normalizeEntityName(topic.name),
22496
+ kind: topic.kind ?? null,
22497
+ createdAt: now,
22498
+ updatedAt: now
22499
+ })
22500
+ );
22501
+ },
22502
+ setVisibility: async (id, visibility, visibilityOptions) => asStored(
22503
+ await mutate(id, "edit", (memory) => {
22504
+ memory.visibility = visibility;
22505
+ if (visibility === "private") delete memory.published_at;
22506
+ else memory.published_at ?? (memory.published_at = Date.now());
22507
+ if (visibilityOptions?.twinOptIn !== void 0)
22508
+ memory.twin_opt_in = visibilityOptions.twinOptIn;
22509
+ return memory;
22510
+ })
22511
+ ),
22512
+ recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
22513
+ retain: async (content, retainOptions) => {
22514
+ const result = await pipeline.retain(content, retainOptions);
22515
+ if (result.action === "create" || result.action === "supersede") notify("membership");
22516
+ else if (result.action === "update" || result.action === "merge") notify("edit");
22517
+ return result;
22518
+ },
22519
+ subscribe: (onChange, subscribeOptions = {}) => {
22520
+ const subscriber = { onChange, options: subscribeOptions };
22521
+ subscribers.add(subscriber);
22522
+ if (pollIntervalMs > 0 && !timer) {
22523
+ timer = setInterval(poll, pollIntervalMs);
22524
+ poll();
22525
+ }
22526
+ return () => {
22527
+ subscribers.delete(subscriber);
22528
+ if (subscribers.size || !timer) return;
22529
+ clearInterval(timer);
22530
+ timer = void 0;
22531
+ generation++;
22532
+ seen.clear();
22533
+ ready = false;
22534
+ cursor = void 0;
22535
+ pending = /* @__PURE__ */ new Set();
22536
+ };
22537
+ }
22538
+ };
22539
+ }
22540
+
21946
22541
  // src/lib/memory/synthesizeProfile.ts
21947
22542
  var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
21948
22543
  var DEFAULT_FACET_RECALL_LIMIT = 20;
@@ -35924,6 +36519,7 @@ export {
35924
36519
  MEMORY_KINDS,
35925
36520
  MEMORY_LEVELS,
35926
36521
  MemoryEntity as MemoryEntityModel,
36522
+ MemoryKeyError,
35927
36523
  MemoryLevelError,
35928
36524
  NEVER_TTL_MS,
35929
36525
  NODE_BUDGET,
@@ -35938,6 +36534,7 @@ export {
35938
36534
  RECALL_MAX_LIMIT,
35939
36535
  RECALL_TOOL_NAME,
35940
36536
  RemoteMemoryError,
36537
+ RemoteMemoryPartialCreateError,
35941
36538
  RerankerUnavailableError,
35942
36539
  SDK_SCHEMA_VERSION,
35943
36540
  SERVER_TOOL_DEPENDENCY_SETS,
@@ -36031,6 +36628,7 @@ export {
36031
36628
  createRecallTool,
36032
36629
  createRemoteMemoryPersistence,
36033
36630
  createRemoteMemoryPipeline,
36631
+ createRemoteMemoryStore,
36034
36632
  createSavedToolOp,
36035
36633
  createServerToolsFilter,
36036
36634
  createStockPricePreProcessor,
@@ -36062,6 +36660,7 @@ export {
36062
36660
  deleteVaultMemoryOp,
36063
36661
  dequantizeEmbedding,
36064
36662
  deriveKeyFromSignatureBytes,
36663
+ deriveMemoryKeyRing,
36065
36664
  eagerEmbedContent,
36066
36665
  embedAllMessages,
36067
36666
  embedMessage,
@@ -36201,6 +36800,7 @@ export {
36201
36800
  linkMemoryEntitiesOp,
36202
36801
  maskScopedEmbeddingCache,
36203
36802
  mediaToStored,
36803
+ memoryCipher,
36204
36804
  migrateCalendarToken,
36205
36805
  migrateDisplayResult,
36206
36806
  migrateDriveToken,
@@ -36222,6 +36822,7 @@ export {
36222
36822
  rankProfileCandidates,
36223
36823
  readEncryptedFile,
36224
36824
  recall,
36825
+ reencryptMemoryField,
36225
36826
  reflect,
36226
36827
  refreshCalendarToken,
36227
36828
  refreshDriveToken,