@anuma/sdk 8.0.1 → 8.1.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.
@@ -458,7 +458,7 @@ ${appendix}` : appendix;
458
458
  }
459
459
 
460
460
  // src/lib/db/chat/operations.ts
461
- import { Q } from "@nozbe/watermelondb";
461
+ import { Q as Q2 } from "@nozbe/watermelondb";
462
462
  import { v7 as uuidv72 } from "uuid";
463
463
 
464
464
  // src/react/useEncryption.ts
@@ -1666,6 +1666,118 @@ async function assembleDecryptedMessage(message, address) {
1666
1666
  return result;
1667
1667
  }
1668
1668
 
1669
+ // src/lib/db/chat/toolCallEventIndex.ts
1670
+ import { Q } from "@nozbe/watermelondb";
1671
+ function parseEventIds(value) {
1672
+ const ids = /* @__PURE__ */ new Set();
1673
+ let events;
1674
+ try {
1675
+ events = typeof value === "string" ? JSON.parse(value) : value;
1676
+ } catch {
1677
+ return ids;
1678
+ }
1679
+ if (!Array.isArray(events)) return ids;
1680
+ for (const event of events) {
1681
+ if (!event || typeof event !== "object") continue;
1682
+ const id = event.id;
1683
+ if (typeof id === "string" && id) ids.add(id);
1684
+ }
1685
+ return ids;
1686
+ }
1687
+ async function fetchEventRows(collection, conversationId) {
1688
+ try {
1689
+ return await collection.query(
1690
+ Q.unsafeSqlQuery(
1691
+ `select "id", "tool_call_events" from "history" where "conversation_id" = ? and "_status" != 'deleted' and "tool_call_events" is not null and "tool_call_events" not in ('', '[]')`,
1692
+ [conversationId]
1693
+ )
1694
+ ).unsafeFetchRaw();
1695
+ } catch (error) {
1696
+ if (!(error instanceof Error) || !/unsafeSqlQuery.*not supported/.test(error.message)) {
1697
+ throw error;
1698
+ }
1699
+ return await collection.query(
1700
+ Q.where("conversation_id", conversationId),
1701
+ Q.where("tool_call_events", Q.notEq(null)),
1702
+ Q.where("tool_call_events", Q.notIn(["", "[]"])),
1703
+ Q.unsafeLokiTransform(
1704
+ (rows) => rows.map(({ id, tool_call_events }) => ({ id, tool_call_events }))
1705
+ )
1706
+ ).unsafeFetchRaw();
1707
+ }
1708
+ }
1709
+ var ToolCallEventIndex = class {
1710
+ constructor(collection) {
1711
+ this.collection = collection;
1712
+ this.conversations = /* @__PURE__ */ new Map();
1713
+ this.messages = /* @__PURE__ */ new Map();
1714
+ this.pending = /* @__PURE__ */ new Map();
1715
+ this.resetCount = collection.database._resetCount;
1716
+ collection.experimentalSubscribe((changes) => {
1717
+ for (const { record: record2, type } of changes) {
1718
+ this.replace(
1719
+ record2.id,
1720
+ type === "destroyed" ? void 0 : record2.conversationId,
1721
+ type === "destroyed" ? void 0 : record2._getRaw("tool_call_events")
1722
+ );
1723
+ }
1724
+ });
1725
+ }
1726
+ replace(messageId, conversationId, value) {
1727
+ const previous = this.messages.get(messageId);
1728
+ if (previous) {
1729
+ const counts2 = this.conversations.get(previous.conversationId);
1730
+ for (const id of previous.ids) {
1731
+ const count2 = counts2.get(id) - 1;
1732
+ if (count2 === 0) counts2.delete(id);
1733
+ else counts2.set(id, count2);
1734
+ }
1735
+ this.messages.delete(messageId);
1736
+ }
1737
+ const counts = conversationId === void 0 ? void 0 : this.conversations.get(conversationId);
1738
+ if (!counts || conversationId === void 0) return;
1739
+ const ids = parseEventIds(value);
1740
+ if (ids.size === 0) return;
1741
+ this.messages.set(messageId, { conversationId, ids });
1742
+ for (const id of ids) counts.set(id, (counts.get(id) ?? 0) + 1);
1743
+ }
1744
+ async get(conversationId) {
1745
+ if (this.resetCount !== this.collection.database._resetCount) {
1746
+ this.conversations.clear();
1747
+ this.messages.clear();
1748
+ this.pending.clear();
1749
+ this.resetCount = this.collection.database._resetCount;
1750
+ }
1751
+ if (!this.conversations.has(conversationId)) {
1752
+ let pending = this.pending.get(conversationId);
1753
+ if (!pending) {
1754
+ pending = this.collection.database.read(async () => {
1755
+ const rows = await fetchEventRows(this.collection, conversationId);
1756
+ this.conversations.set(conversationId, /* @__PURE__ */ new Map());
1757
+ for (const row of rows)
1758
+ this.replace(String(row.id), conversationId, row.tool_call_events);
1759
+ });
1760
+ this.pending.set(conversationId, pending);
1761
+ }
1762
+ try {
1763
+ await pending;
1764
+ } finally {
1765
+ this.pending.delete(conversationId);
1766
+ }
1767
+ }
1768
+ return new Set(this.conversations.get(conversationId).keys());
1769
+ }
1770
+ };
1771
+ var indexes = /* @__PURE__ */ new WeakMap();
1772
+ function getToolCallEventIds(collection, conversationId) {
1773
+ let index = indexes.get(collection);
1774
+ if (!index) {
1775
+ index = new ToolCallEventIndex(collection);
1776
+ indexes.set(collection, index);
1777
+ }
1778
+ return index.get(conversationId);
1779
+ }
1780
+
1669
1781
  // src/lib/db/chat/types.ts
1670
1782
  import { v7 as uuidv7 } from "uuid";
1671
1783
 
@@ -2058,7 +2170,7 @@ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation"
2058
2170
  );
2059
2171
  }
2060
2172
  async function getConversationOp(ctx, id) {
2061
- const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
2173
+ const results = await ctx.conversationsCollection.query(Q2.where("conversation_id", id), Q2.where("is_deleted", false)).fetch();
2062
2174
  return results.length > 0 ? await conversationToStored(
2063
2175
  results[0],
2064
2176
  ctx.walletAddress,
@@ -2067,7 +2179,7 @@ async function getConversationOp(ctx, id) {
2067
2179
  ) : null;
2068
2180
  }
2069
2181
  async function getConversationsOp(ctx) {
2070
- const results = await ctx.conversationsCollection.query(Q.where("is_deleted", false), Q.sortBy("created_at", Q.desc)).unsafeFetchRaw();
2182
+ const results = await ctx.conversationsCollection.query(Q2.where("is_deleted", false), Q2.sortBy("created_at", Q2.desc)).unsafeFetchRaw();
2071
2183
  return Promise.all(
2072
2184
  results.map(
2073
2185
  (raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
@@ -2088,33 +2200,33 @@ function conversationRawToLazyStored(raw) {
2088
2200
  };
2089
2201
  }
2090
2202
  async function getConversationsLazyOp(ctx) {
2091
- const results = await ctx.conversationsCollection.query(Q.where("is_deleted", false), Q.sortBy("created_at", Q.desc)).unsafeFetchRaw();
2203
+ const results = await ctx.conversationsCollection.query(Q2.where("is_deleted", false), Q2.sortBy("created_at", Q2.desc)).unsafeFetchRaw();
2092
2204
  return results.map(conversationRawToLazyStored);
2093
2205
  }
2094
2206
  async function getConversationsPageOp(ctx, options) {
2095
2207
  const limit = Math.floor(options?.limit ?? 200);
2096
2208
  if (!Number.isFinite(limit) || limit < 1) return [];
2097
2209
  const exclude = new Set(options?.boundaryExcludeUniqueIds ?? []);
2098
- const clauses = [Q.where("is_deleted", false)];
2210
+ const clauses = [Q2.where("is_deleted", false)];
2099
2211
  if (options?.before !== void 0) {
2100
2212
  clauses.push(
2101
- exclude.size > 0 ? Q.where("created_at", Q.lte(options.before)) : Q.where("created_at", Q.lt(options.before))
2213
+ exclude.size > 0 ? Q2.where("created_at", Q2.lte(options.before)) : Q2.where("created_at", Q2.lt(options.before))
2102
2214
  );
2103
2215
  }
2104
- const fetched = await ctx.conversationsCollection.query(...clauses, Q.sortBy("created_at", Q.desc), Q.take(limit + exclude.size)).unsafeFetchRaw();
2216
+ const fetched = await ctx.conversationsCollection.query(...clauses, Q2.sortBy("created_at", Q2.desc), Q2.take(limit + exclude.size)).unsafeFetchRaw();
2105
2217
  const results = exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched;
2106
2218
  return results.slice(0, limit).map(conversationRawToLazyStored);
2107
2219
  }
2108
2220
  async function getConversationsByProjectLazyOp(ctx, projectId) {
2109
2221
  const results = await ctx.conversationsCollection.query(
2110
- Q.where("project_id", projectId === null ? "" : projectId),
2111
- Q.where("is_deleted", false),
2112
- Q.sortBy("created_at", Q.desc)
2222
+ Q2.where("project_id", projectId === null ? "" : projectId),
2223
+ Q2.where("is_deleted", false),
2224
+ Q2.sortBy("created_at", Q2.desc)
2113
2225
  ).unsafeFetchRaw();
2114
2226
  return results.map(conversationRawToLazyStored);
2115
2227
  }
2116
2228
  async function updateConversationTitleOp(ctx, id, title) {
2117
- const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
2229
+ const results = await ctx.conversationsCollection.query(Q2.where("conversation_id", id), Q2.where("is_deleted", false)).fetch();
2118
2230
  if (results.length > 0) {
2119
2231
  const encryptedOpts = ctx.walletAddress && ctx.signMessage ? await encryptConversationFields(
2120
2232
  { title },
@@ -2133,13 +2245,13 @@ async function updateConversationTitleOp(ctx, id, title) {
2133
2245
  return false;
2134
2246
  }
2135
2247
  async function deleteConversationOp(ctx, id) {
2136
- const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
2248
+ const results = await ctx.conversationsCollection.query(Q2.where("conversation_id", id), Q2.where("is_deleted", false)).fetch();
2137
2249
  if (results.length > 0) {
2138
2250
  await ctx.database.write(async () => {
2139
2251
  await results[0].update((conv) => {
2140
2252
  conv._setRaw("is_deleted", true);
2141
2253
  });
2142
- const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q.where("conversation_id", id)).fetch() : [];
2254
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q2.where("conversation_id", id)).fetch() : [];
2143
2255
  for (const job of jobs) await job.destroyPermanently();
2144
2256
  });
2145
2257
  return true;
@@ -2147,7 +2259,7 @@ async function deleteConversationOp(ctx, id) {
2147
2259
  return false;
2148
2260
  }
2149
2261
  async function updateConversationPinnedOp(ctx, id, pinned) {
2150
- const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
2262
+ const results = await ctx.conversationsCollection.query(Q2.where("conversation_id", id), Q2.where("is_deleted", false)).fetch();
2151
2263
  if (results.length > 0) {
2152
2264
  await ctx.database.write(async () => {
2153
2265
  await results[0].update((conv) => {
@@ -2159,7 +2271,7 @@ async function updateConversationPinnedOp(ctx, id, pinned) {
2159
2271
  return false;
2160
2272
  }
2161
2273
  async function getMessagesOp(ctx, convId, opts) {
2162
- const fetched = await ctx.messagesCollection.query(Q.where("conversation_id", convId), Q.sortBy("message_id", Q.asc)).unsafeFetchRaw();
2274
+ const fetched = await ctx.messagesCollection.query(Q2.where("conversation_id", convId), Q2.sortBy("message_id", Q2.asc)).unsafeFetchRaw();
2163
2275
  const results = opts?.rawFilter ? fetched.filter(opts.rawFilter) : fetched;
2164
2276
  return Promise.all(
2165
2277
  results.map(
@@ -2168,19 +2280,19 @@ async function getMessagesOp(ctx, convId, opts) {
2168
2280
  );
2169
2281
  }
2170
2282
  async function getMessageCountOp(ctx, convId) {
2171
- return await ctx.messagesCollection.query(Q.where("conversation_id", convId)).fetchCount();
2283
+ return await ctx.messagesCollection.query(Q2.where("conversation_id", convId)).fetchCount();
2172
2284
  }
2173
2285
  async function getMessagesPageOp(ctx, convId, opts) {
2174
2286
  const limit = Math.floor(opts.limit);
2175
2287
  if (!Number.isFinite(limit) || limit < 1) return [];
2176
2288
  const exclude = new Set(opts.boundaryExcludeUniqueIds ?? []);
2177
- const clauses = [Q.where("conversation_id", convId)];
2289
+ const clauses = [Q2.where("conversation_id", convId)];
2178
2290
  if (opts.beforeMessageId !== void 0) {
2179
2291
  clauses.push(
2180
- exclude.size > 0 ? Q.where("message_id", Q.lte(opts.beforeMessageId)) : Q.where("message_id", Q.lt(opts.beforeMessageId))
2292
+ exclude.size > 0 ? Q2.where("message_id", Q2.lte(opts.beforeMessageId)) : Q2.where("message_id", Q2.lt(opts.beforeMessageId))
2181
2293
  );
2182
2294
  }
2183
- const fetched = await ctx.messagesCollection.query(...clauses, Q.sortBy("message_id", Q.desc), Q.take(limit + exclude.size)).unsafeFetchRaw();
2295
+ const fetched = await ctx.messagesCollection.query(...clauses, Q2.sortBy("message_id", Q2.desc), Q2.take(limit + exclude.size)).unsafeFetchRaw();
2184
2296
  const results = (exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched).slice(0, limit);
2185
2297
  results.reverse();
2186
2298
  return Promise.all(
@@ -2192,7 +2304,7 @@ async function getMessagesPageOp(ctx, convId, opts) {
2192
2304
  );
2193
2305
  }
2194
2306
  async function getMessageSkeletonsOp(ctx, convId) {
2195
- const results = await ctx.messagesCollection.query(Q.where("conversation_id", convId), Q.sortBy("message_id", Q.asc)).unsafeFetchRaw();
2307
+ const results = await ctx.messagesCollection.query(Q2.where("conversation_id", convId), Q2.sortBy("message_id", Q2.asc)).unsafeFetchRaw();
2196
2308
  const roleById = /* @__PURE__ */ new Map();
2197
2309
  for (const raw of results) {
2198
2310
  roleById.set(raw.id, raw.role);
@@ -2237,32 +2349,12 @@ async function getMessageSkeletonsOp(ctx, convId) {
2237
2349
  return skeletons;
2238
2350
  }
2239
2351
  async function getToolCallEventIdsOp(ctx, convId) {
2240
- const results = await ctx.messagesCollection.query(Q.where("conversation_id", convId)).unsafeFetchRaw();
2241
- const ids = /* @__PURE__ */ new Set();
2242
- for (const raw of results) {
2243
- const value = raw.tool_call_events;
2244
- if (!value) continue;
2245
- let events;
2246
- if (typeof value === "string") {
2247
- try {
2248
- events = JSON.parse(value);
2249
- } catch {
2250
- continue;
2251
- }
2252
- } else if (Array.isArray(value)) {
2253
- events = value;
2254
- }
2255
- if (!Array.isArray(events)) continue;
2256
- for (const evt of events) {
2257
- if (evt && evt.id) ids.add(evt.id);
2258
- }
2259
- }
2260
- return ids;
2352
+ return getToolCallEventIds(ctx.messagesCollection, convId);
2261
2353
  }
2262
2354
  async function clearMessagesOp(ctx, convId) {
2263
2355
  await ctx.database.write(async () => {
2264
- const messages = await ctx.messagesCollection.query(Q.where("conversation_id", convId)).fetch();
2265
- const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q.where("conversation_id", convId)).fetch() : [];
2356
+ const messages = await ctx.messagesCollection.query(Q2.where("conversation_id", convId)).fetch();
2357
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q2.where("conversation_id", convId)).fetch() : [];
2266
2358
  for (const job of jobs) {
2267
2359
  await job.update((row) => {
2268
2360
  row._setRaw("message_ids", "[]");
@@ -2287,7 +2379,7 @@ async function deleteMessageOp(ctx, uniqueId) {
2287
2379
  return null;
2288
2380
  }
2289
2381
  await ctx.database.write(async () => {
2290
- const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q.where("conversation_id", message.conversationId)).fetch() : [];
2382
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q2.where("conversation_id", message.conversationId)).fetch() : [];
2291
2383
  for (const job of jobs) {
2292
2384
  const ids = JSON.parse(String(job._getRaw("message_ids")));
2293
2385
  await job.update((row) => {
@@ -2360,9 +2452,9 @@ async function createMessageOp(ctx, opts) {
2360
2452
  }
2361
2453
  }
2362
2454
  const newest = await ctx.messagesCollection.query(
2363
- Q.where("conversation_id", opts.conversationId),
2364
- Q.sortBy("message_id", Q.desc),
2365
- Q.take(1)
2455
+ Q2.where("conversation_id", opts.conversationId),
2456
+ Q2.sortBy("message_id", Q2.desc),
2457
+ Q2.take(1)
2366
2458
  ).fetch();
2367
2459
  const messageId = (newest[0]?.messageId ?? 0) + 1;
2368
2460
  const encryptedOpts = await encryptMessageOptsIfNeeded(ctx, opts);
@@ -2376,7 +2468,7 @@ async function createMessageOp(ctx, opts) {
2376
2468
  return messageToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
2377
2469
  }
2378
2470
  async function upsertMessageOp(ctx, opts) {
2379
- const results = await ctx.messagesCollection.query(Q.where("id", opts.uniqueId)).fetch();
2471
+ const results = await ctx.messagesCollection.query(Q2.where("id", opts.uniqueId)).fetch();
2380
2472
  const existing = results.length > 0 ? results[0] : null;
2381
2473
  if (!existing) {
2382
2474
  return createMessageOp(ctx, opts);
@@ -2484,13 +2576,13 @@ async function decryptMessageEmbeddingFields(raw, walletAddress) {
2484
2576
  async function sealLegacyMessageEmbeddingsOp(ctx) {
2485
2577
  if (!ctx.walletAddress) return 0;
2486
2578
  const candidateIds = await ctx.messagesCollection.query(
2487
- Q.where("content", Q.like("enc:%")),
2488
- Q.or(
2579
+ Q2.where("content", Q2.like("enc:%")),
2580
+ Q2.or(
2489
2581
  ...["vector", "chunks"].map(
2490
- (column) => Q.and(
2491
- Q.where(column, Q.notEq(null)),
2492
- Q.where(column, Q.notEq("")),
2493
- Q.where(column, Q.notLike("enc:%"))
2582
+ (column) => Q2.and(
2583
+ Q2.where(column, Q2.notEq(null)),
2584
+ Q2.where(column, Q2.notEq("")),
2585
+ Q2.where(column, Q2.notLike("enc:%"))
2494
2586
  )
2495
2587
  )
2496
2588
  )
@@ -2500,7 +2592,7 @@ async function sealLegacyMessageEmbeddingsOp(ctx) {
2500
2592
  for (let start = 0; start < candidateIds.length; start += 50) {
2501
2593
  const pageIds = candidateIds.slice(start, start + 50);
2502
2594
  await ctx.database.write(async () => {
2503
- const pageMessages = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(pageIds))).fetch();
2595
+ const pageMessages = await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf(pageIds))).fetch();
2504
2596
  for (const message of pageMessages) {
2505
2597
  if (!isEncrypted(message.content)) continue;
2506
2598
  const content = await decryptFieldDetailed(message.content, ctx.walletAddress);
@@ -2581,15 +2673,15 @@ function chunksWithoutText(raw) {
2581
2673
  });
2582
2674
  }
2583
2675
  async function stripLegacyChunkTextOp(ctx) {
2584
- const candidateIds = await ctx.messagesCollection.query(Q.where("chunks", Q.like(`%${Q.sanitizeLikeString('"text":')}%`))).fetchIds();
2676
+ const candidateIds = await ctx.messagesCollection.query(Q2.where("chunks", Q2.like(`%${Q2.sanitizeLikeString('"text":')}%`))).fetchIds();
2585
2677
  let stripped = 0;
2586
2678
  for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
2587
2679
  const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
2588
- const rows = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(pageIds))).unsafeFetchRaw();
2680
+ const rows = await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf(pageIds))).unsafeFetchRaw();
2589
2681
  const changedIds = rows.filter((row) => chunksWithoutText(row.chunks) !== null).map((row) => String(row.id));
2590
2682
  if (changedIds.length === 0) continue;
2591
2683
  await ctx.database.write(async () => {
2592
- const messages = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(changedIds))).fetch();
2684
+ const messages = await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf(changedIds))).fetch();
2593
2685
  const updates = messages.flatMap((message) => {
2594
2686
  const raw = message._raw;
2595
2687
  const chunks3 = chunksWithoutText(raw.chunks);
@@ -2636,13 +2728,13 @@ async function encryptToolCallEventsOp(ctx) {
2636
2728
  return 0;
2637
2729
  }
2638
2730
  const candidateIds = await ctx.messagesCollection.query(
2639
- Q.where("tool_call_events", Q.notEq(null)),
2640
- Q.where("tool_call_events", Q.notIn(["", "[]"]))
2731
+ Q2.where("tool_call_events", Q2.notEq(null)),
2732
+ Q2.where("tool_call_events", Q2.notIn(["", "[]"]))
2641
2733
  ).fetchIds();
2642
2734
  let encrypted = 0;
2643
2735
  for (let start = 0; start < candidateIds.length; start += RAW_REPAIR_PAGE_SIZE) {
2644
2736
  const pageIds = candidateIds.slice(start, start + RAW_REPAIR_PAGE_SIZE);
2645
- const rows = await ctx.messagesCollection.query(Q.where("id", Q.oneOf(pageIds))).unsafeFetchRaw();
2737
+ const rows = await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf(pageIds))).unsafeFetchRaw();
2646
2738
  const repairs = /* @__PURE__ */ new Map();
2647
2739
  for (const row of rows) {
2648
2740
  const column = await encryptedToolCallEventsColumn(
@@ -2655,12 +2747,12 @@ async function encryptToolCallEventsOp(ctx) {
2655
2747
  }
2656
2748
  if (repairs.size === 0) continue;
2657
2749
  await ctx.database.write(async () => {
2658
- const messages = (await ctx.messagesCollection.query(Q.where("id", Q.oneOf([...repairs.keys()]))).fetch()).filter(
2750
+ const messages = (await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf([...repairs.keys()]))).fetch()).filter(
2659
2751
  (message) => message._raw.tool_call_events === repairs.get(message.id)?.raw
2660
2752
  );
2661
2753
  if (messages.length === 0) return;
2662
2754
  const conversationIds = [...new Set(messages.map((message) => message.conversationId))];
2663
- const conversations = await ctx.conversationsCollection.query(Q.where("conversation_id", Q.oneOf(conversationIds))).fetch();
2755
+ const conversations = await ctx.conversationsCollection.query(Q2.where("conversation_id", Q2.oneOf(conversationIds))).fetch();
2664
2756
  await ctx.database.batch(
2665
2757
  ...messages.map(
2666
2758
  (message) => message.prepareUpdate((msg) => {
@@ -2687,7 +2779,7 @@ async function savedKeyOpensExistingData(ctx, address, signMessage, embeddedWall
2687
2779
  return refreshEncryptionKeyIfMatches(address, v2Probe, signMessage, embeddedWalletSigner);
2688
2780
  }
2689
2781
  async function findEncryptedContent(ctx, pattern) {
2690
- const [row] = await ctx.messagesCollection.query(Q.where("content", Q.like(pattern)), Q.take(1)).unsafeFetchRaw();
2782
+ const [row] = await ctx.messagesCollection.query(Q2.where("content", Q2.like(pattern)), Q2.take(1)).unsafeFetchRaw();
2691
2783
  return row ? String(row.content) : null;
2692
2784
  }
2693
2785
  async function updateMessageErrorOp(ctx, uniqueId, error) {
@@ -2800,7 +2892,7 @@ function toChunkCandidateKey(raw) {
2800
2892
  }
2801
2893
  async function fetchRowsByIds(ctx, ids) {
2802
2894
  if (ids.length === 0) return [];
2803
- return await ctx.messagesCollection.query(Q.where("id", Q.oneOf(ids))).unsafeFetchRaw();
2895
+ return await ctx.messagesCollection.query(Q2.where("id", Q2.oneOf(ids))).unsafeFetchRaw();
2804
2896
  }
2805
2897
  async function projectedChunkRowSource(ctx, filter) {
2806
2898
  const clauses = [
@@ -2818,7 +2910,7 @@ async function projectedChunkRowSource(ctx, filter) {
2818
2910
  args.push(filter.excludeConversationId);
2819
2911
  }
2820
2912
  const keyRows = await ctx.messagesCollection.query(
2821
- Q.unsafeSqlQuery(
2913
+ Q2.unsafeSqlQuery(
2822
2914
  `select "id", "conversation_id", "updated_at", "embedding_model" from "history" where ${clauses.join(" and ")}`,
2823
2915
  args
2824
2916
  )
@@ -2828,7 +2920,7 @@ async function projectedChunkRowSource(ctx, filter) {
2828
2920
  loadVectorRows: async (ids) => {
2829
2921
  if (ids.length === 0) return [];
2830
2922
  return await ctx.messagesCollection.query(
2831
- Q.unsafeSqlQuery(
2923
+ Q2.unsafeSqlQuery(
2832
2924
  `select "id", "updated_at", "chunks", "vector" from "history" where "_status" is not 'deleted' and "id" in (${ids.map(() => "?").join(",")})`,
2833
2925
  ids
2834
2926
  )
@@ -2838,11 +2930,11 @@ async function projectedChunkRowSource(ctx, filter) {
2838
2930
  };
2839
2931
  }
2840
2932
  async function fullScanChunkRowSource(ctx, filter) {
2841
- const activeConversations = await ctx.conversationsCollection.query(Q.where("is_deleted", false)).fetch();
2933
+ const activeConversations = await ctx.conversationsCollection.query(Q2.where("is_deleted", false)).fetch();
2842
2934
  const activeConversationIds = new Set(
2843
2935
  activeConversations.map((c) => String(c._getRaw("conversation_id")))
2844
2936
  );
2845
- const queryConditions = filter.conversationId !== void 0 ? [Q.where("conversation_id", filter.conversationId)] : [];
2937
+ const queryConditions = filter.conversationId !== void 0 ? [Q2.where("conversation_id", filter.conversationId)] : [];
2846
2938
  const rows = await ctx.messagesCollection.query(...queryConditions).unsafeFetchRaw();
2847
2939
  const rowsById = /* @__PURE__ */ new Map();
2848
2940
  for (const row of rows) {
@@ -4755,6 +4847,17 @@ function missingConfirmFields(action, parameters) {
4755
4847
  return requirement.fields.filter((field10) => !shown.has(field10));
4756
4848
  }
4757
4849
 
4850
+ // src/tools/walletPaymentConstants.ts
4851
+ var SELECT_PAYMENT_WALLET_TOOL_NAME = "select_payment_wallet";
4852
+ var WALLET_PAYMENT_TOOL_NAME = "prompt_wallet_payment";
4853
+ var FLIGHT_BOOK_TOOL_SET = "flight-book";
4854
+ var FLIGHT_SERVER_TOOL_NAMES = [
4855
+ "AnumaPaymentsMCP-anuma_search_flights",
4856
+ "AnumaPaymentsMCP-anuma_flight_offer_details",
4857
+ "AnumaPaymentsMCP-anuma_create_flight_intent",
4858
+ "AnumaPaymentsMCP-anuma_get_flight_booking"
4859
+ ];
4860
+
4758
4861
  // src/lib/storage/mcpImages.ts
4759
4862
  var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
4760
4863
  "AnumaMediaMCP-anuma_create_image",
@@ -5450,7 +5553,8 @@ var BUILT_IN_TOOL_SETS = [
5450
5553
  "AnumaPaymentsMCP-anuma_cancel_reservation"
5451
5554
  ],
5452
5555
  anchors: []
5453
- }
5556
+ },
5557
+ { name: FLIGHT_BOOK_TOOL_SET, members: [...FLIGHT_SERVER_TOOL_NAMES], anchors: [] }
5454
5558
  ];
5455
5559
  var CONFIRMED_ACTION_TOOL_SETS = /* @__PURE__ */ new Map([
5456
5560
  ["book_restaurant", "restaurant-book"],
@@ -5582,6 +5686,16 @@ var SERVER_TOOL_DEPENDENCY_SETS = [
5582
5686
  members: ["AnumaPaymentsMCP-anuma_list_reservations"],
5583
5687
  anchors: ["AnumaPaymentsMCP-anuma_cancel_reservation"],
5584
5688
  anchorMinSimilarity: 0.5
5689
+ },
5690
+ {
5691
+ name: "flight-book-lookup",
5692
+ members: [
5693
+ "AnumaPaymentsMCP-anuma_flight_offer_details",
5694
+ "AnumaPaymentsMCP-anuma_create_flight_intent",
5695
+ "AnumaPaymentsMCP-anuma_get_flight_booking"
5696
+ ],
5697
+ anchors: ["AnumaPaymentsMCP-anuma_search_flights"],
5698
+ anchorMinSimilarity: 0.5
5585
5699
  }
5586
5700
  ];
5587
5701
  var defaultServerToolsFilter = createServerToolsFilter({
@@ -7843,7 +7957,14 @@ function getToolName(tool) {
7843
7957
  function toolsAfterConfirmation(apiTools, executionResults) {
7844
7958
  const members = /* @__PURE__ */ new Set();
7845
7959
  let keepConfirm = false;
7960
+ let keepPaymentTools = false;
7846
7961
  for (const r of executionResults) {
7962
+ if (r.name === SELECT_PAYMENT_WALLET_TOOL_NAME && r.result?.confirmed === true) {
7963
+ const flightSet = BUILT_IN_TOOL_SETS.find((s) => s.name === FLIGHT_BOOK_TOOL_SET);
7964
+ for (const member of flightSet?.members ?? []) members.add(member);
7965
+ keepPaymentTools = true;
7966
+ continue;
7967
+ }
7847
7968
  if (r.name !== CONFIRM_TOOL_NAME) continue;
7848
7969
  const answer = r.result;
7849
7970
  if (answer?.confirmed !== true || typeof answer.action !== "string") continue;
@@ -7855,7 +7976,7 @@ function toolsAfterConfirmation(apiTools, executionResults) {
7855
7976
  if (!apiTools.some((t) => members.has(getToolName(t) ?? ""))) return void 0;
7856
7977
  return apiTools.filter((t) => {
7857
7978
  const name = getToolName(t) ?? "";
7858
- return members.has(name) || name === TOOL_SEARCH_TOOL_NAME || keepConfirm && name === CONFIRM_TOOL_NAME;
7979
+ return members.has(name) || name === TOOL_SEARCH_TOOL_NAME || keepConfirm && name === CONFIRM_TOOL_NAME || keepPaymentTools && (name === SELECT_PAYMENT_WALLET_TOOL_NAME || name === WALLET_PAYMENT_TOOL_NAME);
7859
7980
  });
7860
7981
  }
7861
7982
  var STREAM_RESUMABLE_HEADER = "X-Stream-Resumable";
@@ -9671,7 +9792,7 @@ var chatStorageMigrations = schemaMigrations({
9671
9792
  });
9672
9793
 
9673
9794
  // src/lib/db/chat/summaryOperations.ts
9674
- import { Q as Q2 } from "@nozbe/watermelondb";
9795
+ import { Q as Q3 } from "@nozbe/watermelondb";
9675
9796
  function createSummaryContext(database) {
9676
9797
  return {
9677
9798
  database,
@@ -9690,14 +9811,14 @@ function modelToStored(record2) {
9690
9811
  };
9691
9812
  }
9692
9813
  async function getConversationSummaryOp(ctx, conversationId) {
9693
- const results = await ctx.summariesCollection.query(Q2.where("conversation_id", conversationId)).fetch();
9814
+ const results = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
9694
9815
  if (results.length === 0) return null;
9695
9816
  return modelToStored(results[0]);
9696
9817
  }
9697
9818
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
9698
9819
  let record2;
9699
9820
  await ctx.database.write(async () => {
9700
- const existing = await ctx.summariesCollection.query(Q2.where("conversation_id", conversationId)).fetch();
9821
+ const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
9701
9822
  if (existing.length > 0) {
9702
9823
  record2 = await existing[0].update((rec) => {
9703
9824
  rec.summary = summary;
@@ -9717,7 +9838,7 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
9717
9838
  }
9718
9839
  async function deleteConversationSummaryOp(ctx, conversationId) {
9719
9840
  await ctx.database.write(async () => {
9720
- const existing = await ctx.summariesCollection.query(Q2.where("conversation_id", conversationId)).fetch();
9841
+ const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
9721
9842
  for (const record2 of existing) {
9722
9843
  await record2.destroyPermanently();
9723
9844
  }
@@ -9772,7 +9893,7 @@ __decorateClass([
9772
9893
  ], ConversationMemory.prototype, "createdAt", 2);
9773
9894
 
9774
9895
  // src/lib/db/conversationMemory/operations.ts
9775
- import { Q as Q3 } from "@nozbe/watermelondb";
9896
+ import { Q as Q4 } from "@nozbe/watermelondb";
9776
9897
  var MAX_PER_CONVERSATION = 200;
9777
9898
  function conversationMemoryToStored(row) {
9778
9899
  return {
@@ -9787,7 +9908,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
9787
9908
  if (!conversationId || items.length === 0) return;
9788
9909
  const now = Date.now();
9789
9910
  await ctx.database.write(async () => {
9790
- const existing = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId), Q3.sortBy("created_at", Q3.asc)).fetch();
9911
+ const existing = await ctx.conversationMemoryCollection.query(Q4.where("conversation_id", conversationId), Q4.sortBy("created_at", Q4.asc)).fetch();
9791
9912
  const seen = new Set(existing.map((r) => r.memoryId));
9792
9913
  const batchSeen = /* @__PURE__ */ new Set();
9793
9914
  const deduped = [];
@@ -9817,13 +9938,13 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
9817
9938
  }
9818
9939
  async function getConversationMemoriesOp(ctx, conversationId) {
9819
9940
  if (!conversationId) return [];
9820
- const rows = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId), Q3.sortBy("created_at", Q3.asc)).fetch();
9941
+ const rows = await ctx.conversationMemoryCollection.query(Q4.where("conversation_id", conversationId), Q4.sortBy("created_at", Q4.asc)).fetch();
9821
9942
  return rows.map(conversationMemoryToStored);
9822
9943
  }
9823
9944
  async function clearConversationMemoriesOp(ctx, conversationId) {
9824
9945
  if (!conversationId) return;
9825
9946
  await ctx.database.write(async () => {
9826
- const rows = await ctx.conversationMemoryCollection.query(Q3.where("conversation_id", conversationId)).fetch();
9947
+ const rows = await ctx.conversationMemoryCollection.query(Q4.where("conversation_id", conversationId)).fetch();
9827
9948
  if (rows.length === 0) return;
9828
9949
  await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
9829
9950
  });
@@ -10229,6 +10350,9 @@ __decorateClass([
10229
10350
  __decorateClass([
10230
10351
  text11("personality")
10231
10352
  ], UserPreference.prototype, "personality", 2);
10353
+ __decorateClass([
10354
+ text11("external_wallets")
10355
+ ], UserPreference.prototype, "externalWallets", 2);
10232
10356
  __decorateClass([
10233
10357
  field8("created_at")
10234
10358
  ], UserPreference.prototype, "createdAt", 2);
@@ -10266,7 +10390,7 @@ __decorateClass([
10266
10390
  ], VaultFolder.prototype, "context", 2);
10267
10391
 
10268
10392
  // src/lib/db/schema.ts
10269
- var SDK_SCHEMA_VERSION = 48;
10393
+ var SDK_SCHEMA_VERSION = 49;
10270
10394
  var sdkSchema = appSchema2({
10271
10395
  version: SDK_SCHEMA_VERSION,
10272
10396
  tables: [
@@ -10352,6 +10476,7 @@ var sdkSchema = appSchema2({
10352
10476
  { name: "description", type: "string", isOptional: true },
10353
10477
  { name: "models", type: "string", isOptional: true },
10354
10478
  { name: "personality", type: "string", isOptional: true },
10479
+ { name: "external_wallets", type: "string", isOptional: true },
10355
10480
  { name: "created_at", type: "number" },
10356
10481
  { name: "updated_at", type: "number" }
10357
10482
  ]
@@ -11056,6 +11181,15 @@ var sdkMigrations = schemaMigrations2({
11056
11181
  "UPDATE memory_vault SET level = CASE WHEN scope IN ('shared', 'public') THEN 'matching' ELSE 'private' END WHERE level IS NULL;"
11057
11182
  )
11058
11183
  ]
11184
+ },
11185
+ {
11186
+ toVersion: 49,
11187
+ steps: [
11188
+ addColumns2({
11189
+ table: "userPreferences",
11190
+ columns: [{ name: "external_wallets", type: "string", isOptional: true }]
11191
+ })
11192
+ ]
11059
11193
  }
11060
11194
  ]
11061
11195
  });
@@ -11237,10 +11371,10 @@ var DatabaseManager = class {
11237
11371
  };
11238
11372
 
11239
11373
  // src/lib/db/memoryVault/operations.ts
11240
- import { Q as Q5 } from "@nozbe/watermelondb";
11374
+ import { Q as Q6 } from "@nozbe/watermelondb";
11241
11375
 
11242
11376
  // src/lib/db/entities/operations.ts
11243
- import { Q as Q4 } from "@nozbe/watermelondb";
11377
+ import { Q as Q5 } from "@nozbe/watermelondb";
11244
11378
 
11245
11379
  // src/lib/db/memoryVault/types.ts
11246
11380
  var MEMORY_KINDS = [
@@ -11333,7 +11467,7 @@ async function upsertEntitiesInWrite(ctx, entities) {
11333
11467
  const unique = Array.from(kindByName.keys());
11334
11468
  const out = /* @__PURE__ */ new Map();
11335
11469
  if (unique.length === 0) return { entities: out, operations: [], kindBackfills: [] };
11336
- const existing = await ctx.entityCollection.query(Q4.where("canonical_name", Q4.oneOf(unique))).fetch();
11470
+ const existing = await ctx.entityCollection.query(Q5.where("canonical_name", Q5.oneOf(unique))).fetch();
11337
11471
  const existingNames = new Set(existing.map((e) => e.canonicalName));
11338
11472
  const kindBackfills = existing.filter((e) => {
11339
11473
  const incoming = kindByName.get(e.canonicalName);
@@ -11363,7 +11497,7 @@ function prepareKindBackfills(backfills) {
11363
11497
  }
11364
11498
  async function findVaultRowInWrite(ctx, memoryId) {
11365
11499
  try {
11366
- const rows = await ctx.database.get("memory_vault").query(Q4.where("id", memoryId)).fetch();
11500
+ const rows = await ctx.database.get("memory_vault").query(Q5.where("id", memoryId)).fetch();
11367
11501
  return rows[0] ?? null;
11368
11502
  } catch {
11369
11503
  return null;
@@ -11465,7 +11599,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
11465
11599
  return;
11466
11600
  }
11467
11601
  if (entities.length === 0) return;
11468
- const existingLinks = await ctx.memoryEntityCollection.query(Q4.where("memory_id", memoryId)).fetch();
11602
+ const existingLinks = await ctx.memoryEntityCollection.query(Q5.where("memory_id", memoryId)).fetch();
11469
11603
  const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
11470
11604
  const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
11471
11605
  const keptIds = entities.map((e) => e.uniqueId);
@@ -11501,7 +11635,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
11501
11635
  }
11502
11636
  async function resolveEntitiesByIds(ctx, entityIds) {
11503
11637
  if (entityIds.length === 0) return [];
11504
- const rows = await ctx.entityCollection.query(Q4.where("id", Q4.oneOf(Array.from(entityIds)))).fetch();
11638
+ const rows = await ctx.entityCollection.query(Q5.where("id", Q5.oneOf(Array.from(entityIds)))).fetch();
11505
11639
  return rows.map(entityToStored);
11506
11640
  }
11507
11641
  function autoLinkBlocked(row) {
@@ -11537,7 +11671,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
11537
11671
  kindBackfills
11538
11672
  } = await upsertEntitiesInWrite(ctx, normalized);
11539
11673
  entities = Array.from(byName.values());
11540
- const existingLinks = await ctx.memoryEntityCollection.query(Q4.where("memory_id", memoryId)).fetch();
11674
+ const existingLinks = await ctx.memoryEntityCollection.query(Q5.where("memory_id", memoryId)).fetch();
11541
11675
  const keep = new Set(entities.map((e) => e.uniqueId));
11542
11676
  const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
11543
11677
  const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
@@ -11573,17 +11707,17 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
11573
11707
  async function findOrphanedEntities(ctx, memoryId, toDestroy) {
11574
11708
  const candidateIds = [...new Set(toDestroy.map((l) => String(l.entityId)))];
11575
11709
  if (candidateIds.length === 0) return [];
11576
- const links = await ctx.memoryEntityCollection.query(Q4.where("entity_id", Q4.oneOf(candidateIds))).fetch();
11710
+ const links = await ctx.memoryEntityCollection.query(Q5.where("entity_id", Q5.oneOf(candidateIds))).fetch();
11577
11711
  const stillLinked = new Set(
11578
11712
  links.filter((l) => String(l.memoryId) !== memoryId).map((l) => String(l.entityId))
11579
11713
  );
11580
11714
  const orphanIds = candidateIds.filter((id) => !stillLinked.has(id));
11581
11715
  if (orphanIds.length === 0) return [];
11582
- return await ctx.entityCollection.query(Q4.where("id", Q4.oneOf(orphanIds))).fetch();
11716
+ return await ctx.entityCollection.query(Q5.where("id", Q5.oneOf(orphanIds))).fetch();
11583
11717
  }
11584
11718
  async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
11585
11719
  if (memoryIds.length === 0) return;
11586
- const links = await ctx.memoryEntityCollection.query(Q4.where("memory_id", Q4.oneOf(Array.from(memoryIds)))).fetch();
11720
+ const links = await ctx.memoryEntityCollection.query(Q5.where("memory_id", Q5.oneOf(Array.from(memoryIds)))).fetch();
11587
11721
  if (links.length === 0) return;
11588
11722
  await ctx.database.write(async () => {
11589
11723
  await assertCanWrite(ctx);
@@ -11592,7 +11726,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
11592
11726
  }
11593
11727
  async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
11594
11728
  if (!userId) return;
11595
- const links = await ctx.memoryEntityCollection.query(Q4.where("user_id", userId)).fetch();
11729
+ const links = await ctx.memoryEntityCollection.query(Q5.where("user_id", userId)).fetch();
11596
11730
  if (links.length === 0) return;
11597
11731
  await ctx.database.write(async () => {
11598
11732
  await assertCanWrite(ctx);
@@ -11602,15 +11736,15 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
11602
11736
  async function getMemoriesByEntityNamesOp(ctx, entityNames) {
11603
11737
  const unique = Array.from(new Set(entityNames.map(normalizeEntityName).filter((n) => n.length > 0)));
11604
11738
  if (unique.length === 0) return /* @__PURE__ */ new Map();
11605
- const entityRows = await ctx.entityCollection.query(Q4.where("canonical_name", Q4.oneOf(unique))).fetch();
11739
+ const entityRows = await ctx.entityCollection.query(Q5.where("canonical_name", Q5.oneOf(unique))).fetch();
11606
11740
  if (entityRows.length === 0) return /* @__PURE__ */ new Map();
11607
11741
  const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
11608
- const linkConditions = [Q4.where("entity_id", Q4.oneOf(entityRows.map((e) => e.id)))];
11742
+ const linkConditions = [Q5.where("entity_id", Q5.oneOf(entityRows.map((e) => e.id)))];
11609
11743
  if (ctx.userId !== void 0) {
11610
11744
  if (ctx.allowUnscopedRows) {
11611
- linkConditions.push(Q4.or(Q4.where("user_id", ctx.userId), Q4.where("user_id", null)));
11745
+ linkConditions.push(Q5.or(Q5.where("user_id", ctx.userId), Q5.where("user_id", null)));
11612
11746
  } else {
11613
- linkConditions.push(Q4.where("user_id", ctx.userId));
11747
+ linkConditions.push(Q5.where("user_id", ctx.userId));
11614
11748
  }
11615
11749
  }
11616
11750
  const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
@@ -11631,18 +11765,18 @@ async function getMemoriesByEntityNamesOp(ctx, entityNames) {
11631
11765
  async function getEntitiesByMemoryIdsOp(ctx, memoryIds) {
11632
11766
  const unique = Array.from(new Set(memoryIds.filter((id) => id.length > 0)));
11633
11767
  if (unique.length === 0) return /* @__PURE__ */ new Map();
11634
- const linkConditions = [Q4.where("memory_id", Q4.oneOf(unique))];
11768
+ const linkConditions = [Q5.where("memory_id", Q5.oneOf(unique))];
11635
11769
  if (ctx.userId !== void 0) {
11636
11770
  if (ctx.allowUnscopedRows) {
11637
- linkConditions.push(Q4.or(Q4.where("user_id", ctx.userId), Q4.where("user_id", null)));
11771
+ linkConditions.push(Q5.or(Q5.where("user_id", ctx.userId), Q5.where("user_id", null)));
11638
11772
  } else {
11639
- linkConditions.push(Q4.where("user_id", ctx.userId));
11773
+ linkConditions.push(Q5.where("user_id", ctx.userId));
11640
11774
  }
11641
11775
  }
11642
11776
  const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
11643
11777
  if (links.length === 0) return /* @__PURE__ */ new Map();
11644
11778
  const entityIds = Array.from(new Set(links.map((l) => String(l.entityId))));
11645
- const entityRows = await ctx.entityCollection.query(Q4.where("id", Q4.oneOf(entityIds))).fetch();
11779
+ const entityRows = await ctx.entityCollection.query(Q5.where("id", Q5.oneOf(entityIds))).fetch();
11646
11780
  const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
11647
11781
  const out = /* @__PURE__ */ new Map();
11648
11782
  for (const link of links) {
@@ -11706,11 +11840,11 @@ var NON_PRIVATE_VISIBILITIES = ["public"];
11706
11840
  function visibilityConditions(requested) {
11707
11841
  if (!requested?.length) return [];
11708
11842
  if (!requested.includes("private")) {
11709
- return [Q5.where("visibility", Q5.oneOf([...requested]))];
11843
+ return [Q6.where("visibility", Q6.oneOf([...requested]))];
11710
11844
  }
11711
11845
  const excluded = NON_PRIVATE_VISIBILITIES.filter((v) => !requested.includes(v));
11712
11846
  if (excluded.length === 0) return [];
11713
- return [Q5.or(Q5.where("visibility", null), Q5.where("visibility", Q5.notIn(excluded)))];
11847
+ return [Q6.or(Q6.where("visibility", null), Q6.where("visibility", Q6.notIn(excluded)))];
11714
11848
  }
11715
11849
  function isKinded(record2) {
11716
11850
  return record2.kind !== null && record2.kind !== void 0;
@@ -11751,17 +11885,17 @@ function levelConditions(requested) {
11751
11885
  const published = ["shared", "public"];
11752
11886
  const wantsMatching = requested.includes("matching");
11753
11887
  const wantsPrivate = requested.includes("private");
11754
- const unresolved = Q5.or(Q5.where("level", null), Q5.where("level", Q5.notIn([...MEMORY_LEVELS])));
11755
- const byLevel = Q5.where("level", Q5.oneOf([...requested]));
11756
- if (wantsMatching && wantsPrivate) return [Q5.or(byLevel, unresolved)];
11888
+ const unresolved = Q6.or(Q6.where("level", null), Q6.where("level", Q6.notIn([...MEMORY_LEVELS])));
11889
+ const byLevel = Q6.where("level", Q6.oneOf([...requested]));
11890
+ if (wantsMatching && wantsPrivate) return [Q6.or(byLevel, unresolved)];
11757
11891
  if (wantsMatching) {
11758
- return [Q5.or(byLevel, Q5.and(unresolved, Q5.where("scope", Q5.oneOf(published))))];
11892
+ return [Q6.or(byLevel, Q6.and(unresolved, Q6.where("scope", Q6.oneOf(published))))];
11759
11893
  }
11760
11894
  if (wantsPrivate) {
11761
11895
  return [
11762
- Q5.or(
11896
+ Q6.or(
11763
11897
  byLevel,
11764
- Q5.and(unresolved, Q5.or(Q5.where("scope", null), Q5.where("scope", Q5.notIn(published))))
11898
+ Q6.and(unresolved, Q6.or(Q6.where("scope", null), Q6.where("scope", Q6.notIn(published))))
11765
11899
  )
11766
11900
  ];
11767
11901
  }
@@ -11772,13 +11906,13 @@ function isOwnedByCtxUser(ctx, record2) {
11772
11906
  }
11773
11907
  function baseVaultConditions(ctx, options) {
11774
11908
  return [
11775
- ...options?.memoryIds !== void 0 ? [Q5.where("id", Q5.oneOf(options.memoryIds))] : [],
11776
- ...options?.includeDeleted ? [] : [Q5.where("is_deleted", false)],
11777
- ...options?.includeArchived ? [] : [Q5.where("archived_at", Q5.eq(null))],
11778
- ...options?.includeQuarantined ? [] : [Q5.where("trust_tier", Q5.notEq("quarantined"))],
11779
- ...options?.includeSuperseded ? [] : [Q5.where("superseded_by", null)],
11780
- ...ctx.userId !== void 0 ? [Q5.where("user_id", ctx.userId)] : [],
11781
- ...options?.since ? [Q5.where("updated_at", Q5.gt(options.since.getTime()))] : []
11909
+ ...options?.memoryIds !== void 0 ? [Q6.where("id", Q6.oneOf(options.memoryIds))] : [],
11910
+ ...options?.includeDeleted ? [] : [Q6.where("is_deleted", false)],
11911
+ ...options?.includeArchived ? [] : [Q6.where("archived_at", Q6.eq(null))],
11912
+ ...options?.includeQuarantined ? [] : [Q6.where("trust_tier", Q6.notEq("quarantined"))],
11913
+ ...options?.includeSuperseded ? [] : [Q6.where("superseded_by", null)],
11914
+ ...ctx.userId !== void 0 ? [Q6.where("user_id", ctx.userId)] : [],
11915
+ ...options?.since ? [Q6.where("updated_at", Q6.gt(options.since.getTime()))] : []
11782
11916
  ];
11783
11917
  }
11784
11918
  var KNOWN_TRUST_TIERS = /* @__PURE__ */ new Set(["quarantined", "trusted"]);
@@ -11948,11 +12082,11 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
11948
12082
  async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
11949
12083
  const records = await ctx.vaultMemoryCollection.query(
11950
12084
  ...baseVaultConditions(ctx),
11951
- Q5.where("event_time_start", Q5.notEq(null)),
11952
- Q5.where("event_time_start", Q5.lte(windowEnd)),
11953
- Q5.or(
11954
- Q5.where("event_time_start", Q5.gte(windowStart)),
11955
- Q5.where("event_time_kind", Q5.oneOf(["range", "ongoing"]))
12085
+ Q6.where("event_time_start", Q6.notEq(null)),
12086
+ Q6.where("event_time_start", Q6.lte(windowEnd)),
12087
+ Q6.or(
12088
+ Q6.where("event_time_start", Q6.gte(windowStart)),
12089
+ Q6.where("event_time_kind", Q6.oneOf(["range", "ongoing"]))
11956
12090
  )
11957
12091
  ).fetch();
11958
12092
  const out = [];
@@ -12108,18 +12242,18 @@ async function getAllVaultMemoriesOp(ctx, options) {
12108
12242
  function vaultListConditions(ctx, options) {
12109
12243
  return [
12110
12244
  ...baseVaultConditions(ctx, options),
12111
- ...options?.scopes?.length ? [Q5.where("scope", Q5.oneOf(options.scopes))] : [],
12245
+ ...options?.scopes?.length ? [Q6.where("scope", Q6.oneOf(options.scopes))] : [],
12112
12246
  ...visibilityConditions(options?.visibility),
12113
12247
  ...levelConditions(options?.levels),
12114
- ...options?.kinds?.length ? [Q5.where("kind", Q5.oneOf(options.kinds))] : [],
12115
- ...options?.folderId !== void 0 ? [Q5.where("folder_id", options.folderId)] : [],
12116
- ...options?.factTypes?.length ? [Q5.where("fact_type", Q5.oneOf(options.factTypes))] : []
12248
+ ...options?.kinds?.length ? [Q6.where("kind", Q6.oneOf(options.kinds))] : [],
12249
+ ...options?.folderId !== void 0 ? [Q6.where("folder_id", options.folderId)] : [],
12250
+ ...options?.factTypes?.length ? [Q6.where("fact_type", Q6.oneOf(options.factTypes))] : []
12117
12251
  ];
12118
12252
  }
12119
12253
  function vaultListOrder(options) {
12120
12254
  return [
12121
- Q5.sortBy(options?.since ? "updated_at" : "created_at", Q5.desc),
12122
- ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [Q5.take(options.limit)] : []
12255
+ Q6.sortBy(options?.since ? "updated_at" : "created_at", Q6.desc),
12256
+ ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [Q6.take(options.limit)] : []
12123
12257
  ];
12124
12258
  }
12125
12259
  async function getAllVaultMemoryRowsOp(ctx) {
@@ -12158,10 +12292,10 @@ function vaultMemoryRawToRankable(raw) {
12158
12292
  async function getVaultRankingProjectionsOp(ctx, options) {
12159
12293
  const conditions = [
12160
12294
  ...baseVaultConditions(ctx, options),
12161
- ...options?.scopes?.length ? [Q5.where("scope", Q5.oneOf(options.scopes))] : [],
12162
- ...options?.folderId !== void 0 ? [Q5.where("folder_id", options.folderId)] : [],
12163
- Q5.sortBy(options?.since ? "updated_at" : "created_at", Q5.desc),
12164
- ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [Q5.take(options.limit)] : []
12295
+ ...options?.scopes?.length ? [Q6.where("scope", Q6.oneOf(options.scopes))] : [],
12296
+ ...options?.folderId !== void 0 ? [Q6.where("folder_id", options.folderId)] : [],
12297
+ Q6.sortBy(options?.since ? "updated_at" : "created_at", Q6.desc),
12298
+ ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [Q6.take(options.limit)] : []
12165
12299
  ];
12166
12300
  const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
12167
12301
  return results.map(vaultMemoryRawToRankable);
@@ -12212,7 +12346,7 @@ async function getVaultCandidateKeysOp(ctx, options) {
12212
12346
  args.push(...options.factTypes);
12213
12347
  }
12214
12348
  const sql = `select "id", "scope", "folder_id", "embedding_model", "updated_at" from "memory_vault" where ${clauses.join(" and ")}`;
12215
- const rows = await ctx.vaultMemoryCollection.query(Q5.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
12349
+ const rows = await ctx.vaultMemoryCollection.query(Q6.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
12216
12350
  return rows.map(mapRaw);
12217
12351
  } catch (err) {
12218
12352
  getLogger().debug(
@@ -12223,9 +12357,9 @@ async function getVaultCandidateKeysOp(ctx, options) {
12223
12357
  memoryIds: options?.memoryIds,
12224
12358
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
12225
12359
  }),
12226
- ...options?.scopes?.length ? [Q5.where("scope", Q5.oneOf(options.scopes))] : [],
12227
- ...options?.folderId !== void 0 ? [Q5.where("folder_id", options.folderId)] : [],
12228
- ...options?.factTypes?.length ? [Q5.where("fact_type", Q5.oneOf(options.factTypes))] : []
12360
+ ...options?.scopes?.length ? [Q6.where("scope", Q6.oneOf(options.scopes))] : [],
12361
+ ...options?.folderId !== void 0 ? [Q6.where("folder_id", options.folderId)] : [],
12362
+ ...options?.factTypes?.length ? [Q6.where("fact_type", Q6.oneOf(options.factTypes))] : []
12229
12363
  ];
12230
12364
  const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
12231
12365
  return rows.map(mapRaw);
@@ -12243,7 +12377,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
12243
12377
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
12244
12378
  });
12245
12379
  const sql = `select "id", "embedding", "embedding_model" from "memory_vault" where ${base.sql} and "id" in (${ids.map(() => "?").join(",")})`;
12246
- const rows = await ctx.vaultMemoryCollection.query(Q5.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
12380
+ const rows = await ctx.vaultMemoryCollection.query(Q6.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
12247
12381
  return rows.map(mapRaw);
12248
12382
  } catch (err) {
12249
12383
  getLogger().debug(
@@ -12255,7 +12389,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
12255
12389
  includeArchived: options.includeArchived
12256
12390
  }
12257
12391
  }),
12258
- Q5.where("id", Q5.oneOf(ids))
12392
+ Q6.where("id", Q6.oneOf(ids))
12259
12393
  ).unsafeFetchRaw();
12260
12394
  return rows.map(mapRaw);
12261
12395
  }
@@ -12266,7 +12400,7 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
12266
12400
  ...baseVaultConditions(ctx, {
12267
12401
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
12268
12402
  }),
12269
- Q5.where("id", Q5.oneOf(ids))
12403
+ Q6.where("id", Q6.oneOf(ids))
12270
12404
  ];
12271
12405
  const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
12272
12406
  return mapInBatches(
@@ -12291,7 +12425,7 @@ async function countActiveVaultMemoriesOp(ctx) {
12291
12425
  }
12292
12426
  async function getActiveVaultMemoryIdsOp(ctx, ids) {
12293
12427
  if (ids.length === 0) return /* @__PURE__ */ new Set();
12294
- const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), Q5.where("id", Q5.oneOf(ids))).unsafeFetchRaw();
12428
+ const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), Q6.where("id", Q6.oneOf(ids))).unsafeFetchRaw();
12295
12429
  return new Set(rows.map((r) => r.id));
12296
12430
  }
12297
12431
  async function updateVaultMemoryOp(ctx, id, opts) {
@@ -12440,7 +12574,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
12440
12574
  () => linkMemoryEntitiesOp(entityCtx, memoryId, entities, { topicsSource: "user" })
12441
12575
  ) : [];
12442
12576
  const keep = new Set(linked.map((e) => e.uniqueId));
12443
- const existing = await entityCtx.memoryEntityCollection.query(Q5.where("memory_id", memoryId)).fetch();
12577
+ const existing = await entityCtx.memoryEntityCollection.query(Q6.where("memory_id", memoryId)).fetch();
12444
12578
  const staleLinks = existing.filter((l) => !keep.has(String(l.entityId)));
12445
12579
  if (staleLinks.length === 0 && entities.length > 0) return;
12446
12580
  const topicsWrite = await resolveMemoryTopicsWrite(
@@ -12581,9 +12715,9 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
12581
12715
  }
12582
12716
  async function getUnfiledVaultMemoriesOp(ctx) {
12583
12717
  const conditions = [
12584
- Q5.where("folder_id", null),
12718
+ Q6.where("folder_id", null),
12585
12719
  ...baseVaultConditions(ctx),
12586
- Q5.sortBy("created_at", Q5.desc)
12720
+ Q6.sortBy("created_at", Q6.desc)
12587
12721
  ];
12588
12722
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
12589
12723
  return mapInBatches(
@@ -12597,7 +12731,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
12597
12731
  const entityIdByMemory = /* @__PURE__ */ new Map();
12598
12732
  const allEntityIds = /* @__PURE__ */ new Set();
12599
12733
  for (let i = 0; i < memoryIds.length; i += CHUNK) {
12600
- const links = await entityCtx.memoryEntityCollection.query(Q5.where("memory_id", Q5.oneOf(memoryIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
12734
+ const links = await entityCtx.memoryEntityCollection.query(Q6.where("memory_id", Q6.oneOf(memoryIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
12601
12735
  for (const link of links) {
12602
12736
  const memoryId = String(link.memory_id);
12603
12737
  const entityId = String(link.entity_id);
@@ -12613,7 +12747,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
12613
12747
  const entityIds = Array.from(allEntityIds);
12614
12748
  const nameById = /* @__PURE__ */ new Map();
12615
12749
  for (let i = 0; i < entityIds.length; i += CHUNK) {
12616
- const entities = await entityCtx.entityCollection.query(Q5.where("id", Q5.oneOf(entityIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
12750
+ const entities = await entityCtx.entityCollection.query(Q6.where("id", Q6.oneOf(entityIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
12617
12751
  for (const e of entities) {
12618
12752
  if (typeof e.canonical_name === "string") nameById.set(String(e.id), e.canonical_name);
12619
12753
  }
@@ -12642,7 +12776,7 @@ async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
12642
12776
  if (!entityCtx) {
12643
12777
  throw new Error("getMemoriesNeedingTopicExtractionOp requires ctx.entityCtx");
12644
12778
  }
12645
- const conditions = [...baseVaultConditions(ctx), Q5.sortBy("created_at", Q5.desc)];
12779
+ const conditions = [...baseVaultConditions(ctx), Q6.sortBy("created_at", Q6.desc)];
12646
12780
  const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
12647
12781
  const linkedNames = await linkedEntityNamesByMemory(
12648
12782
  entityCtx,
@@ -12798,10 +12932,10 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
12798
12932
  }
12799
12933
  if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
12800
12934
  if (parseTopics(record2.topics) !== null) continue;
12801
- const links = await entityCtx.memoryEntityCollection.query(Q5.where("memory_id", id)).unsafeFetchRaw();
12935
+ const links = await entityCtx.memoryEntityCollection.query(Q6.where("memory_id", id)).unsafeFetchRaw();
12802
12936
  const entityIds = links.map((l) => String(l.entity_id));
12803
12937
  if (entityIds.length === 0) continue;
12804
- const entities = await entityCtx.entityCollection.query(Q5.where("id", Q5.oneOf(entityIds))).fetch();
12938
+ const entities = await entityCtx.entityCollection.query(Q6.where("id", Q6.oneOf(entityIds))).fetch();
12805
12939
  if (entities.length === 0) continue;
12806
12940
  const source = record2.topicsUserManaged ? "user" : "auto";
12807
12941
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
@@ -12817,7 +12951,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
12817
12951
  }
12818
12952
  async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
12819
12953
  if (ctx.userId !== void 0 && ctx.userId !== userId) return 0;
12820
- const records = await ctx.vaultMemoryCollection.query(Q5.where("user_id", userId), Q5.where("is_deleted", false)).fetch();
12954
+ const records = await ctx.vaultMemoryCollection.query(Q6.where("user_id", userId), Q6.where("is_deleted", false)).fetch();
12821
12955
  if (records.length === 0) return 0;
12822
12956
  await ctx.database.write(async () => {
12823
12957
  await assertCanWrite2(ctx);
@@ -12854,7 +12988,7 @@ async function getDecayCandidatesRawOp(ctx) {
12854
12988
  assertVaultScopeForSweep(ctx);
12855
12989
  const results = await ctx.vaultMemoryCollection.query(
12856
12990
  ...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true }),
12857
- Q5.where("kind", null)
12991
+ Q6.where("kind", null)
12858
12992
  ).unsafeFetchRaw();
12859
12993
  return results.map((raw) => ({
12860
12994
  uniqueId: raw.id,
@@ -12984,11 +13118,11 @@ async function findQuarantinedDuplicateOp(ctx, content, sourceIds2, where) {
12984
13118
  const wanted = [...new Set(sourceIds2)].sort().join("\0");
12985
13119
  const target = normalizeForDedupe(content);
12986
13120
  const rows = await ctx.vaultMemoryCollection.query(
12987
- Q5.where("trust_tier", "quarantined"),
12988
- Q5.where("is_deleted", false),
12989
- Q5.where("scope", where.scope),
12990
- Q5.where("folder_id", where.folderId),
12991
- ...ctx.userId !== void 0 ? [Q5.where("user_id", ctx.userId)] : []
13121
+ Q6.where("trust_tier", "quarantined"),
13122
+ Q6.where("is_deleted", false),
13123
+ Q6.where("scope", where.scope),
13124
+ Q6.where("folder_id", where.folderId),
13125
+ ...ctx.userId !== void 0 ? [Q6.where("user_id", ctx.userId)] : []
12992
13126
  ).unsafeFetchRaw();
12993
13127
  for (const raw of rows) {
12994
13128
  let ids;
@@ -13483,7 +13617,7 @@ var WalletPoller = class {
13483
13617
  };
13484
13618
 
13485
13619
  // src/lib/db/vaultFolders/operations.ts
13486
- import { Q as Q6 } from "@nozbe/watermelondb";
13620
+ import { Q as Q7 } from "@nozbe/watermelondb";
13487
13621
  function folderToStored(folder) {
13488
13622
  return {
13489
13623
  uniqueId: folder.id,
@@ -13508,7 +13642,7 @@ async function createVaultFolderOp(ctx, opts) {
13508
13642
  return folderToStored(created);
13509
13643
  }
13510
13644
  async function getAllVaultFoldersOp(ctx) {
13511
- const results = await ctx.vaultFolderCollection.query(Q6.where("is_deleted", false), Q6.sortBy("created_at", Q6.desc)).fetch();
13645
+ const results = await ctx.vaultFolderCollection.query(Q7.where("is_deleted", false), Q7.sortBy("created_at", Q7.desc)).fetch();
13512
13646
  return results.map(folderToStored);
13513
13647
  }
13514
13648
  async function updateVaultFolderOp(ctx, id, opts) {
@@ -13517,7 +13651,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
13517
13651
  if (record2.isDeleted) return null;
13518
13652
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
13519
13653
  const updated = await ctx.database.write(async () => {
13520
- const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q6.where("folder_id", id), Q6.where("is_deleted", false)).fetch() : [];
13654
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q7.where("folder_id", id), Q7.where("is_deleted", false)).fetch() : [];
13521
13655
  const updates = [];
13522
13656
  updates.push(
13523
13657
  record2.prepareUpdate((r) => {
@@ -13546,7 +13680,7 @@ async function deleteVaultFolderOp(ctx, id) {
13546
13680
  const record2 = await ctx.vaultFolderCollection.find(id);
13547
13681
  if (record2.isDeleted) return false;
13548
13682
  await ctx.database.write(async () => {
13549
- const memories = await ctx.vaultMemoryCollection.query(Q6.where("folder_id", id), Q6.where("is_deleted", false)).fetch();
13683
+ const memories = await ctx.vaultMemoryCollection.query(Q7.where("folder_id", id), Q7.where("is_deleted", false)).fetch();
13550
13684
  const preparedMemories = memories.map(
13551
13685
  (memory) => memory.prepareUpdate((r) => {
13552
13686
  r._setRaw("folder_id", null);
@@ -13617,7 +13751,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
13617
13751
  }
13618
13752
  }
13619
13753
  async function getVaultFolderMemoryCountOp(ctx, folderId) {
13620
- return await ctx.vaultMemoryCollection.query(Q6.where("folder_id", folderId), Q6.where("is_deleted", false)).fetchCount();
13754
+ return await ctx.vaultMemoryCollection.query(Q7.where("folder_id", folderId), Q7.where("is_deleted", false)).fetchCount();
13621
13755
  }
13622
13756
 
13623
13757
  // src/lib/db/vaultFolders/defaults.ts
@@ -13660,7 +13794,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
13660
13794
  }
13661
13795
 
13662
13796
  // src/lib/memory/autoExtract.ts
13663
- import { Q as Q7 } from "@nozbe/watermelondb";
13797
+ import { Q as Q8 } from "@nozbe/watermelondb";
13664
13798
 
13665
13799
  // src/lib/memory/entitySalience.ts
13666
13800
  var GENERIC_ENTITY_NAMES = /* @__PURE__ */ new Set([
@@ -16368,7 +16502,7 @@ async function assertMergeTargetGoneOrThrow(ctx, targetId) {
16368
16502
  // src/lib/memory/autoExtract.ts
16369
16503
  async function isMemoryTopicsUserManaged(ctx, memoryId) {
16370
16504
  try {
16371
- const rows = await ctx.database.get(VaultMemory.table).query(Q7.where("id", memoryId)).fetch();
16505
+ const rows = await ctx.database.get(VaultMemory.table).query(Q8.where("id", memoryId)).fetch();
16372
16506
  return rows[0]?.topicsUserManaged === true;
16373
16507
  } catch {
16374
16508
  return true;
@@ -18913,7 +19047,7 @@ function parseAnswer(body, base, parseSchema) {
18913
19047
  }
18914
19048
 
18915
19049
  // src/lib/memory/store/local.ts
18916
- import { Q as Q8 } from "@nozbe/watermelondb";
19050
+ import { Q as Q9 } from "@nozbe/watermelondb";
18917
19051
 
18918
19052
  // src/lib/memory/topicExtract.ts
18919
19053
  var TOPIC_EXTRACTION_BATCH_SIZE = 10;
@@ -19192,8 +19326,8 @@ function createLocalMemoryStore(options) {
19192
19326
  writeOptions?.signal?.throwIfAborted();
19193
19327
  };
19194
19328
  const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
19195
- const ownedBy = userId !== void 0 ? [Q8.where("user_id", userId)] : [];
19196
- const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
19329
+ const ownedBy = userId !== void 0 ? [Q9.where("user_id", userId)] : [];
19330
+ const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q9.or(Q9.where("user_id", userId), Q9.where("user_id", null))] : [Q9.where("user_id", userId)];
19197
19331
  const watchedColumns = [
19198
19332
  "content",
19199
19333
  "scope",
@@ -19238,7 +19372,7 @@ function createLocalMemoryStore(options) {
19238
19372
  list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
19239
19373
  get: (id) => getVaultMemoryOp(vaultCtx, id),
19240
19374
  listArchived: async () => {
19241
- const ids = await vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), Q8.where("archived_at", Q8.notEq(null)), ...ownedBy).fetchIds();
19375
+ const ids = await vaultCtx.vaultMemoryCollection.query(Q9.where("is_deleted", false), Q9.where("archived_at", Q9.notEq(null)), ...ownedBy).fetchIds();
19242
19376
  if (ids.length === 0) return [];
19243
19377
  const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
19244
19378
  return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
@@ -19254,7 +19388,7 @@ function createLocalMemoryStore(options) {
19254
19388
  set.add(String(link.memory_id));
19255
19389
  members.set(entityId, set);
19256
19390
  }
19257
- const entities = userId === void 0 ? await entityCtx.entityCollection.query().unsafeFetchRaw() : members.size ? await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf([...members.keys()]))).unsafeFetchRaw() : [];
19391
+ const entities = userId === void 0 ? await entityCtx.entityCollection.query().unsafeFetchRaw() : members.size ? await entityCtx.entityCollection.query(Q9.where("id", Q9.oneOf([...members.keys()]))).unsafeFetchRaw() : [];
19258
19392
  const byName = /* @__PURE__ */ new Map();
19259
19393
  for (const entity of entities) {
19260
19394
  const name = String(entity.canonical_name);
@@ -19304,7 +19438,7 @@ function createLocalMemoryStore(options) {
19304
19438
  setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
19305
19439
  addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
19306
19440
  await assertWrite(writeOptions);
19307
- const owned = await vaultCtx.vaultMemoryCollection.query(Q8.where("id", memoryId), Q8.where("is_deleted", false), ...ownedBy).fetchCount();
19441
+ const owned = await vaultCtx.vaultMemoryCollection.query(Q9.where("id", memoryId), Q9.where("is_deleted", false), ...ownedBy).fetchCount();
19308
19442
  return owned > 0 ? writer.callWriter(
19309
19443
  () => linkMemoryEntitiesOp(
19310
19444
  {
@@ -19376,7 +19510,7 @@ function createLocalMemoryStore(options) {
19376
19510
  else onChange();
19377
19511
  };
19378
19512
  };
19379
- const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), ...ownedBy).observeWithColumns(
19513
+ const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(Q9.where("is_deleted", false), ...ownedBy).observeWithColumns(
19380
19514
  subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
19381
19515
  );
19382
19516
  const subscriptions = [memories.subscribe(afterFirst())];
@@ -22435,7 +22569,7 @@ async function assembleMemoryContext(options) {
22435
22569
  }
22436
22570
 
22437
22571
  // src/lib/memory/durableExtraction.ts
22438
- import { Q as Q9 } from "@nozbe/watermelondb";
22572
+ import { Q as Q10 } from "@nozbe/watermelondb";
22439
22573
  var MAX_JOBS_PER_PASS = 3;
22440
22574
  var MAX_ATTEMPTS = 3;
22441
22575
  var MAX_FAILED_SESSIONS = 3;
@@ -22606,7 +22740,7 @@ function createDurableAutoExtractor(options) {
22606
22740
  const source = options.messageSource?.(conversationId);
22607
22741
  if (source)
22608
22742
  return await fromSource(source.status(conversationId)) === "ready" && (await loadFromSource(source, conversationId, ids)).every(Boolean);
22609
- return await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q9.where("conversation_id", conversationId), Q9.where("id", Q9.oneOf(ids))).fetchCount() === ids.length;
22743
+ return await storage.conversationsCollection.query(Q10.where("conversation_id", conversationId), Q10.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q10.where("conversation_id", conversationId), Q10.where("id", Q10.oneOf(ids))).fetchCount() === ids.length;
22610
22744
  }
22611
22745
  function schedule(delay) {
22612
22746
  if (disposed) return;
@@ -22780,7 +22914,7 @@ function createDurableAutoExtractor(options) {
22780
22914
  let sourceWaiting = false;
22781
22915
  try {
22782
22916
  await writes;
22783
- const pending = await jobs.query(Q9.where("owner_key", owner), Q9.where("message_ids", Q9.notEq("[]"))).fetch();
22917
+ const pending = await jobs.query(Q10.where("owner_key", owner), Q10.where("message_ids", Q10.notEq("[]"))).fetch();
22784
22918
  storeFailures = 0;
22785
22919
  let processed = 0;
22786
22920
  for (const job of pending) {
@@ -22812,7 +22946,7 @@ function createDurableAutoExtractor(options) {
22812
22946
  let ids = [];
22813
22947
  let loaded = [];
22814
22948
  try {
22815
- const present = source ? sourceStatus === "ready" : await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount() > 0;
22949
+ const present = source ? sourceStatus === "ready" : await storage.conversationsCollection.query(Q10.where("conversation_id", conversationId), Q10.where("is_deleted", false)).fetchCount() > 0;
22816
22950
  if (!present) {
22817
22951
  await database.write(() => job.destroyPermanently());
22818
22952
  continue;
@@ -22980,7 +23114,7 @@ function createDurableAutoExtractor(options) {
22980
23114
  const scope = currentScope();
22981
23115
  writes = writes.then(
22982
23116
  () => database.write(async () => {
22983
- const existing = await jobs.query(Q9.where("owner_key", owner), Q9.where("conversation_id", conversationId)).fetch();
23117
+ const existing = await jobs.query(Q10.where("owner_key", owner), Q10.where("conversation_id", conversationId)).fetch();
22984
23118
  const job = existing.find(
22985
23119
  (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
22986
23120
  );
@@ -22993,8 +23127,8 @@ function createDurableAutoExtractor(options) {
22993
23127
  if (watermarks.length) {
22994
23128
  const misplaced = new Set(
22995
23129
  await storage.messagesCollection.query(
22996
- Q9.where("id", Q9.oneOf(watermarks)),
22997
- Q9.where("conversation_id", Q9.notEq(conversationId))
23130
+ Q10.where("id", Q10.oneOf(watermarks)),
23131
+ Q10.where("conversation_id", Q10.notEq(conversationId))
22998
23132
  ).fetchIds()
22999
23133
  );
23000
23134
  for (const prior of existing)
@@ -23004,7 +23138,7 @@ function createDurableAutoExtractor(options) {
23004
23138
  r._setRaw("watermark_seq", null);
23005
23139
  });
23006
23140
  }
23007
- const rows = fromSourceConversation ? [] : await storage.messagesCollection.query(Q9.where("id", Q9.oneOf(ids))).fetch();
23141
+ const rows = fromSourceConversation ? [] : await storage.messagesCollection.query(Q10.where("id", Q10.oneOf(ids))).fetch();
23008
23142
  const foreignRows = new Set(
23009
23143
  rows.filter((row) => row._getRaw("conversation_id") !== conversationId).map((row) => row.id)
23010
23144
  );
@@ -24003,7 +24137,7 @@ function computeToolGuidance(selectedServerTools, selectedClientTools, extraTool
24003
24137
  async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embeddingOptions, extraToolSets = [], activeToolSets = [], noEmbeddingsReason = "short-prompt") {
24004
24138
  const isAlwaysIncluded = (t) => {
24005
24139
  const name = getToolName2(t);
24006
- return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME || name === CONFIRM_TOOL_NAME;
24140
+ return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME || name === CONFIRM_TOOL_NAME || name === SELECT_PAYMENT_WALLET_TOOL_NAME || name === WALLET_PAYMENT_TOOL_NAME;
24007
24141
  };
24008
24142
  const alwaysInclude = clientTools.filter(isAlwaysIncluded);
24009
24143
  const filterCandidates = clientTools.filter((t) => !isAlwaysIncluded(t));
@@ -24015,7 +24149,7 @@ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embed
24015
24149
  }
24016
24150
  if (!promptEmbeddings) {
24017
24151
  if (activeToolSets.length === 0) {
24018
- return { tools: [], activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
24152
+ return { tools: alwaysInclude, activatedSetNames: /* @__PURE__ */ new Set(), matchedSetNames: /* @__PURE__ */ new Set() };
24019
24153
  }
24020
24154
  const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
24021
24155
  const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
@@ -25161,6 +25295,179 @@ function createNotionProxyTools(callMcp) {
25161
25295
  return NOTION_TOOLS.map((tool) => tool(run));
25162
25296
  }
25163
25297
 
25298
+ // src/tools/uiInteraction.ts
25299
+ function generateInteractionId(prefix) {
25300
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
25301
+ }
25302
+ function createInteractiveTool(options, config) {
25303
+ return {
25304
+ type: "function",
25305
+ function: {
25306
+ name: config.name,
25307
+ description: config.description,
25308
+ arguments: config.parameters
25309
+ },
25310
+ executor: async (args, signal) => {
25311
+ if (config.validate && !config.validate(args)) {
25312
+ return { cancelled: true };
25313
+ }
25314
+ const context = options.getContext();
25315
+ if (!context) {
25316
+ return { cancelled: true };
25317
+ }
25318
+ const interactionId = generateInteractionId(config.interactionType);
25319
+ const interactionData = config.mapArgs ? config.mapArgs(args) : args;
25320
+ const onAbort = () => context.cancelInteraction?.(interactionId);
25321
+ signal?.addEventListener("abort", onAbort, { once: true });
25322
+ try {
25323
+ const result = await context.createInteraction(interactionId, config.interactionType, {
25324
+ ...interactionData,
25325
+ afterMessageId: options.getLastMessageId?.()
25326
+ });
25327
+ if (config.mapResult) {
25328
+ return config.mapResult(result, args);
25329
+ }
25330
+ return result;
25331
+ } catch {
25332
+ return { cancelled: true };
25333
+ } finally {
25334
+ signal?.removeEventListener("abort", onAbort);
25335
+ }
25336
+ },
25337
+ executorTimeout: Infinity
25338
+ };
25339
+ }
25340
+
25341
+ // src/tools/walletPayment.ts
25342
+ var CANCELLED = { cancelled: true };
25343
+ function isNonEmptyString(value) {
25344
+ return typeof value === "string" && value.length > 0;
25345
+ }
25346
+ function hasPassengers(value) {
25347
+ return Array.isArray(value?.passengers);
25348
+ }
25349
+ function createSelectPaymentWalletTool(options) {
25350
+ const tool = createInteractiveTool(options, {
25351
+ name: SELECT_PAYMENT_WALLET_TOOL_NAME,
25352
+ description: "Show the user a card with the flight offer and their wallets, and let them pick the wallet to pay from. Call it after anuma_flight_offer_details, with the exact offer id, price and currency from that result. Returns the chosen wallet, or that the user declined.",
25353
+ parameters: {
25354
+ type: "object",
25355
+ properties: {
25356
+ offer_id: {
25357
+ type: "string",
25358
+ description: "The offer id from anuma_flight_offer_details"
25359
+ },
25360
+ summary: {
25361
+ type: "string",
25362
+ description: "Route, dates and fare of the offer, as shown to the user"
25363
+ },
25364
+ amount: {
25365
+ type: "string",
25366
+ description: "Total price of the offer, e.g. '412.50'"
25367
+ },
25368
+ currency: {
25369
+ type: "string",
25370
+ description: "Currency of the price, e.g. 'USD'"
25371
+ }
25372
+ },
25373
+ required: ["offer_id", "amount", "currency"]
25374
+ },
25375
+ interactionType: "select_payment_wallet",
25376
+ validate: (args) => isNonEmptyString(args.offer_id),
25377
+ mapArgs: ({ offer_id, summary, amount, currency, wallets }) => ({
25378
+ offer_id,
25379
+ summary,
25380
+ amount,
25381
+ currency,
25382
+ wallets
25383
+ }),
25384
+ mapResult: (result, args) => {
25385
+ if (result?.confirmed === true && isNonEmptyString(result.funding_wallet)) {
25386
+ return {
25387
+ confirmed: true,
25388
+ offer_id: args.offer_id,
25389
+ funding_wallet: result.funding_wallet
25390
+ };
25391
+ }
25392
+ if (result?.confirmed === false) return { confirmed: false };
25393
+ return CANCELLED;
25394
+ }
25395
+ });
25396
+ const showCard = tool.executor;
25397
+ return {
25398
+ ...tool,
25399
+ executor: async (args, signal) => {
25400
+ if (!isNonEmptyString(args.offer_id)) return CANCELLED;
25401
+ let wallets;
25402
+ try {
25403
+ wallets = await options.listWallets();
25404
+ } catch {
25405
+ return { error_code: "wallets_unavailable", retryable: true };
25406
+ }
25407
+ if (signal?.aborted) return CANCELLED;
25408
+ return showCard?.({ ...args, wallets }, signal);
25409
+ }
25410
+ };
25411
+ }
25412
+ function createWalletPaymentTool(options) {
25413
+ const tool = createInteractiveTool(options, {
25414
+ name: WALLET_PAYMENT_TOOL_NAME,
25415
+ description: "Show the user a card to enter the passengers, then pay the flight booking from the wallet they chose. Call it after anuma_create_flight_intent, with the provider and reference from that result. Returns whether the payment went through.",
25416
+ parameters: {
25417
+ type: "object",
25418
+ properties: {
25419
+ provider: {
25420
+ type: "string",
25421
+ description: "The payment provider from anuma_create_flight_intent"
25422
+ },
25423
+ reference: {
25424
+ type: "string",
25425
+ description: "The payment reference from anuma_create_flight_intent"
25426
+ },
25427
+ passenger_count: {
25428
+ type: "integer",
25429
+ minimum: 1,
25430
+ description: "How many passengers the booking is for"
25431
+ }
25432
+ },
25433
+ required: ["provider", "reference", "passenger_count"]
25434
+ },
25435
+ interactionType: "prompt_wallet_payment",
25436
+ validate: (args) => isNonEmptyString(args.provider) && isNonEmptyString(args.reference) && Number.isInteger(args.passenger_count) && args.passenger_count >= 1,
25437
+ mapArgs: ({ provider, reference, passenger_count }) => ({
25438
+ provider,
25439
+ reference,
25440
+ passenger_count
25441
+ }),
25442
+ mapResult: (result) => hasPassengers(result) ? { passengers: result.passengers } : CANCELLED
25443
+ });
25444
+ const showCard = tool.executor;
25445
+ return {
25446
+ ...tool,
25447
+ executor: async (args, signal) => {
25448
+ const answer = await showCard?.(args, signal);
25449
+ if (!hasPassengers(answer) || signal?.aborted) return CANCELLED;
25450
+ const provider = args.provider;
25451
+ const reference = args.reference;
25452
+ let outcome2;
25453
+ try {
25454
+ outcome2 = await options.pay({ provider, reference, passengers: answer.passengers }, signal);
25455
+ } catch {
25456
+ return { paid: false, error_code: "payment_failed", retryable: false };
25457
+ }
25458
+ if (outcome2.paid) {
25459
+ return {
25460
+ paid: true,
25461
+ provider: outcome2.provider,
25462
+ reference: outcome2.reference,
25463
+ status: outcome2.status
25464
+ };
25465
+ }
25466
+ return { paid: false, error_code: outcome2.error_code, retryable: outcome2.retryable };
25467
+ }
25468
+ };
25469
+ }
25470
+
25164
25471
  // src/expo/useChat.ts
25165
25472
  import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
25166
25473
  function useChat(options) {
@@ -26047,7 +26354,7 @@ async function cleanupConversationSummary(database, conversationId) {
26047
26354
  }
26048
26355
 
26049
26356
  // src/lib/db/media/operations.ts
26050
- import { Q as Q10 } from "@nozbe/watermelondb";
26357
+ import { Q as Q11 } from "@nozbe/watermelondb";
26051
26358
 
26052
26359
  // src/lib/storage/opfs.ts
26053
26360
  function isOPFSSupported() {
@@ -26238,7 +26545,7 @@ async function createMediaBatchOp(ctx, optionsArray) {
26238
26545
  })
26239
26546
  );
26240
26547
  });
26241
- const results = await mediaCollection.query(Q10.where("media_id", Q10.oneOf(mediaIds))).fetch();
26548
+ const results = await mediaCollection.query(Q11.where("media_id", Q11.oneOf(mediaIds))).fetch();
26242
26549
  return Promise.all(
26243
26550
  results.map(
26244
26551
  (m) => mediaToStored(m, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
@@ -26248,7 +26555,7 @@ async function createMediaBatchOp(ctx, optionsArray) {
26248
26555
  var IMAGE_VIDEO_MIMES = VIDEO_EXTENSIONS.map((ext) => `image/${ext}`);
26249
26556
  async function deleteMediaByConversationOp(ctx, conversationId) {
26250
26557
  const mediaCollection = ctx.database.get("media");
26251
- const results = await mediaCollection.query(Q10.where("conversation_id", conversationId), Q10.where("is_deleted", false)).fetch();
26558
+ const results = await mediaCollection.query(Q11.where("conversation_id", conversationId), Q11.where("is_deleted", false)).fetch();
26252
26559
  if (results.length === 0) {
26253
26560
  return 0;
26254
26561
  }
@@ -28327,6 +28634,7 @@ export {
28327
28634
  RemoteMemoryPartialCreateError,
28328
28635
  RerankerUnavailableError,
28329
28636
  SDK_SCHEMA_VERSION,
28637
+ SELECT_PAYMENT_WALLET_TOOL_NAME,
28330
28638
  SHORT_TTL_MS,
28331
28639
  STREAM_RESUMABLE_HEADER,
28332
28640
  VaultFolder as StoredVaultFolderModel,
@@ -28339,6 +28647,7 @@ export {
28339
28647
  TREND_RECENT_WINDOW_DAYS,
28340
28648
  TREND_STALE_WINDOW_DAYS,
28341
28649
  VAULT_SIZE_HOP_CAP,
28650
+ WALLET_PAYMENT_TOOL_NAME,
28342
28651
  WalletPoller,
28343
28652
  addConversationMemoriesOp,
28344
28653
  archiveVaultMemoryOp,
@@ -28393,12 +28702,14 @@ export {
28393
28702
  createRemoteMemoryPersistence,
28394
28703
  createRemoteMemoryPipeline,
28395
28704
  createRemoteMemoryStore,
28705
+ createSelectPaymentWalletTool,
28396
28706
  createStockPricePreProcessor,
28397
28707
  createStreamingDeAnonymizer,
28398
28708
  createVaultEmbeddingCache,
28399
28709
  createVaultFolderOp,
28400
28710
  createVaultMemoriesBatchOp,
28401
28711
  createVaultMemoryOp,
28712
+ createWalletPaymentTool,
28402
28713
  createWeatherPreProcessor,
28403
28714
  createWebSearchPreProcessor,
28404
28715
  decodeChunkVector,