@anuma/sdk 10.0.1 → 10.0.3

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.
@@ -2180,6 +2180,160 @@ async function assembleDecryptedMessage(message, address) {
2180
2180
  return result;
2181
2181
  }
2182
2182
 
2183
+ // src/lib/db/chat/models.ts
2184
+ import { Model as Model2 } from "@nozbe/watermelondb";
2185
+ import { date, field, json, text } from "@nozbe/watermelondb/decorators";
2186
+ var Message = class extends Model2 {
2187
+ };
2188
+ Message.table = "history";
2189
+ Message.associations = {
2190
+ conversations: { type: "belongs_to", key: "conversation_id" },
2191
+ media: { type: "has_many", foreignKey: "message_id" }
2192
+ };
2193
+ __decorateClass([
2194
+ field("message_id")
2195
+ ], Message.prototype, "messageId", 2);
2196
+ __decorateClass([
2197
+ text("conversation_id")
2198
+ ], Message.prototype, "conversationId", 2);
2199
+ __decorateClass([
2200
+ text("role")
2201
+ ], Message.prototype, "role", 2);
2202
+ __decorateClass([
2203
+ text("content")
2204
+ ], Message.prototype, "content", 2);
2205
+ __decorateClass([
2206
+ text("model")
2207
+ ], Message.prototype, "model", 2);
2208
+ __decorateClass([
2209
+ text("image_model")
2210
+ ], Message.prototype, "imageModel", 2);
2211
+ __decorateClass([
2212
+ json("files", (raw) => raw)
2213
+ ], Message.prototype, "files", 2);
2214
+ __decorateClass([
2215
+ json("file_ids", (raw) => raw)
2216
+ ], Message.prototype, "fileIds", 2);
2217
+ __decorateClass([
2218
+ date("created_at")
2219
+ ], Message.prototype, "createdAt", 2);
2220
+ __decorateClass([
2221
+ date("updated_at")
2222
+ ], Message.prototype, "updatedAt", 2);
2223
+ __decorateClass([
2224
+ json("vector", (raw) => raw)
2225
+ ], Message.prototype, "vector", 2);
2226
+ __decorateClass([
2227
+ text("embedding_model")
2228
+ ], Message.prototype, "embeddingModel", 2);
2229
+ __decorateClass([
2230
+ json("chunks", (raw) => raw)
2231
+ ], Message.prototype, "chunks", 2);
2232
+ __decorateClass([
2233
+ json("usage", (raw) => raw)
2234
+ ], Message.prototype, "usage", 2);
2235
+ __decorateClass([
2236
+ json("sources", (raw) => raw)
2237
+ ], Message.prototype, "sources", 2);
2238
+ __decorateClass([
2239
+ field("response_duration")
2240
+ ], Message.prototype, "responseDuration", 2);
2241
+ __decorateClass([
2242
+ field("was_stopped")
2243
+ ], Message.prototype, "wasStopped", 2);
2244
+ __decorateClass([
2245
+ text("error")
2246
+ ], Message.prototype, "error", 2);
2247
+ __decorateClass([
2248
+ json("thought_process", (raw) => raw)
2249
+ ], Message.prototype, "thoughtProcess", 2);
2250
+ __decorateClass([
2251
+ text("thinking")
2252
+ ], Message.prototype, "thinking", 2);
2253
+ __decorateClass([
2254
+ text("parent_message_id")
2255
+ ], Message.prototype, "parentMessageId", 2);
2256
+ __decorateClass([
2257
+ text("feedback")
2258
+ ], Message.prototype, "feedback", 2);
2259
+ __decorateClass([
2260
+ json("tool_call_events", (raw) => raw)
2261
+ ], Message.prototype, "toolCallEvents", 2);
2262
+ __decorateClass([
2263
+ text("origin")
2264
+ ], Message.prototype, "origin", 2);
2265
+ var Conversation = class extends Model2 {
2266
+ };
2267
+ Conversation.table = "conversations";
2268
+ Conversation.associations = {
2269
+ history: { type: "has_many", foreignKey: "conversation_id" },
2270
+ projects: { type: "belongs_to", key: "project_id" }
2271
+ };
2272
+ __decorateClass([
2273
+ text("conversation_id")
2274
+ ], Conversation.prototype, "conversationId", 2);
2275
+ __decorateClass([
2276
+ text("title")
2277
+ ], Conversation.prototype, "title", 2);
2278
+ __decorateClass([
2279
+ text("project_id")
2280
+ ], Conversation.prototype, "projectId", 2);
2281
+ __decorateClass([
2282
+ date("created_at")
2283
+ ], Conversation.prototype, "createdAt", 2);
2284
+ __decorateClass([
2285
+ date("updated_at")
2286
+ ], Conversation.prototype, "updatedAt", 2);
2287
+ __decorateClass([
2288
+ field("is_deleted")
2289
+ ], Conversation.prototype, "isDeleted", 2);
2290
+ __decorateClass([
2291
+ date("pinned_at")
2292
+ ], Conversation.prototype, "pinnedAt", 2);
2293
+ var ConversationSummary = class extends Model2 {
2294
+ };
2295
+ ConversationSummary.table = "conversation_summaries";
2296
+ ConversationSummary.associations = {
2297
+ conversations: { type: "belongs_to", key: "conversation_id" }
2298
+ };
2299
+ __decorateClass([
2300
+ text("conversation_id")
2301
+ ], ConversationSummary.prototype, "conversationId", 2);
2302
+ __decorateClass([
2303
+ text("summary")
2304
+ ], ConversationSummary.prototype, "summary", 2);
2305
+ __decorateClass([
2306
+ text("summarized_up_to")
2307
+ ], ConversationSummary.prototype, "summarizedUpTo", 2);
2308
+ __decorateClass([
2309
+ field("token_count")
2310
+ ], ConversationSummary.prototype, "tokenCount", 2);
2311
+ __decorateClass([
2312
+ date("created_at")
2313
+ ], ConversationSummary.prototype, "createdAt", 2);
2314
+ __decorateClass([
2315
+ date("updated_at")
2316
+ ], ConversationSummary.prototype, "updatedAt", 2);
2317
+
2318
+ // src/lib/db/chat/summaryRevision.ts
2319
+ var conversationRevisions = /* @__PURE__ */ new WeakMap();
2320
+ function getConversationRevision(database, conversationId) {
2321
+ return conversationRevisions.get(database)?.get(conversationId) ?? 0;
2322
+ }
2323
+ function advanceConversationRevision(database, conversationId) {
2324
+ let revisions = conversationRevisions.get(database);
2325
+ if (!revisions) {
2326
+ revisions = /* @__PURE__ */ new Map();
2327
+ conversationRevisions.set(database, revisions);
2328
+ }
2329
+ revisions.set(conversationId, getConversationRevision(database, conversationId) + 1);
2330
+ }
2331
+ function assertConversationRevision(database, conversationId, revision2) {
2332
+ if (getConversationRevision(database, conversationId) !== revision2) {
2333
+ throw new Error("The conversation changed during summarization. Retry the request.");
2334
+ }
2335
+ }
2336
+
2183
2337
  // src/lib/db/chat/toolCallEventIndex.ts
2184
2338
  import { Q } from "@nozbe/watermelondb";
2185
2339
  function parseEventIds(value) {
@@ -2889,8 +3043,20 @@ async function getMessageSkeletonsOp(ctx, convId) {
2889
3043
  async function getToolCallEventIdsOp(ctx, convId) {
2890
3044
  return getToolCallEventIds(ctx.messagesCollection, convId);
2891
3045
  }
3046
+ async function invalidateConversationSummary(ctx, conversationId, changedMessageId) {
3047
+ if (!ctx.database.schema?.tables[ConversationSummary.table]) return;
3048
+ const summaries = await ctx.database.get(ConversationSummary.table).query(Q2.where("conversation_id", conversationId)).fetch();
3049
+ for (const summary of summaries) {
3050
+ if (changedMessageId !== void 0) {
3051
+ const [boundary] = await ctx.messagesCollection.query(Q2.where("id", summary.summarizedUpTo), Q2.where("conversation_id", conversationId)).fetch();
3052
+ if (boundary && changedMessageId > boundary.messageId) continue;
3053
+ }
3054
+ await summary.destroyPermanently();
3055
+ }
3056
+ }
2892
3057
  async function clearMessagesOp(ctx, convId) {
2893
3058
  await ctx.database.write(async () => {
3059
+ await invalidateConversationSummary(ctx, convId);
2894
3060
  const messages = await ctx.messagesCollection.query(Q2.where("conversation_id", convId)).fetch();
2895
3061
  const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q2.where("conversation_id", convId)).fetch() : [];
2896
3062
  for (const job of jobs) {
@@ -2902,11 +3068,12 @@ async function clearMessagesOp(ctx, convId) {
2902
3068
  }
2903
3069
  for (const message of messages) {
2904
3070
  await message.update((msg) => {
2905
- msg._setRaw("file_ids", null);
3071
+ if (ctx.messagesCollection.schema.columns.file_ids) msg._setRaw("file_ids", null);
2906
3072
  msg._setRaw("files", null);
2907
3073
  });
2908
3074
  await message.destroyPermanently();
2909
3075
  }
3076
+ advanceConversationRevision(ctx.database, convId);
2910
3077
  });
2911
3078
  }
2912
3079
  async function deleteMessageOp(ctx, uniqueId) {
@@ -2917,6 +3084,7 @@ async function deleteMessageOp(ctx, uniqueId) {
2917
3084
  return null;
2918
3085
  }
2919
3086
  await ctx.database.write(async () => {
3087
+ await invalidateConversationSummary(ctx, message.conversationId, message.messageId);
2920
3088
  const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(Q2.where("conversation_id", message.conversationId)).fetch() : [];
2921
3089
  for (const job of jobs) {
2922
3090
  const ids = JSON.parse(String(job._getRaw("message_ids")));
@@ -2926,10 +3094,11 @@ async function deleteMessageOp(ctx, uniqueId) {
2926
3094
  });
2927
3095
  }
2928
3096
  await message.update((msg) => {
2929
- msg._setRaw("file_ids", null);
3097
+ if (ctx.messagesCollection.schema.columns.file_ids) msg._setRaw("file_ids", null);
2930
3098
  msg._setRaw("files", null);
2931
3099
  });
2932
3100
  await message.destroyPermanently();
3101
+ advanceConversationRevision(ctx.database, message.conversationId);
2933
3102
  });
2934
3103
  return uniqueId;
2935
3104
  }
@@ -3339,6 +3508,14 @@ async function _updateMessageOp(ctx, uniqueId, opts) {
3339
3508
  ctx.embeddedWalletSigner
3340
3509
  ) : opts;
3341
3510
  await ctx.database.write(async () => {
3511
+ let contentChanged = false;
3512
+ if (opts.content !== void 0) {
3513
+ const originalContent = ctx.walletAddress ? await decryptField(message.content, ctx.walletAddress) : message.content;
3514
+ contentChanged = opts.content !== originalContent;
3515
+ if (contentChanged) {
3516
+ await invalidateConversationSummary(ctx, message.conversationId, message.messageId);
3517
+ }
3518
+ }
3342
3519
  await message.update((msg) => {
3343
3520
  if (encryptedOpts.content !== void 0)
3344
3521
  msg._setRaw("content", encryptedOpts.content);
@@ -3383,6 +3560,7 @@ async function _updateMessageOp(ctx, uniqueId, opts) {
3383
3560
  msg._setRaw("tool_call_events", tceValue);
3384
3561
  }
3385
3562
  });
3563
+ if (contentChanged) advanceConversationRevision(ctx.database, message.conversationId);
3386
3564
  });
3387
3565
  return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
3388
3566
  }
@@ -5419,22 +5597,22 @@ function toReceipt(action, argumentsJson, output) {
5419
5597
  const result = parseObject(output);
5420
5598
  return {
5421
5599
  kind: action.kind,
5422
- venueName: text(args.venue_name) ?? "",
5423
- day: text(args.day) ?? "",
5424
- time: text(args.time) ?? "",
5600
+ venueName: text2(args.venue_name) ?? "",
5601
+ day: text2(args.day) ?? "",
5602
+ time: text2(args.time) ?? "",
5425
5603
  partySize: count(args.party_size),
5426
- reservationId: text(result.reservation_id) ?? text(args.reservation_id),
5427
- resyUrl: text(result.reservations_url),
5428
- feeSummary: text(result.fee_summary),
5604
+ reservationId: text2(result.reservation_id) ?? text2(args.reservation_id),
5605
+ resyUrl: text2(result.reservations_url),
5606
+ feeSummary: text2(result.fee_summary),
5429
5607
  ...outcome(action, output, result)
5430
5608
  };
5431
5609
  }
5432
5610
  function outcome(action, output, result) {
5433
5611
  if (action.alreadyDone.test(output)) return { status: "already_done" };
5434
- const reason = text(result.error);
5612
+ const reason = text2(result.error);
5435
5613
  if (action.kind === "booking") {
5436
5614
  if (BOOKING_OUTCOME_UNKNOWN.test(output)) return { status: "unknown" };
5437
- const held = result.success === true || text(result.reservation_id) !== void 0;
5615
+ const held = result.success === true || text2(result.reservation_id) !== void 0;
5438
5616
  return held ? { status: "made" } : { status: "not_made", reason };
5439
5617
  }
5440
5618
  if (result.error_code === CANCEL_OUTCOME_UNKNOWN) return { status: "unknown", reason };
@@ -5449,7 +5627,7 @@ function parseObject(json5) {
5449
5627
  return {};
5450
5628
  }
5451
5629
  }
5452
- function text(value) {
5630
+ function text2(value) {
5453
5631
  if (typeof value === "number") return String(value);
5454
5632
  return typeof value === "string" && value ? value : void 0;
5455
5633
  }
@@ -10899,7 +11077,7 @@ function hasControl(value) {
10899
11077
  function integer(value, minimum = 0) {
10900
11078
  return Number.isSafeInteger(value) && value >= minimum;
10901
11079
  }
10902
- function json(value, ancestors = /* @__PURE__ */ new Set()) {
11080
+ function json2(value, ancestors = /* @__PURE__ */ new Set()) {
10903
11081
  if (value === null || typeof value === "string" || typeof value === "boolean") return true;
10904
11082
  if (typeof value === "number") return Number.isFinite(value);
10905
11083
  if (typeof value !== "object" || ancestors.has(value)) return false;
@@ -10907,12 +11085,12 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
10907
11085
  if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
10908
11086
  return false;
10909
11087
  ancestors.add(value);
10910
- const valid = Object.values(value).every((v) => json(v, ancestors));
11088
+ const valid = Object.values(value).every((v) => json2(v, ancestors));
10911
11089
  ancestors.delete(value);
10912
11090
  return valid;
10913
11091
  }
10914
11092
  function validRecord(value) {
10915
- if (!object(value) || typeof value.kind !== "string" || !kinds.has(value.kind) || !id(value.id) || !integer(value.sortKey) || !integer(value.createdAt, 1) || !integer(value.updatedAt, 1) || typeof value.isDeleted !== "boolean" || !object(value.data) || !json(value.data) || Object.keys(value).some(
11093
+ if (!object(value) || typeof value.kind !== "string" || !kinds.has(value.kind) || !id(value.id) || !integer(value.sortKey) || !integer(value.createdAt, 1) || !integer(value.updatedAt, 1) || typeof value.isDeleted !== "boolean" || !object(value.data) || !json2(value.data) || Object.keys(value).some(
10916
11094
  (key) => ![...metadata, "data"].includes(key)
10917
11095
  ))
10918
11096
  return false;
@@ -10941,14 +11119,14 @@ function vectorFields(write) {
10941
11119
  ...write.embeddingModel !== void 0 ? { embedding_model: write.embeddingModel } : {}
10942
11120
  };
10943
11121
  }
10944
- function text2(value) {
11122
+ function text3(value) {
10945
11123
  return typeof value === "string";
10946
11124
  }
10947
11125
  function timestamp(value) {
10948
11126
  return typeof value === "string" && Number.isFinite(Date.parse(value));
10949
11127
  }
10950
11128
  function presigned(value) {
10951
- if (!object(value) || !text2(value.url) || !/^https:\/\//.test(value.url) || !text2(value.method) || !object(value.headers) || !Object.values(value.headers).every(text2) || !timestamp(value.expires_at))
11129
+ if (!object(value) || !text3(value.url) || !/^https:\/\//.test(value.url) || !text3(value.method) || !object(value.headers) || !Object.values(value.headers).every(text3) || !timestamp(value.expires_at))
10952
11130
  invalid();
10953
11131
  return {
10954
11132
  url: value.url,
@@ -10958,7 +11136,7 @@ function presigned(value) {
10958
11136
  };
10959
11137
  }
10960
11138
  function attachment(value) {
10961
- if (!object(value) || !text2(value.attachment_id) || !attachmentIdPattern.test(value.attachment_id) || !integer(value.size_bytes, 1) || value.state !== "pending" && value.state !== "committed" || value.owner_kind !== void 0 && value.owner_kind !== "message" && value.owner_kind !== "summary" || value.owner_id !== void 0 && !id(value.owner_id) || !timestamp(value.created_at) || value.committed_at !== void 0 && !timestamp(value.committed_at))
11139
+ if (!object(value) || !text3(value.attachment_id) || !attachmentIdPattern.test(value.attachment_id) || !integer(value.size_bytes, 1) || value.state !== "pending" && value.state !== "committed" || value.owner_kind !== void 0 && value.owner_kind !== "message" && value.owner_kind !== "summary" || value.owner_id !== void 0 && !id(value.owner_id) || !timestamp(value.created_at) || value.committed_at !== void 0 && !timestamp(value.committed_at))
10962
11140
  invalid();
10963
11141
  return {
10964
11142
  id: value.attachment_id,
@@ -10971,7 +11149,7 @@ function attachment(value) {
10971
11149
  };
10972
11150
  }
10973
11151
  function ref(value) {
10974
- if (!object(value) || !text2(value.kind) || !kinds.has(value.kind) || !id(value.id)) invalid();
11152
+ if (!object(value) || !text3(value.kind) || !kinds.has(value.kind) || !id(value.id)) invalid();
10975
11153
  return { kind: value.kind, id: value.id };
10976
11154
  }
10977
11155
  function sameMetadata(a, b) {
@@ -11194,7 +11372,7 @@ async function createRemoteChatStore(options) {
11194
11372
  },
11195
11373
  async account(signal) {
11196
11374
  const value = await request("/account", {}, signal);
11197
- if (!object(value) || value.account_id !== accountId || !text2(value.key_id) || value.state !== "none" && value.state !== "migrating" && value.state !== "active" || !integer(value.record_count) || !integer(value.storage_bytes) || !integer(value.vector_count))
11375
+ if (!object(value) || value.account_id !== accountId || !text3(value.key_id) || value.state !== "none" && value.state !== "migrating" && value.state !== "active" || !integer(value.record_count) || !integer(value.storage_bytes) || !integer(value.vector_count))
11198
11376
  invalid();
11199
11377
  if (value.key_id && value.key_id !== keyId)
11200
11378
  throw new ChatStoreError("Canonical chat key does not match", 409, "key_mismatch");
@@ -11268,12 +11446,12 @@ async function createRemoteChatStore(options) {
11268
11446
  },
11269
11447
  async changes(cursor, options2) {
11270
11448
  const limit = options2?.limit ?? 100;
11271
- if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text2(cursor) || cursor.length > 2048))
11449
+ if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text3(cursor) || cursor.length > 2048))
11272
11450
  invalid();
11273
11451
  const params = new URLSearchParams({ account_id: String(accountId), limit: String(limit) });
11274
11452
  if (cursor) params.set("cursor", cursor);
11275
11453
  const value = await request(`/changes?${params}`, {}, options2?.signal);
11276
- if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !text2(value.next_cursor) || value.changes_cursor !== void 0 && !text2(value.changes_cursor))
11454
+ if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !text3(value.next_cursor) || value.changes_cursor !== void 0 && !text3(value.changes_cursor))
11277
11455
  invalid();
11278
11456
  const items = [];
11279
11457
  for (const item of value.items) items.push(await decode(item));
@@ -11401,27 +11579,27 @@ var emptyMessage = {
11401
11579
  };
11402
11580
 
11403
11581
  // src/lib/db/appFiles/models.ts
11404
- import { Model as Model2 } from "@nozbe/watermelondb";
11405
- import { date, readonly, text as text3 } from "@nozbe/watermelondb/decorators";
11406
- var AppFile = class extends Model2 {
11582
+ import { Model as Model3 } from "@nozbe/watermelondb";
11583
+ import { date as date2, readonly, text as text4 } from "@nozbe/watermelondb/decorators";
11584
+ var AppFile = class extends Model3 {
11407
11585
  };
11408
11586
  AppFile.table = "app_files";
11409
11587
  AppFile.associations = {};
11410
11588
  __decorateClass([
11411
- text3("conversation_id")
11589
+ text4("conversation_id")
11412
11590
  ], AppFile.prototype, "conversationId", 2);
11413
11591
  __decorateClass([
11414
- text3("path")
11592
+ text4("path")
11415
11593
  ], AppFile.prototype, "path", 2);
11416
11594
  __decorateClass([
11417
- text3("content")
11595
+ text4("content")
11418
11596
  ], AppFile.prototype, "content", 2);
11419
11597
  __decorateClass([
11420
11598
  readonly,
11421
- date("created_at")
11599
+ date2("created_at")
11422
11600
  ], AppFile.prototype, "createdAt", 2);
11423
11601
  __decorateClass([
11424
- date("updated_at")
11602
+ date2("updated_at")
11425
11603
  ], AppFile.prototype, "updatedAt", 2);
11426
11604
 
11427
11605
  // src/lib/db/appFiles/operations.ts
@@ -11566,141 +11744,6 @@ async function decryptConversationTitle(encryptedTitle, address) {
11566
11744
  }
11567
11745
  }
11568
11746
 
11569
- // src/lib/db/chat/models.ts
11570
- import { Model as Model3 } from "@nozbe/watermelondb";
11571
- import { date as date2, field, json as json2, text as text4 } from "@nozbe/watermelondb/decorators";
11572
- var Message = class extends Model3 {
11573
- };
11574
- Message.table = "history";
11575
- Message.associations = {
11576
- conversations: { type: "belongs_to", key: "conversation_id" },
11577
- media: { type: "has_many", foreignKey: "message_id" }
11578
- };
11579
- __decorateClass([
11580
- field("message_id")
11581
- ], Message.prototype, "messageId", 2);
11582
- __decorateClass([
11583
- text4("conversation_id")
11584
- ], Message.prototype, "conversationId", 2);
11585
- __decorateClass([
11586
- text4("role")
11587
- ], Message.prototype, "role", 2);
11588
- __decorateClass([
11589
- text4("content")
11590
- ], Message.prototype, "content", 2);
11591
- __decorateClass([
11592
- text4("model")
11593
- ], Message.prototype, "model", 2);
11594
- __decorateClass([
11595
- text4("image_model")
11596
- ], Message.prototype, "imageModel", 2);
11597
- __decorateClass([
11598
- json2("files", (raw) => raw)
11599
- ], Message.prototype, "files", 2);
11600
- __decorateClass([
11601
- json2("file_ids", (raw) => raw)
11602
- ], Message.prototype, "fileIds", 2);
11603
- __decorateClass([
11604
- date2("created_at")
11605
- ], Message.prototype, "createdAt", 2);
11606
- __decorateClass([
11607
- date2("updated_at")
11608
- ], Message.prototype, "updatedAt", 2);
11609
- __decorateClass([
11610
- json2("vector", (raw) => raw)
11611
- ], Message.prototype, "vector", 2);
11612
- __decorateClass([
11613
- text4("embedding_model")
11614
- ], Message.prototype, "embeddingModel", 2);
11615
- __decorateClass([
11616
- json2("chunks", (raw) => raw)
11617
- ], Message.prototype, "chunks", 2);
11618
- __decorateClass([
11619
- json2("usage", (raw) => raw)
11620
- ], Message.prototype, "usage", 2);
11621
- __decorateClass([
11622
- json2("sources", (raw) => raw)
11623
- ], Message.prototype, "sources", 2);
11624
- __decorateClass([
11625
- field("response_duration")
11626
- ], Message.prototype, "responseDuration", 2);
11627
- __decorateClass([
11628
- field("was_stopped")
11629
- ], Message.prototype, "wasStopped", 2);
11630
- __decorateClass([
11631
- text4("error")
11632
- ], Message.prototype, "error", 2);
11633
- __decorateClass([
11634
- json2("thought_process", (raw) => raw)
11635
- ], Message.prototype, "thoughtProcess", 2);
11636
- __decorateClass([
11637
- text4("thinking")
11638
- ], Message.prototype, "thinking", 2);
11639
- __decorateClass([
11640
- text4("parent_message_id")
11641
- ], Message.prototype, "parentMessageId", 2);
11642
- __decorateClass([
11643
- text4("feedback")
11644
- ], Message.prototype, "feedback", 2);
11645
- __decorateClass([
11646
- json2("tool_call_events", (raw) => raw)
11647
- ], Message.prototype, "toolCallEvents", 2);
11648
- __decorateClass([
11649
- text4("origin")
11650
- ], Message.prototype, "origin", 2);
11651
- var Conversation = class extends Model3 {
11652
- };
11653
- Conversation.table = "conversations";
11654
- Conversation.associations = {
11655
- history: { type: "has_many", foreignKey: "conversation_id" },
11656
- projects: { type: "belongs_to", key: "project_id" }
11657
- };
11658
- __decorateClass([
11659
- text4("conversation_id")
11660
- ], Conversation.prototype, "conversationId", 2);
11661
- __decorateClass([
11662
- text4("title")
11663
- ], Conversation.prototype, "title", 2);
11664
- __decorateClass([
11665
- text4("project_id")
11666
- ], Conversation.prototype, "projectId", 2);
11667
- __decorateClass([
11668
- date2("created_at")
11669
- ], Conversation.prototype, "createdAt", 2);
11670
- __decorateClass([
11671
- date2("updated_at")
11672
- ], Conversation.prototype, "updatedAt", 2);
11673
- __decorateClass([
11674
- field("is_deleted")
11675
- ], Conversation.prototype, "isDeleted", 2);
11676
- __decorateClass([
11677
- date2("pinned_at")
11678
- ], Conversation.prototype, "pinnedAt", 2);
11679
- var ConversationSummary = class extends Model3 {
11680
- };
11681
- ConversationSummary.table = "conversation_summaries";
11682
- ConversationSummary.associations = {
11683
- conversations: { type: "belongs_to", key: "conversation_id" }
11684
- };
11685
- __decorateClass([
11686
- text4("conversation_id")
11687
- ], ConversationSummary.prototype, "conversationId", 2);
11688
- __decorateClass([
11689
- text4("summary")
11690
- ], ConversationSummary.prototype, "summary", 2);
11691
- __decorateClass([
11692
- text4("summarized_up_to")
11693
- ], ConversationSummary.prototype, "summarizedUpTo", 2);
11694
- __decorateClass([
11695
- field("token_count")
11696
- ], ConversationSummary.prototype, "tokenCount", 2);
11697
- __decorateClass([
11698
- date2("created_at")
11699
- ], ConversationSummary.prototype, "createdAt", 2);
11700
- __decorateClass([
11701
- date2("updated_at")
11702
- ], ConversationSummary.prototype, "updatedAt", 2);
11703
-
11704
11747
  // src/lib/db/chat/schema.ts
11705
11748
  import { appSchema, tableSchema } from "@nozbe/watermelondb";
11706
11749
  import { addColumns, schemaMigrations } from "@nozbe/watermelondb/Schema/migrations";
@@ -32347,6 +32390,13 @@ var lastCompactionTime = /* @__PURE__ */ new Map();
32347
32390
  var COMPACTION_COOLDOWN_MS = 6e4;
32348
32391
  var MAX_SUMMARY_TOKEN_RATIO = 0.8;
32349
32392
  async function maybeSummarizeHistory(options) {
32393
+ const { database, conversationId } = options;
32394
+ const revision2 = getConversationRevision(database, conversationId);
32395
+ const result = await summarizeHistoryAtRevision(options, revision2);
32396
+ assertConversationRevision(database, conversationId, revision2);
32397
+ return result;
32398
+ }
32399
+ async function summarizeHistoryAtRevision(options, revision2) {
32350
32400
  const { database, conversationId, messages, summarizeHistory, summaryMinWindowMessages, token } = options;
32351
32401
  if (!summarizeHistory) {
32352
32402
  return { messagesToConvert: messages, summarySystemMessage: null };
@@ -32387,7 +32437,7 @@ async function maybeSummarizeHistory(options) {
32387
32437
  clearTimeout(staleGuardTimerId);
32388
32438
  }
32389
32439
  }
32390
- const promise = doSummarizeHistory(options);
32440
+ const promise = doSummarizeHistory(options, revision2);
32391
32441
  summarizationLocks.set(conversationId, promise);
32392
32442
  try {
32393
32443
  return await promise;
@@ -32401,7 +32451,7 @@ Summary to condense:
32401
32451
  {summary}
32402
32452
 
32403
32453
  Condensed summary:`;
32404
- async function doSummarizeHistory(options) {
32454
+ async function doSummarizeHistory(options, revision2) {
32405
32455
  const {
32406
32456
  database,
32407
32457
  conversationId,
@@ -32416,7 +32466,20 @@ async function doSummarizeHistory(options) {
32416
32466
  } = options;
32417
32467
  try {
32418
32468
  const summaryCtx = createSummaryContext(database);
32469
+ const persistSummary = (summary, summarizedUpTo, tokenCount) => database.write(async (writer) => {
32470
+ assertConversationRevision(database, conversationId, revision2);
32471
+ await writer.callWriter(
32472
+ () => upsertConversationSummaryOp(
32473
+ summaryCtx,
32474
+ conversationId,
32475
+ summary,
32476
+ summarizedUpTo,
32477
+ tokenCount
32478
+ )
32479
+ );
32480
+ });
32419
32481
  let cachedSummary = await getConversationSummaryOp(summaryCtx, conversationId);
32482
+ assertConversationRevision(database, conversationId, revision2);
32420
32483
  const lastCompacted = lastCompactionTime.get(conversationId) ?? 0;
32421
32484
  const compactionCooledDown = Date.now() - lastCompacted > COMPACTION_COOLDOWN_MS;
32422
32485
  if (cachedSummary && cachedSummary.tokenCount > summaryTokenThreshold * MAX_SUMMARY_TOKEN_RATIO && compactionCooledDown) {
@@ -32432,13 +32495,7 @@ async function doSummarizeHistory(options) {
32432
32495
  );
32433
32496
  const compactedSummary = redactor ? redactor.deAnonymize(rawCompacted) : rawCompacted;
32434
32497
  const compactedTokens = estimateTokens(compactedSummary);
32435
- await upsertConversationSummaryOp(
32436
- summaryCtx,
32437
- conversationId,
32438
- compactedSummary,
32439
- cachedSummary.summarizedUpTo,
32440
- compactedTokens
32441
- );
32498
+ await persistSummary(compactedSummary, cachedSummary.summarizedUpTo, compactedTokens);
32442
32499
  cachedSummary = {
32443
32500
  ...cachedSummary,
32444
32501
  summary: compactedSummary,
@@ -32446,6 +32503,7 @@ async function doSummarizeHistory(options) {
32446
32503
  };
32447
32504
  lastCompactionTime.set(conversationId, Date.now());
32448
32505
  } catch {
32506
+ assertConversationRevision(database, conversationId, revision2);
32449
32507
  lastCompactionTime.set(conversationId, Date.now());
32450
32508
  getLogger().warn(
32451
32509
  "[summarize] Summary compaction failed, proceeding with oversized summary"
@@ -32477,10 +32535,9 @@ async function doSummarizeHistory(options) {
32477
32535
  redactor,
32478
32536
  onPiiRedacted
32479
32537
  });
32538
+ assertConversationRevision(database, conversationId, revision2);
32480
32539
  if (summarizeResult.didSummarize && summarizeResult.summary && summarizeResult.summarizedUpTo) {
32481
- await upsertConversationSummaryOp(
32482
- summaryCtx,
32483
- conversationId,
32540
+ await persistSummary(
32484
32541
  summarizeResult.summary,
32485
32542
  summarizeResult.summarizedUpTo,
32486
32543
  summarizeResult.summaryTokenCount
@@ -32499,6 +32556,7 @@ async function doSummarizeHistory(options) {
32499
32556
  summarySystemMessage: summarizeResult.summary ? summaryToSystemMessage(summarizeResult.summary) : null
32500
32557
  };
32501
32558
  } catch (err) {
32559
+ assertConversationRevision(database, conversationId, revision2);
32502
32560
  getLogger().warn("[summarize] Summarization failed, falling back to verbatim:", err);
32503
32561
  return { messagesToConvert: messages, summarySystemMessage: null };
32504
32562
  }